diff --git a/.clang-format b/.clang-format index 41969eca4b7459..9547fe1b77cac0 100644 --- a/.clang-format +++ b/.clang-format @@ -32,6 +32,9 @@ AlignConsecutiveAssignments: false # double b = 3.14; AlignConsecutiveDeclarations: false +# Align consecutive macro definitions. +AlignConsecutiveMacros: true + # Align escaped newlines as far left as possible # #define A \ # int aaaa; \ @@ -209,13 +212,14 @@ KeepEmptyLinesAtTheStartOfBlocks: false # Penalties # This decides what order things should be done if a line is too long -PenaltyBreakAssignment: 10 -PenaltyBreakBeforeFirstCallParameter: 30 -PenaltyBreakComment: 10 +PenaltyBreakAssignment: 5 +PenaltyBreakBeforeFirstCallParameter: 5 +PenaltyBreakComment: 5 PenaltyBreakFirstLessLess: 0 -PenaltyBreakString: 10 -PenaltyExcessCharacter: 100 -PenaltyReturnTypeOnItsOwnLine: 60 +PenaltyBreakOpenParenthesis: 300 +PenaltyBreakString: 5 +PenaltyExcessCharacter: 10 +PenaltyReturnTypeOnItsOwnLine: 300 # Don't sort #include's SortIncludes: false diff --git a/.editorconfig b/.editorconfig index 15d6cbeab109ef..2d3929b5916a14 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,7 @@ insert_final_newline = true # The settings for C (*.c and *.h) files are mirrored in .clang-format. Keep # them in sync. -[{*.{c,h,sh,perl,pl,pm,txt},config.mak.*,Makefile}] +[{*.{c,h,sh,bash,perl,pl,pm,txt,adoc},config.mak.*,Makefile}] indent_style = tab tab_width = 8 diff --git a/.gitattributes b/.gitattributes index 158c3d45c4c10c..c6a0b35116fd90 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,12 +7,12 @@ *.py text eol=lf diff=python *.bat text eol=crlf CODE_OF_CONDUCT.md -whitespace -/Documentation/**/*.txt text eol=lf +/Documentation/**/*.adoc text eol=lf /command-list.txt text eol=lf /GIT-VERSION-GEN text eol=lf /mergetools/* text eol=lf /t/oid-info/* text eol=lf -/Documentation/git-merge.txt conflict-marker-size=32 -/Documentation/gitk.txt conflict-marker-size=32 -/Documentation/user-manual.txt conflict-marker-size=32 +/Documentation/git-merge.adoc conflict-marker-size=32 +/Documentation/gitk.adoc conflict-marker-size=32 +/Documentation/user-manual.adoc conflict-marker-size=32 /t/t????-*.sh conflict-marker-size=32 diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 48341e81f49066..124301dbbe2fc1 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -45,7 +45,7 @@ jobs: - run: ci/install-dependencies.sh if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos') env: - distro: ${{ matrix.os }} + CI_JOB_IMAGE: ${{ matrix.os }} # The Coverity site says the tool is usually updated twice yearly, so the # MD5 of download can be used to determine whether there's been an update. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 916a64b6736d1c..9959b61ece2bcc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -248,6 +248,58 @@ jobs: with: name: failed-tests-windows-vs-${{ matrix.nr }} path: ${{env.FAILED_TEST_ARTIFACTS}} + + windows-meson-build: + name: win+Meson build + needs: ci-config + if: needs.ci-config.outputs.enabled == 'yes' + runs-on: windows-latest + concurrency: + group: windows-meson-build-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - name: Set up dependencies + shell: pwsh + run: pip install meson ninja + - name: Setup + shell: pwsh + run: meson setup build -Dperl=disabled -Dcredential_helpers=wincred + - name: Compile + shell: pwsh + run: meson compile -C build + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: windows-meson-artifacts + path: build + windows-meson-test: + name: win+Meson test + runs-on: windows-latest + needs: [ci-config, windows-meson-build] + strategy: + fail-fast: false + matrix: + nr: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + concurrency: + group: windows-meson-test-${{ matrix.nr }}-${{ github.ref }} + cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - name: Set up dependencies + shell: pwsh + run: pip install meson ninja + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: windows-meson-artifacts + path: build + - name: Test + shell: pwsh + run: meson test -C build --list | Select-Object -Skip 1 | Select-String .* | Group-Object -Property { $_.LineNumber % 10 } | Where-Object Name -EQ ${{ matrix.nr }} | ForEach-Object { meson test -C build --no-rebuild --print-errorlogs $_.Group } + regular: name: ${{matrix.vector.jobname}} (${{matrix.vector.pool}}) needs: ci-config @@ -259,20 +311,6 @@ jobs: fail-fast: false matrix: vector: - - 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 - pool: ubuntu-20.04 - - jobname: linux-TEST-vars - cc: gcc - cc_package: gcc-8 - pool: ubuntu-20.04 - jobname: osx-clang cc: clang pool: macos-13 @@ -282,23 +320,15 @@ jobs: - jobname: osx-gcc cc: gcc-13 pool: macos-13 - - jobname: linux-gcc-default - cc: gcc - pool: ubuntu-latest - - jobname: linux-leaks - cc: gcc - pool: ubuntu-latest - - jobname: linux-reftable-leaks - cc: gcc - pool: ubuntu-latest - - jobname: linux-asan-ubsan + - jobname: osx-meson cc: clang - pool: ubuntu-latest + pool: macos-13 env: CC: ${{matrix.vector.cc}} CC_PACKAGE: ${{matrix.vector.cc_package}} jobname: ${{matrix.vector.jobname}} - distro: ${{matrix.vector.pool}} + CI_JOB_IMAGE: ${{matrix.vector.pool}} + TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t runs-on: ${{matrix.vector.pool}} steps: - uses: actions/checkout@v4 @@ -335,18 +365,48 @@ jobs: fail-fast: false matrix: vector: - - jobname: linux-musl - image: alpine - distro: alpine-latest + - jobname: linux-sha256 + image: ubuntu:rolling + cc: clang + - jobname: linux-reftable + image: ubuntu:rolling + cc: clang + - jobname: linux-TEST-vars + image: ubuntu:20.04 + cc: gcc + cc_package: gcc-8 + - jobname: linux-breaking-changes + cc: gcc + image: ubuntu:rolling + - jobname: linux-leaks + image: ubuntu:rolling + cc: gcc + - jobname: linux-reftable-leaks + image: ubuntu:rolling + cc: gcc + - jobname: linux-asan-ubsan + image: ubuntu:rolling + cc: clang + - jobname: linux-meson + image: ubuntu:rolling + cc: gcc + - jobname: linux-musl-meson + image: alpine:latest + # Supported until 2025-04-02. - jobname: linux32 image: i386/ubuntu:focal - distro: ubuntu32-20.04 - jobname: pedantic - image: fedora - distro: fedora-latest + image: fedora:latest + # A RHEL 8 compatible distro. Supported until 2029-05-31. + - jobname: almalinux-8 + image: almalinux:8 + # Supported until 2026-08-31. + - jobname: debian-11 + image: debian:11 env: jobname: ${{matrix.vector.jobname}} - distro: ${{matrix.vector.distro}} + CC: ${{matrix.vector.cc}} + CI_JOB_IMAGE: ${{matrix.vector.image}} runs-on: ubuntu-latest container: ${{matrix.vector.image}} steps: @@ -355,10 +415,12 @@ jobs: run: apt -q update && apt -q -y install libc6-amd64 lib64stdc++6 - uses: actions/checkout@v4 - run: ci/install-dependencies.sh - - run: ci/run-build-and-tests.sh + - run: useradd builder --create-home + - run: chown -R builder . + - run: sudo --preserve-env --set-home --user=builder ci/run-build-and-tests.sh - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' - run: ci/print-test-failures.sh + run: sudo --preserve-env --set-home --user=builder ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v4 diff --git a/.gitignore b/.gitignore index 6687bd6db4c0a6..b47d63555f1576 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ /GIT-TEST-SUITES /GIT-USER-AGENT /GIT-VERSION-FILE -/bin-wrappers/ /git /git-add /git-am @@ -20,6 +19,7 @@ /git-apply /git-archimport /git-archive +/git-backfill /git-bisect /git-blame /git-branch @@ -165,6 +165,7 @@ /git-submodule /git-submodule--helper /git-subtree +/git-survey /git-svn /git-switch /git-symbolic-ref @@ -195,9 +196,11 @@ /config-list.h /command-list.h /hook-list.h +/version-def.h *.tar.gz *.dsc *.deb +/git.rc /git.spec *.exe *.[aos] @@ -249,3 +252,5 @@ Release/ /git.VC.db *.dSYM /contrib/buildsystems/out +/contrib/libgit-rs/target +/contrib/libgit-sys/target diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4abfbc3e208e5b..2805cdeecb6a54 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,11 @@ default: timeout: 2h +stages: + - build + - test + - analyze + workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" @@ -9,10 +14,13 @@ workflow: test:linux: image: $image + stage: test + needs: [ ] tags: - saas-linux-medium-amd64 variables: CUSTOM_PATH: "/custom" + TEST_OUTPUT_DIRECTORY: "/tmp/test-output" before_script: - ./ci/install-dependencies.sh script: @@ -24,42 +32,41 @@ test:linux: if test "$CI_JOB_STATUS" != 'success' then sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh + mv "$TEST_OUTPUT_DIRECTORY"/failed-test-artifacts t/ fi parallel: matrix: - - jobname: linux-old - image: ubuntu:16.04 - CC: gcc - jobname: linux-sha256 - image: ubuntu:latest + image: ubuntu:rolling CC: clang - jobname: linux-reftable - image: ubuntu:latest + image: ubuntu:rolling CC: clang - - jobname: linux-gcc + - jobname: linux-breaking-changes 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 + image: ubuntu:rolling CC: gcc - jobname: linux-reftable-leaks - image: ubuntu:latest + image: ubuntu:rolling CC: gcc - jobname: linux-asan-ubsan - image: ubuntu:latest + image: ubuntu:rolling CC: clang - jobname: pedantic image: fedora:latest - - jobname: linux-musl + - jobname: linux-musl-meson image: alpine:latest + - jobname: linux32 + image: i386/ubuntu:20.04 + - jobname: linux-meson + image: ubuntu:rolling + CC: gcc artifacts: paths: - t/failed-test-artifacts @@ -67,6 +74,8 @@ test:linux: test:osx: image: $image + stage: test + needs: [ ] tags: - saas-macos-medium-m1 variables: @@ -90,18 +99,93 @@ test:osx: parallel: matrix: - jobname: osx-clang - image: macos-13-xcode-14 + image: macos-14-xcode-15 CC: clang - jobname: osx-reftable - image: macos-13-xcode-14 + image: macos-14-xcode-15 + CC: clang + - jobname: osx-meson + image: macos-14-xcode-15 CC: clang artifacts: paths: - t/failed-test-artifacts when: on_failure +build:mingw64: + stage: build + tags: + - saas-windows-medium-amd64 + variables: + NO_PERL: 1 + before_script: + - ./ci/install-sdk.ps1 -directory "git-sdk" + script: + - git-sdk/usr/bin/bash.exe -l -c 'ci/make-test-artifacts.sh artifacts' + artifacts: + paths: + - artifacts + - git-sdk + +test:mingw64: + stage: test + tags: + - saas-windows-medium-amd64 + needs: + - job: "build:mingw64" + artifacts: true + before_script: + - git-sdk/usr/bin/bash.exe -l -c 'tar xf artifacts/artifacts.tar.gz' + - New-Item -Path .git/info -ItemType Directory + - New-Item .git/info/exclude -ItemType File -Value "/git-sdk" + script: + - git-sdk/usr/bin/bash.exe -l -c "ci/run-test-slice.sh $CI_NODE_INDEX $CI_NODE_TOTAL" + after_script: + - git-sdk/usr/bin/bash.exe -l -c 'ci/print-test-failures.sh' + parallel: 10 + +.msvc-meson: + tags: + - saas-windows-medium-amd64 + before_script: + - choco install -y git meson ninja openssl + - Import-Module $env:ChocolateyInstall\helpers\chocolateyProfile.psm1 + - refreshenv + # The certificate store for Python on Windows is broken and fails to fetch + # certificates, see https://bugs.python.org/issue36011. This seems to + # mostly be an issue with how the GitLab image is set up as it is a + # non-issue on GitHub Actions. Work around the issue by importing + # cetrificates manually. + - Invoke-WebRequest https://curl.haxx.se/ca/cacert.pem -OutFile cacert.pem + - openssl pkcs12 -export -nokeys -in cacert.pem -out certs.pfx -passout "pass:" + - Import-PfxCertificate -CertStoreLocation Cert:\LocalMachine\Root -FilePath certs.pfx + +build:msvc-meson: + extends: .msvc-meson + stage: build + script: + - meson setup build -Dperl=disabled -Dbackend_max_links=1 -Dcredential_helpers=wincred + - meson compile -C build + artifacts: + paths: + - build + +test:msvc-meson: + extends: .msvc-meson + stage: test + when: manual + timeout: 6h + needs: + - job: "build:msvc-meson" + artifacts: true + script: + - meson test -C build --list | Select-Object -Skip 1 | Select-String .* | Group-Object -Property { $_.LineNumber % $Env:CI_NODE_TOTAL + 1 } | Where-Object Name -EQ $Env:CI_NODE_INDEX | ForEach-Object { meson test -C build --no-rebuild --print-errorlogs $_.Group; if (!$?) { exit $LASTEXITCODE } } + parallel: 10 + test:fuzz-smoke-tests: image: ubuntu:latest + stage: test + needs: [ ] variables: CC: clang before_script: @@ -111,6 +195,8 @@ test:fuzz-smoke-tests: static-analysis: image: ubuntu:22.04 + stage: analyze + needs: [ ] variables: jobname: StaticAnalysis before_script: @@ -121,6 +207,8 @@ static-analysis: check-whitespace: image: ubuntu:latest + stage: analyze + needs: [ ] before_script: - ./ci/install-dependencies.sh # Since $CI_MERGE_REQUEST_TARGET_BRANCH_SHA is only defined for merged @@ -128,13 +216,15 @@ check-whitespace: # be defined in all pipelines. script: - | - R=${CI_MERGE_REQUEST_TARGET_BRANCH_SHA-${CI_MERGE_REQUEST_DIFF_BASE_SHA:?}} || exit + R=${CI_MERGE_REQUEST_TARGET_BRANCH_SHA:-${CI_MERGE_REQUEST_DIFF_BASE_SHA:?}} || exit ./ci/check-whitespace.sh "$R" rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' check-style: image: ubuntu:latest + stage: analyze + needs: [ ] allow_failure: true variables: CC: clang @@ -146,13 +236,15 @@ check-style: # be defined in all pipelines. script: - | - R=${CI_MERGE_REQUEST_TARGET_BRANCH_SHA-${CI_MERGE_REQUEST_DIFF_BASE_SHA:?}} || exit + R=${CI_MERGE_REQUEST_TARGET_BRANCH_SHA:-${CI_MERGE_REQUEST_DIFF_BASE_SHA:?}} || exit ./ci/run-style-check.sh "$R" rules: - if: $CI_PIPELINE_SOURCE == 'merge_request_event' documentation: image: ubuntu:latest + stage: analyze + needs: [ ] variables: jobname: Documentation before_script: diff --git a/Documentation/.gitattributes b/Documentation/.gitattributes deleted file mode 100644 index ddb030137d54ef..00000000000000 --- a/Documentation/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.txt whitespace diff --git a/Documentation/.gitignore b/Documentation/.gitignore index a48448de32f98b..dd54cc768a250c 100644 --- a/Documentation/.gitignore +++ b/Documentation/.gitignore @@ -6,12 +6,15 @@ *.pdf git.info gitman.info -howto-index.txt +howto-index.adoc doc.dep -cmds-*.txt -mergetools-*.txt -SubmittingPatches.txt +cmds-*.adoc +mergetools-*.adoc +SubmittingPatches.adoc tmp-doc-diff/ +tmp-meson-diff/ GIT-ASCIIDOCFLAGS /.build/ /GIT-EXCLUDED-PROGRAMS +/asciidoc.conf +/asciidoctor-extensions.rb diff --git a/Documentation/BreakingChanges.txt b/Documentation/BreakingChanges.adoc similarity index 75% rename from Documentation/BreakingChanges.txt rename to Documentation/BreakingChanges.adoc index 2b64665694f6a9..bdfad29d8a9e3d 100644 --- a/Documentation/BreakingChanges.txt +++ b/Documentation/BreakingChanges.adoc @@ -59,6 +59,24 @@ over time. If circumstances change, an earlier decision to deprecate or change something may need to be revisited from time to time. So do not take items on this list to mean "it is settled, do not waste our time bringing it up again". +== Procedure + +Discussing the desire to make breaking changes, declaring that breaking +changes are made at a certain version boundary, and recording these +decisions in this document, are necessary but not sufficient. +Because such changes are expected to be numerous, and the design and +implementation of them are expected to span over time, they have to +be deployable trivially at such a version boundary, prepared over long +time. + +The breaking changes MUST be guarded with the a compile-time switch, +WITH_BREAKING_CHANGES, to help this process. When built with it, +the resulting Git binary together with its documentation would +behave as if these breaking changes slated for the next big version +boundary are already in effect. We also have a CI job to exercise +the work-in-progress version of Git with these breaking changes. + + == Git 3.0 The following subsections document upcoming breaking changes for Git 3.0. There @@ -117,7 +135,7 @@ Cf. <20140304174806.GA11561@sigill.intra.peff.net>. * The git-pack-redundant(1) command can be used to remove redundant pack files. The subcommand is unusably slow and the reason why nobody reports it as a - performance bug is suspected to be the absense of users. We have nominated + performance bug is suspected to be the absence of users. We have nominated the command for removal and have started to emit a user-visible warning in c3b58472be (pack-redundant: gauge the usage before proposing its removal, 2020-08-25) whenever the command is executed. @@ -135,6 +153,31 @@ Cf. <xmqq1rjuz6n3.fsf_-_@gitster.c.googlers.com>, <CAKvOHKAFXQwt4D8yUCCkf_TQL79mYaJ=KAKhtpDNTvHJFuX1NA@mail.gmail.com>, <20230323204047.GA9290@coredump.intra.peff.net>, +* Support for storing shorthands for remote URLs in "$GIT_COMMON_DIR/branches/" + and "$GIT_COMMON_DIR/remotes/" has been long superseded by storing remotes in + the repository configuration. ++ +The mechanism has originally been introduced in f170e4b39d ([PATCH] fetch/pull: +short-hand notation for remote repositories., 2005-07-16) and was superseded by +6687f8fea2 ([PATCH] Use .git/remote/origin, not .git/branches/origin., +2005-08-20), where we switched from ".git/branches/" to ".git/remotes/". That +commit already mentions an upcoming deprecation of the ".git/branches/" +directory, and starting with a1d4aa7424 (Add repository-layout document., +2005-09-01) we have also marked this layout as deprecated. Eventually we also +started to migrate away from ".git/remotes/" in favor of config-based remotes, +and we have marked the directory as legacy in 3d3d282146 (Documentation: +Grammar correction, wording fixes and cleanup, 2011-08-23) ++ +As our documentation mentions, these directories are unlikely to be used in +modern repositories and most users aren't even aware of these mechanisms. They +have been deprecated for almost 20 years and 14 years respectively, and we are +not aware of any active users that have complained about this deprecation. +Furthermore, the ".git/branches/" directory is nowadays misleadingly named and +may cause confusion as "branches" are almost exclusively used in the context of +references. ++ +These features will be removed. + == Superseded features that will not be deprecated Some features have gained newer replacements that aim to improve the design in diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 3263245b032370..a0e7041c54b497 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -44,7 +44,7 @@ code are expected to match the style the surrounding code already uses (even if it doesn't match the overall style of existing code). But if you must have a list of rules, here are some language -specific ones. Note that Documentation/ToolsForGit.txt document +specific ones. Note that Documentation/ToolsForGit.adoc document has a collection of tips to help you use some external tools to conform to these guidelines. @@ -583,7 +583,7 @@ For C programs: Run `GIT_DEBUGGER=1 ./bin-wrappers/git foo` to simply use gdb as is, or run `GIT_DEBUGGER="<debugger> <debugger-args>" ./bin-wrappers/git foo` to use your own debugger and arguments. Example: `GIT_DEBUGGER="ddd --gdb" - ./bin-wrappers/git log` (See `wrap-for-bin.sh`.) + ./bin-wrappers/git log` (See `bin-wrappers/wrap-for-bin.sh`.) - The primary data structure that a subsystem 'S' deals with is called `struct S`. Functions that operate on `struct S` are named @@ -621,6 +621,20 @@ For C programs: - `S_free()` releases a structure's contents and frees the structure. + - Function names should be clear and descriptive, accurately reflecting + their purpose or behavior. Arbitrary suffixes that do not add meaningful + context can lead to confusion, particularly for newcomers to the codebase. + + Historically, the '_1' suffix has been used in situations where: + + - A function handles one element among a group that requires similar + processing. + - A recursive function has been separated from its setup phase. + + The '_1' suffix can be used as a concise way to indicate these specific + cases. However, it is recommended to find a more descriptive name wherever + possible to improve the readability and maintainability of the code. + For Perl programs: - Most of the C guidelines above apply. @@ -689,16 +703,30 @@ Program Output Error Messages - - Do not end error messages with a full stop. + - Do not end a single-sentence error message with a full stop. - Do not capitalize the first word, only because it is the first word - in the message ("unable to open %s", not "Unable to open %s"). But + in the message ("unable to open '%s'", not "Unable to open '%s'"). But "SHA-3 not supported" is fine, because the reason the first word is capitalized is not because it is at the beginning of the sentence, but because the word would be spelled in capital letters even when it appeared in the middle of the sentence. - - Say what the error is first ("cannot open %s", not "%s: cannot open") + - Say what the error is first ("cannot open '%s'", not "%s: cannot open"). + + - Enclose the subject of an error inside a pair of single quotes, + e.g. `die(_("unable to open '%s'"), path)`. + + - Unless there is a compelling reason not to, error messages from + porcelain commands should be marked for translation, e.g. + `die(_("bad revision %s"), revision)`. + + - Error messages from the plumbing commands are sometimes meant for + machine consumption and should not be marked for translation, + e.g., `die("bad revision %s", revision)`. + + - BUG("message") are for communicating the specific error to developers, + thus should not be translated. Externally Visible Names @@ -727,7 +755,7 @@ Externally Visible Names Writing Documentation: Most (if not all) of the documentation pages are written in the - AsciiDoc format in *.txt files (e.g. Documentation/git.txt), and + AsciiDoc format in *.adoc files (e.g. Documentation/git.adoc), and processed into HTML and manpages (e.g. git.html and git.1 in the same directory). @@ -828,78 +856,80 @@ Markup: _<new-branch-name>_ _<template-directory>_ - A placeholder is not enclosed in backticks, as it is not a literal. - When needed, use a distinctive identifier for placeholders, usually made of a qualification and a type: _<git-dir>_ _<key-id>_ - When literal and placeholders are mixed, each markup is applied for - each sub-entity. If they are stuck, a special markup, called - unconstrained formatting is required. - Unconstrained formating for placeholders is __<like-this>__ - Unconstrained formatting for literal formatting is ++like this++ - `--jobs` _<n>_ - ++--sort=++__<key>__ - __<directory>__++/.git++ - ++remote.++__<name>__++.mirror++ + Git's Asciidoc processor has been tailored to treat backticked text + as complex synopsis. When literal and placeholders are mixed, you can + use the backtick notation which will take care of correctly typesetting + the content. + `--jobs <n>` + `--sort=<key>` + `<directory>/.git` + `remote.<name>.mirror` + `ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>` - caveat: ++ unconstrained format is not verbatim and may expand - content. Use Asciidoc escapes inside them. +As a side effect, backquoted placeholders are correctly typeset, but +this style is not recommended. Synopsis Syntax - Syntax grammar is formatted neither as literal nor as placeholder. + The synopsis (a paragraph with [synopsis] attribute) is automatically + formatted by the toolchain and does not need typesetting. A few commented examples follow to provide reference when writing or modifying command usage strings and synopsis sections in the manual pages: Possibility of multiple occurrences is indicated by three dots: - _<file>_... + <file>... (One or more of <file>.) Optional parts are enclosed in square brackets: - [_<file>_...] + [<file>...] (Zero or more of <file>.) - ++--exec-path++[++=++__<path>__] + An optional parameter needs to be typeset with unconstrained pairs + [<repository>] + + --exec-path[=<path>] (Option with an optional argument. Note that the "=" is inside the brackets.) - [_<patch>_...] + [<patch>...] (Zero or more of <patch>. Note that the dots are inside, not outside the brackets.) Multiple alternatives are indicated with vertical bars: - [`-q` | `--quiet`] - [`--utf8` | `--no-utf8`] + [-q | --quiet] + [--utf8 | --no-utf8] Use spacing around "|" token(s), but not immediately after opening or before closing a [] or () pair: - Do: [`-q` | `--quiet`] - Don't: [`-q`|`--quiet`] + Do: [-q | --quiet] + Don't: [-q|--quiet] Don't use spacing around "|" tokens when they're used to separate the alternate arguments of an option: - Do: ++--track++[++=++(`direct`|`inherit`)]` - Don't: ++--track++[++=++(`direct` | `inherit`)] + Do: --track[=(direct|inherit)] + Don't: --track[=(direct | inherit)] Parentheses are used for grouping: - [(_<rev>_ | _<range>_)...] + [(<rev>|<range>)...] (Any number of either <rev> or <range>. Parens are needed to make it clear that "..." pertains to both <rev> and <range>.) - [(`-p` _<parent>_)...] + [(-p <parent>)...] (Any number of option -p, each with one <parent> argument.) - `git remote set-head` _<name>_ (`-a` | `-d` | _<branch>_) + git remote set-head <name> (-a|-d|<branch>) (One and only one of "-a", "-d" or "<branch>" _must_ (no square brackets) be provided.) And a somewhat more contrived example: - `--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]` + --diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]] Here "=" is outside the brackets, because "--diff-filter=" is a valid usage. "*" has its own pair of brackets, because it can (optionally) be specified only when one or more of the letters is diff --git a/Documentation/DecisionMaking.txt b/Documentation/DecisionMaking.adoc similarity index 98% rename from Documentation/DecisionMaking.txt rename to Documentation/DecisionMaking.adoc index dbb4c1f56981d0..b43c472ae598ed 100644 --- a/Documentation/DecisionMaking.txt +++ b/Documentation/DecisionMaking.adoc @@ -54,7 +54,7 @@ implementation, for very large changes). For non-technical decisions such as community norms or processes, it is up to the community as a whole to implement and sustain agreed-upon changes. -The project leadership committe (PLC) may help the implementation of +The project leadership committee (PLC) may help the implementation of policy decisions. diff --git a/Documentation/Makefile b/Documentation/Makefile index 0f55baa252fffb..671267a8ac7af6 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,6 +1,11 @@ +# The default target of this Makefile is... +all:: + # Import tree-wide shared Makefile behavior and libraries include ../shared.mak +.PHONY: FORCE + # Guard against environment variables MAN1_TXT = MAN5_TXT = @@ -15,56 +20,56 @@ OBSOLETE_HTML = -include GIT-EXCLUDED-PROGRAMS MAN1_TXT += $(filter-out \ - $(patsubst %,%.txt,$(EXCLUDED_PROGRAMS)) \ - $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ - $(wildcard git-*.txt)) -MAN1_TXT += git.txt -MAN1_TXT += gitk.txt -MAN1_TXT += gitweb.txt -MAN1_TXT += scalar.txt + $(patsubst %,%.adoc,$(EXCLUDED_PROGRAMS)) \ + $(addsuffix .adoc, $(ARTICLES) $(SP_ARTICLES)), \ + $(wildcard git-*.adoc)) +MAN1_TXT += git.adoc +MAN1_TXT += gitk.adoc +MAN1_TXT += gitweb.adoc +MAN1_TXT += scalar.adoc # man5 / man7 guides (note: new guides should also be added to command-list.txt) -MAN5_TXT += gitattributes.txt -MAN5_TXT += gitformat-bundle.txt -MAN5_TXT += gitformat-chunk.txt -MAN5_TXT += gitformat-commit-graph.txt -MAN5_TXT += gitformat-index.txt -MAN5_TXT += gitformat-pack.txt -MAN5_TXT += gitformat-signature.txt -MAN5_TXT += githooks.txt -MAN5_TXT += gitignore.txt -MAN5_TXT += gitmailmap.txt -MAN5_TXT += gitmodules.txt -MAN5_TXT += gitprotocol-capabilities.txt -MAN5_TXT += gitprotocol-common.txt -MAN5_TXT += gitprotocol-http.txt -MAN5_TXT += gitprotocol-pack.txt -MAN5_TXT += gitprotocol-v2.txt -MAN5_TXT += gitrepository-layout.txt -MAN5_TXT += gitweb.conf.txt - -MAN7_TXT += gitcli.txt -MAN7_TXT += gitcore-tutorial.txt -MAN7_TXT += gitcredentials.txt -MAN7_TXT += gitcvs-migration.txt -MAN7_TXT += gitdiffcore.txt -MAN7_TXT += giteveryday.txt -MAN7_TXT += gitfaq.txt -MAN7_TXT += gitglossary.txt -MAN7_TXT += gitpacking.txt -MAN7_TXT += gitnamespaces.txt -MAN7_TXT += gitremote-helpers.txt -MAN7_TXT += gitrevisions.txt -MAN7_TXT += gitsubmodules.txt -MAN7_TXT += gittutorial-2.txt -MAN7_TXT += gittutorial.txt -MAN7_TXT += gitworkflows.txt - -HOWTO_TXT += $(wildcard howto/*.txt) - -DOC_DEP_TXT += $(wildcard *.txt) -DOC_DEP_TXT += $(wildcard config/*.txt) -DOC_DEP_TXT += $(wildcard includes/*.txt) +MAN5_TXT += gitattributes.adoc +MAN5_TXT += gitformat-bundle.adoc +MAN5_TXT += gitformat-chunk.adoc +MAN5_TXT += gitformat-commit-graph.adoc +MAN5_TXT += gitformat-index.adoc +MAN5_TXT += gitformat-pack.adoc +MAN5_TXT += gitformat-signature.adoc +MAN5_TXT += githooks.adoc +MAN5_TXT += gitignore.adoc +MAN5_TXT += gitmailmap.adoc +MAN5_TXT += gitmodules.adoc +MAN5_TXT += gitprotocol-capabilities.adoc +MAN5_TXT += gitprotocol-common.adoc +MAN5_TXT += gitprotocol-http.adoc +MAN5_TXT += gitprotocol-pack.adoc +MAN5_TXT += gitprotocol-v2.adoc +MAN5_TXT += gitrepository-layout.adoc +MAN5_TXT += gitweb.conf.adoc + +MAN7_TXT += gitcli.adoc +MAN7_TXT += gitcore-tutorial.adoc +MAN7_TXT += gitcredentials.adoc +MAN7_TXT += gitcvs-migration.adoc +MAN7_TXT += gitdiffcore.adoc +MAN7_TXT += giteveryday.adoc +MAN7_TXT += gitfaq.adoc +MAN7_TXT += gitglossary.adoc +MAN7_TXT += gitpacking.adoc +MAN7_TXT += gitnamespaces.adoc +MAN7_TXT += gitremote-helpers.adoc +MAN7_TXT += gitrevisions.adoc +MAN7_TXT += gitsubmodules.adoc +MAN7_TXT += gittutorial-2.adoc +MAN7_TXT += gittutorial.adoc +MAN7_TXT += gitworkflows.adoc + +HOWTO_TXT += $(wildcard howto/*.adoc) + +DOC_DEP_TXT += $(wildcard *.adoc) +DOC_DEP_TXT += $(wildcard config/*.adoc) +DOC_DEP_TXT += $(wildcard includes/*.adoc) ifdef MAN_FILTER MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT)) @@ -73,8 +78,8 @@ MAN_TXT = $(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT) MAN_FILTER = $(MAN_TXT) endif -MAN_XML = $(patsubst %.txt,%.xml,$(MAN_TXT)) -MAN_HTML = $(patsubst %.txt,%.html,$(MAN_TXT)) +MAN_XML = $(patsubst %.adoc,%.xml,$(MAN_TXT)) +MAN_HTML = $(patsubst %.adoc,%.html,$(MAN_TXT)) GIT_MAN_REF = master OBSOLETE_HTML += everyday.html @@ -101,7 +106,7 @@ SP_ARTICLES += howto/rebase-from-internal-branch SP_ARTICLES += howto/keep-canonical-history-correct SP_ARTICLES += howto/maintain-git SP_ARTICLES += howto/coordinate-embargoed-releases -API_DOCS = $(patsubst %.txt,%,$(filter-out technical/api-index-skel.txt technical/api-index.txt, $(wildcard technical/api-*.txt))) +API_DOCS = $(patsubst %.adoc,%,$(filter-out technical/api-index-skel.adoc technical/api-index.adoc, $(wildcard technical/api-*.adoc))) SP_ARTICLES += $(API_DOCS) TECH_DOCS += DecisionMaking @@ -111,6 +116,7 @@ TECH_DOCS += MyFirstObjectWalk TECH_DOCS += SubmittingPatches TECH_DOCS += ToolsForGit TECH_DOCS += technical/bitmap-format +TECH_DOCS += technical/build-systems TECH_DOCS += technical/bundle-uri TECH_DOCS += technical/hash-function-transition TECH_DOCS += technical/long-running-process-protocol @@ -133,9 +139,9 @@ ARTICLES_HTML += $(patsubst %,%.html,$(ARTICLES) $(SP_ARTICLES)) HTML_FILTER ?= $(ARTICLES_HTML) $(OBSOLETE_HTML) DOC_HTML = $(MAN_HTML) $(filter $(HTML_FILTER),$(ARTICLES_HTML) $(OBSOLETE_HTML)) -DOC_MAN1 = $(patsubst %.txt,%.1,$(filter $(MAN_FILTER),$(MAN1_TXT))) -DOC_MAN5 = $(patsubst %.txt,%.5,$(filter $(MAN_FILTER),$(MAN5_TXT))) -DOC_MAN7 = $(patsubst %.txt,%.7,$(filter $(MAN_FILTER),$(MAN7_TXT))) +DOC_MAN1 = $(patsubst %.adoc,%.1,$(filter $(MAN_FILTER),$(MAN1_TXT))) +DOC_MAN5 = $(patsubst %.adoc,%.5,$(filter $(MAN_FILTER),$(MAN5_TXT))) +DOC_MAN7 = $(patsubst %.adoc,%.7,$(filter $(MAN_FILTER),$(MAN7_TXT))) prefix ?= $(HOME) bindir ?= $(prefix)/bin @@ -148,16 +154,12 @@ man5dir = $(mandir)/man5 man7dir = $(mandir)/man7 # DESTDIR = -GIT_DATE := $(shell git show --quiet --pretty='%as') - ASCIIDOC = asciidoc ASCIIDOC_EXTRA = ASCIIDOC_HTML = xhtml11 ASCIIDOC_DOCBOOK = docbook ASCIIDOC_CONF = -f asciidoc.conf -ASCIIDOC_COMMON = $(ASCIIDOC) $(ASCIIDOC_EXTRA) $(ASCIIDOC_CONF) \ - -amanmanual='Git Manual' -amansource='Git $(GIT_VERSION)' \ - -arevdate='$(GIT_DATE)' +ASCIIDOC_COMMON = $(ASCIIDOC) $(ASCIIDOC_EXTRA) $(ASCIIDOC_CONF) ASCIIDOC_DEPS = asciidoc.conf GIT-ASCIIDOCFLAGS TXT_TO_HTML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_HTML) TXT_TO_XML = $(ASCIIDOC_COMMON) -b $(ASCIIDOC_DOCBOOK) @@ -182,6 +184,10 @@ endif -include ../config.mak.autogen -include ../config.mak +# Set GIT_VERSION_OVERRIDE such that version_gen knows to substitute +# GIT_VERSION in case it was set by the user. +GIT_VERSION_OVERRIDE := $(GIT_VERSION) + ifndef NO_MAN_BOLD_LITERAL XMLTO_EXTRA += -m manpage-bold-literal.xsl endif @@ -210,6 +216,16 @@ ASCIIDOC_DEPS = asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS DBLATEX_COMMON = XMLTO_EXTRA += --skip-validation XMLTO_EXTRA += -x manpage.xsl + +asciidoctor-extensions.rb: asciidoctor-extensions.rb.in FORCE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)/..",$<,$@) +else +asciidoc.conf: asciidoc.conf.in FORCE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)/..",$<,$@) +endif + +ifdef WITH_BREAKING_CHANGES +ASCIIDOC_EXTRA += -awith-breaking-changes endif ASCIIDOC_DEPS += docinfo.html @@ -218,6 +234,7 @@ SHELL_PATH ?= $(SHELL) # Shell quote; SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) +ASCIIDOC_EXTRA += -abuild_dir='$(shell pwd)' ifdef DEFAULT_PAGER DEFAULT_PAGER_SQ = $(subst ','\'',$(DEFAULT_PAGER)) ASCIIDOC_EXTRA += -a 'git-default-pager=$(DEFAULT_PAGER_SQ)' @@ -228,7 +245,7 @@ DEFAULT_EDITOR_SQ = $(subst ','\'',$(DEFAULT_EDITOR)) ASCIIDOC_EXTRA += -a 'git-default-editor=$(DEFAULT_EDITOR_SQ)' endif -all: html man +all:: html man html: $(DOC_HTML) @@ -268,59 +285,46 @@ install-pdf: pdf install-html: html '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir) -../GIT-VERSION-FILE: FORCE - $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE - -ifneq ($(filter-out lint-docs clean,$(MAKECMDGOALS)),) --include ../GIT-VERSION-FILE -endif +mergetools_txt = mergetools-diff.adoc mergetools-merge.adoc # # Determine "include::" file references in asciidoc files. # docdep_prereqs = \ - mergetools-list.made $(mergetools_txt) \ + $(mergetools_txt) \ cmd-list.made $(cmds_txt) doc.dep : $(docdep_prereqs) $(DOC_DEP_TXT) build-docdep.perl - $(QUIET_GEN)$(PERL_PATH) ./build-docdep.perl >$@ $(QUIET_STDERR) + $(QUIET_GEN)$(PERL_PATH) ./build-docdep.perl "$(shell pwd)" >$@ $(QUIET_STDERR) ifneq ($(MAKECMDGOALS),clean) -include doc.dep endif -cmds_txt = cmds-ancillaryinterrogators.txt \ - cmds-ancillarymanipulators.txt \ - cmds-mainporcelain.txt \ - cmds-plumbinginterrogators.txt \ - cmds-plumbingmanipulators.txt \ - cmds-synchingrepositories.txt \ - cmds-synchelpers.txt \ - cmds-guide.txt \ - cmds-developerinterfaces.txt \ - cmds-userinterfaces.txt \ - cmds-purehelpers.txt \ - cmds-foreignscminterface.txt +cmds_txt = cmds-ancillaryinterrogators.adoc \ + cmds-ancillarymanipulators.adoc \ + cmds-mainporcelain.adoc \ + cmds-plumbinginterrogators.adoc \ + cmds-plumbingmanipulators.adoc \ + cmds-synchingrepositories.adoc \ + cmds-synchelpers.adoc \ + cmds-guide.adoc \ + cmds-developerinterfaces.adoc \ + cmds-userinterfaces.adoc \ + cmds-purehelpers.adoc \ + cmds-foreignscminterface.adoc $(cmds_txt): cmd-list.made cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) - $(QUIET_GEN)$(PERL_PATH) ./cmd-list.perl ../command-list.txt $(cmds_txt) $(QUIET_STDERR) && \ + $(QUIET_GEN)$(PERL_PATH) ./cmd-list.perl .. . $(cmds_txt) && \ date >$@ -mergetools_txt = mergetools-diff.txt mergetools-merge.txt - -$(mergetools_txt): mergetools-list.made - -mergetools-list.made: ../git-mergetool--lib.sh $(wildcard ../mergetools/*) - $(QUIET_GEN) \ - $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && TOOL_MODE=diff && \ - . ../git-mergetool--lib.sh && \ - show_tool_names can_diff' | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >mergetools-diff.txt && \ - $(SHELL_PATH) -c 'MERGE_TOOLS_DIR=../mergetools && TOOL_MODE=merge && \ - . ../git-mergetool--lib.sh && \ - show_tool_names can_merge' | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >mergetools-merge.txt && \ - date >$@ +mergetools-%.adoc: generate-mergetool-list.sh ../git-mergetool--lib.sh $(wildcard ../mergetools/*) +mergetools-diff.adoc: + $(QUIET_GEN)$(SHELL_PATH) ./generate-mergetool-list.sh .. diff $@ +mergetools-merge.adoc: + $(QUIET_GEN)$(SHELL_PATH) ./generate-mergetool-list.sh .. merge $@ TRACK_ASCIIDOCFLAGS = $(subst ','\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK)) @@ -336,19 +340,21 @@ clean: $(RM) *.xml *.xml+ *.html *.html+ *.1 *.5 *.7 $(RM) *.texi *.texi+ *.texi++ git.info gitman.info $(RM) *.pdf - $(RM) howto-index.txt howto/*.html doc.dep - $(RM) technical/*.html technical/api-index.txt - $(RM) SubmittingPatches.txt + $(RM) howto-index.adoc howto/*.html doc.dep + $(RM) technical/*.html technical/api-index.adoc + $(RM) SubmittingPatches.adoc $(RM) $(cmds_txt) $(mergetools_txt) *.made $(RM) GIT-ASCIIDOCFLAGS + $(RM) asciidoc.conf asciidoctor-extensions.rb + $(RM) -rf tmp-meson-diff docinfo.html: docinfo-html.in $(QUIET_GEN)$(RM) $@ && cat $< >$@ -$(MAN_HTML): %.html : %.txt $(ASCIIDOC_DEPS) +$(MAN_HTML): %.html : %.adoc $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_HTML) -d manpage -o $@ $< -$(OBSOLETE_HTML): %.html : %.txto $(ASCIIDOC_DEPS) +$(OBSOLETE_HTML): %.html : %.adoco $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_HTML) -o $@ $< manpage-prereqs := $(wildcard manpage*.xsl) @@ -361,22 +367,22 @@ manpage-cmd = $(QUIET_XMLTO)$(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< %.7 : %.xml $(manpage-prereqs) $(manpage-cmd) -%.xml : %.txt $(ASCIIDOC_DEPS) +%.xml : %.adoc $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_XML) -d manpage -o $@ $< -user-manual.xml: user-manual.txt user-manual.conf asciidoctor-extensions.rb GIT-ASCIIDOCFLAGS +user-manual.xml: user-manual.adoc $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_XML) -d book -o $@ $< -technical/api-index.txt: technical/api-index-skel.txt \ - technical/api-index.sh $(patsubst %,%.txt,$(API_DOCS)) - $(QUIET_GEN)cd technical && '$(SHELL_PATH_SQ)' ./api-index.sh +technical/api-index.adoc: technical/api-index-skel.adoc \ + technical/api-index.sh $(patsubst %,%.adoc,$(API_DOCS)) + $(QUIET_GEN)'$(SHELL_PATH_SQ)' technical/api-index.sh ./technical ./technical/api-index.adoc technical/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../ -$(patsubst %,%.html,$(API_DOCS) technical/api-index $(TECH_DOCS)): %.html : %.txt \ - asciidoc.conf GIT-ASCIIDOCFLAGS - $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.txt +$(patsubst %,%.html,$(API_DOCS) technical/api-index $(TECH_DOCS)): %.html : %.adoc \ + $(ASCIIDOC_DEPS) + $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.adoc -SubmittingPatches.txt: SubmittingPatches +SubmittingPatches.adoc: SubmittingPatches $(QUIET_GEN) cp $< $@ XSLT = docbook.xsl @@ -410,19 +416,19 @@ gitman.texi: $(MAN_XML) cat-texi.perl texi.xsl gitman.info: gitman.texi $(QUIET_MAKEINFO)$(MAKEINFO) --no-split --no-validate $< -$(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml +$(patsubst %.adoc,%.texi,$(MAN_TXT)): %.texi : %.xml $(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@ -howto-index.txt: howto-index.sh $(HOWTO_TXT) - $(QUIET_GEN)'$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(HOWTO_TXT)) >$@ +howto-index.adoc: howto/howto-index.sh $(HOWTO_TXT) + $(QUIET_GEN)'$(SHELL_PATH_SQ)' ./howto/howto-index.sh $(sort $(HOWTO_TXT)) >$@ -$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt - $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.txt +$(patsubst %,%.html,$(ARTICLES)) : %.html : %.adoc $(ASCIIDOC_DEPS) + $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.adoc WEBDOC_DEST = /pub/software/scm/git/docs howto/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../ -$(patsubst %.txt,%.html,$(HOWTO_TXT)): %.html : %.txt GIT-ASCIIDOCFLAGS +$(patsubst %.adoc,%.html,$(HOWTO_TXT)): %.html : %.adoc $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC) \ sed -e '1,/^$$/d' $< | \ $(TXT_TO_HTML) - >$@ @@ -453,9 +459,9 @@ print-man1: @for i in $(MAN1_TXT); do echo $$i; done ## Lint: gitlink -LINT_DOCS_GITLINK = $(patsubst %.txt,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT)) +LINT_DOCS_GITLINK = $(patsubst %.adoc,.build/lint-docs/gitlink/%.ok,$(HOWTO_TXT) $(DOC_DEP_TXT)) $(LINT_DOCS_GITLINK): lint-gitlink.perl -$(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt +$(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.adoc $(call mkdir_p_parent_template) $(QUIET_LINT_GITLINK)$(PERL_PATH) lint-gitlink.perl \ $< \ @@ -467,17 +473,17 @@ $(LINT_DOCS_GITLINK): .build/lint-docs/gitlink/%.ok: %.txt lint-docs-gitlink: $(LINT_DOCS_GITLINK) ## Lint: man-end-blurb -LINT_DOCS_MAN_END_BLURB = $(patsubst %.txt,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT)) +LINT_DOCS_MAN_END_BLURB = $(patsubst %.adoc,.build/lint-docs/man-end-blurb/%.ok,$(MAN_TXT)) $(LINT_DOCS_MAN_END_BLURB): lint-man-end-blurb.perl -$(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.txt +$(LINT_DOCS_MAN_END_BLURB): .build/lint-docs/man-end-blurb/%.ok: %.adoc $(call mkdir_p_parent_template) $(QUIET_LINT_MANEND)$(PERL_PATH) lint-man-end-blurb.perl $< >$@ .PHONY: lint-docs-man-end-blurb ## Lint: man-section-order -LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.txt,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT)) +LINT_DOCS_MAN_SECTION_ORDER = $(patsubst %.adoc,.build/lint-docs/man-section-order/%.ok,$(MAN_TXT)) $(LINT_DOCS_MAN_SECTION_ORDER): lint-man-section-order.perl -$(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.txt +$(LINT_DOCS_MAN_SECTION_ORDER): .build/lint-docs/man-section-order/%.ok: %.adoc $(call mkdir_p_parent_template) $(QUIET_LINT_MANSEC)$(PERL_PATH) lint-man-section-order.perl $< >$@ .PHONY: lint-docs-man-section-order @@ -486,16 +492,30 @@ lint-docs-man-section-order: $(LINT_DOCS_MAN_SECTION_ORDER) .PHONY: lint-docs-fsck-msgids LINT_DOCS_FSCK_MSGIDS = .build/lint-docs/fsck-msgids.ok $(LINT_DOCS_FSCK_MSGIDS): lint-fsck-msgids.perl -$(LINT_DOCS_FSCK_MSGIDS): ../fsck.h fsck-msgids.txt +$(LINT_DOCS_FSCK_MSGIDS): ../fsck.h fsck-msgids.adoc $(call mkdir_p_parent_template) $(QUIET_GEN)$(PERL_PATH) lint-fsck-msgids.perl \ - ../fsck.h fsck-msgids.txt $@ + ../fsck.h fsck-msgids.adoc $@ lint-docs-fsck-msgids: $(LINT_DOCS_FSCK_MSGIDS) lint-docs-manpages: $(QUIET_GEN)./lint-manpages.sh +.PHONY: lint-docs-meson +lint-docs-meson: + @# awk acts up when trying to match single quotes, so we use \047 instead. + @mkdir -p tmp-meson-diff && \ + awk "/^manpages = {$$/ {flag=1 ; next } /^}$$/ { flag=0 } flag { gsub(/^ \047/, \"\"); gsub(/\047 : [157],\$$/, \"\"); print }" meson.build | \ + grep -v -e '#' -e '^$$' | \ + sort >tmp-meson-diff/meson.adoc && \ + ls git*.adoc scalar.adoc | grep -v -e git-bisect-lk2009.adoc -e git-tools.adoc >tmp-meson-diff/actual.adoc && \ + if ! cmp tmp-meson-diff/meson.adoc tmp-meson-diff/actual.adoc; then \ + echo "Meson man pages differ from actual man pages:"; \ + diff -u tmp-meson-diff/meson.adoc tmp-meson-diff/actual.adoc; \ + exit 1; \ + fi + ## Lint: list of targets above .PHONY: lint-docs lint-docs: lint-docs-fsck-msgids @@ -503,6 +523,7 @@ lint-docs: lint-docs-gitlink lint-docs: lint-docs-man-end-blurb lint-docs: lint-docs-man-section-order lint-docs: lint-docs-manpages +lint-docs: lint-docs-meson ifeq ($(wildcard po/Makefile),po/Makefile) doc-l10n install-l10n:: diff --git a/Documentation/MyFirstContribution.txt b/Documentation/MyFirstContribution.adoc similarity index 98% rename from Documentation/MyFirstContribution.txt rename to Documentation/MyFirstContribution.adoc index e41654c00a68e0..afcf4b46c11ab2 100644 --- a/Documentation/MyFirstContribution.txt +++ b/Documentation/MyFirstContribution.adoc @@ -21,7 +21,7 @@ This tutorial aims to summarize the following documents, but the reader may find useful additional context: - `Documentation/SubmittingPatches` -- `Documentation/howto/new-command.txt` +- `Documentation/howto/new-command.adoc` [[getting-help]] === Getting Help @@ -331,7 +331,7 @@ function body: apply standard precedence rules. `git_config_get_string_tmp()` will look up a specific key ("user.name") and give you the value. There are a number of single-key lookup functions like this one; you can see them all (and more info -about how to use `git_config()`) in `Documentation/technical/api-config.txt`. +about how to use `git_config()`) in `Documentation/technical/api-config.adoc`. You should see that the name printed matches the one you see when you run: @@ -461,10 +461,10 @@ $ ./bin-wrappers/git help psuh Your new command is undocumented! Let's fix that. -Take a look at `Documentation/git-*.txt`. These are the manpages for the +Take a look at `Documentation/git-*.adoc`. These are the manpages for the subcommands that Git knows about. You can open these up and take a look to get acquainted with the format, but then go ahead and make a new file -`Documentation/git-psuh.txt`. Like with most of the documentation in the Git +`Documentation/git-psuh.adoc`. Like with most of the documentation in the Git project, help pages are written with AsciiDoc (see CodingGuidelines, "Writing Documentation" section). Use the following template to fill out your own manpage: @@ -543,7 +543,7 @@ Try and run `./bin-wrappers/git psuh -h`. Your command should crash at the end. That's because `-h` is a special case which your command should handle by printing usage. -Take a look at `Documentation/technical/api-parse-options.txt`. This is a handy +Take a look at `Documentation/technical/api-parse-options.adoc`. This is a handy tool for pulling out options you need to be able to handle, and it takes a usage string. @@ -1088,14 +1088,14 @@ This gives reviewers a summary of what they're in for when reviewing your topic. The one generated for `psuh` from the sample implementation looks like this: ---- - Documentation/git-psuh.txt | 40 +++++++++++++++++++++ - Makefile | 1 + - builtin.h | 1 + - builtin/psuh.c | 73 ++++++++++++++++++++++++++++++++++++++ - git.c | 1 + - t/t9999-psuh-tutorial.sh | 12 +++++++ + Documentation/git-psuh.adoc | 40 +++++++++++++++++++++ + Makefile | 1 + + builtin.h | 1 + + builtin/psuh.c | 73 ++++++++++++++++++++++++++++++++++++++ + git.c | 1 + + t/t9999-psuh-tutorial.sh | 12 +++++++ 6 files changed, 128 insertions(+) - create mode 100644 Documentation/git-psuh.txt + create mode 100644 Documentation/git-psuh.adoc create mode 100644 builtin/psuh.c create mode 100755 t/t9999-psuh-tutorial.sh ---- diff --git a/Documentation/MyFirstObjectWalk.txt b/Documentation/MyFirstObjectWalk.adoc similarity index 98% rename from Documentation/MyFirstObjectWalk.txt rename to Documentation/MyFirstObjectWalk.adoc index dec8afe5b10533..d6e9dfdbbe232e 100644 --- a/Documentation/MyFirstObjectWalk.txt +++ b/Documentation/MyFirstObjectWalk.adoc @@ -15,7 +15,7 @@ revision walk is used for operations like `git log`. === Related Reading -- `Documentation/user-manual.txt` under "Hacking Git" contains some coverage of +- `Documentation/user-manual.adoc` under "Hacking Git" contains some coverage of the revision walker in its various incarnations. - `revision.h` - https://eagain.net/articles/git-for-computer-scientists/[Git for Computer Scientists] @@ -112,7 +112,7 @@ $ GIT_TRACE=1 ./bin-wrappers/git walken ---- NOTE: For a more exhaustive overview of the new command process, take a look at -`Documentation/MyFirstContribution.txt`. +`Documentation/MyFirstContribution.adoc`. NOTE: A reference implementation can be found at https://github.com/nasamuffin/git/tree/revwalk. @@ -132,7 +132,7 @@ used to track the allocated size of the list. Per entry, we find: `item` is the object provided upon which to base the object walk. Items in Git -can be blobs, trees, commits, or tags. (See `Documentation/gittutorial-2.txt`.) +can be blobs, trees, commits, or tags. (See `Documentation/gittutorial-2.adoc`.) `name` is the object ID (OID) of the object - a hex string you may be familiar with from using Git to organize your source in the past. Check the tutorial @@ -141,7 +141,7 @@ from. `whence` indicates some information about what to do with the parents of the specified object. We'll explore this flag more later on; take a look at -`Documentation/revisions.txt` to get an idea of what could set the `whence` +`Documentation/revisions.adoc` to get an idea of what could set the `whence` value. `flags` are used to hint the beginning of the revision walk and are the first @@ -153,7 +153,7 @@ can be used during the walk, as well. This one is quite a bit longer, and many fields are only used during the walk by `revision.c` - not configuration options. Most of the configurable flags in -`struct rev_info` have a mirror in `Documentation/rev-list-options.txt`. It's a +`struct rev_info` have a mirror in `Documentation/rev-list-options.adoc`. It's a good idea to take some time and read through that document. == Basic Commit Walk @@ -710,7 +710,7 @@ objects grows along with the Git project. === Adding a Filter There are a handful of filters that we can apply to the object walk laid out in -`Documentation/rev-list-options.txt`. These filters are typically useful for +`Documentation/rev-list-options.adoc`. These filters are typically useful for operations such as creating packfiles or performing a partial clone. They are defined in `list-objects-filter-options.h`. For the purposes of this tutorial we will use the "tree:1" filter, which causes the walk to omit all trees and blobs diff --git a/Documentation/RelNotes/1.5.0.1.txt b/Documentation/RelNotes/1.5.0.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.1.txt rename to Documentation/RelNotes/1.5.0.1.adoc diff --git a/Documentation/RelNotes/1.5.0.2.txt b/Documentation/RelNotes/1.5.0.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.2.txt rename to Documentation/RelNotes/1.5.0.2.adoc diff --git a/Documentation/RelNotes/1.5.0.3.txt b/Documentation/RelNotes/1.5.0.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.3.txt rename to Documentation/RelNotes/1.5.0.3.adoc diff --git a/Documentation/RelNotes/1.5.0.4.txt b/Documentation/RelNotes/1.5.0.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.4.txt rename to Documentation/RelNotes/1.5.0.4.adoc diff --git a/Documentation/RelNotes/1.5.0.5.txt b/Documentation/RelNotes/1.5.0.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.5.txt rename to Documentation/RelNotes/1.5.0.5.adoc diff --git a/Documentation/RelNotes/1.5.0.6.txt b/Documentation/RelNotes/1.5.0.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.6.txt rename to Documentation/RelNotes/1.5.0.6.adoc diff --git a/Documentation/RelNotes/1.5.0.7.txt b/Documentation/RelNotes/1.5.0.7.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.7.txt rename to Documentation/RelNotes/1.5.0.7.adoc diff --git a/Documentation/RelNotes/1.5.0.txt b/Documentation/RelNotes/1.5.0.adoc similarity index 100% rename from Documentation/RelNotes/1.5.0.txt rename to Documentation/RelNotes/1.5.0.adoc diff --git a/Documentation/RelNotes/1.5.1.1.txt b/Documentation/RelNotes/1.5.1.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.1.txt rename to Documentation/RelNotes/1.5.1.1.adoc diff --git a/Documentation/RelNotes/1.5.1.2.txt b/Documentation/RelNotes/1.5.1.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.2.txt rename to Documentation/RelNotes/1.5.1.2.adoc diff --git a/Documentation/RelNotes/1.5.1.3.txt b/Documentation/RelNotes/1.5.1.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.3.txt rename to Documentation/RelNotes/1.5.1.3.adoc diff --git a/Documentation/RelNotes/1.5.1.4.txt b/Documentation/RelNotes/1.5.1.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.4.txt rename to Documentation/RelNotes/1.5.1.4.adoc diff --git a/Documentation/RelNotes/1.5.1.5.txt b/Documentation/RelNotes/1.5.1.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.5.txt rename to Documentation/RelNotes/1.5.1.5.adoc diff --git a/Documentation/RelNotes/1.5.1.6.txt b/Documentation/RelNotes/1.5.1.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.6.txt rename to Documentation/RelNotes/1.5.1.6.adoc diff --git a/Documentation/RelNotes/1.5.1.txt b/Documentation/RelNotes/1.5.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.1.txt rename to Documentation/RelNotes/1.5.1.adoc diff --git a/Documentation/RelNotes/1.5.2.1.txt b/Documentation/RelNotes/1.5.2.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.2.1.txt rename to Documentation/RelNotes/1.5.2.1.adoc diff --git a/Documentation/RelNotes/1.5.2.2.txt b/Documentation/RelNotes/1.5.2.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.2.2.txt rename to Documentation/RelNotes/1.5.2.2.adoc diff --git a/Documentation/RelNotes/1.5.2.3.txt b/Documentation/RelNotes/1.5.2.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.2.3.txt rename to Documentation/RelNotes/1.5.2.3.adoc diff --git a/Documentation/RelNotes/1.5.2.4.txt b/Documentation/RelNotes/1.5.2.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.2.4.txt rename to Documentation/RelNotes/1.5.2.4.adoc diff --git a/Documentation/RelNotes/1.5.2.5.txt b/Documentation/RelNotes/1.5.2.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.2.5.txt rename to Documentation/RelNotes/1.5.2.5.adoc diff --git a/Documentation/RelNotes/1.5.2.txt b/Documentation/RelNotes/1.5.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.2.txt rename to Documentation/RelNotes/1.5.2.adoc diff --git a/Documentation/RelNotes/1.5.3.1.txt b/Documentation/RelNotes/1.5.3.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.1.txt rename to Documentation/RelNotes/1.5.3.1.adoc diff --git a/Documentation/RelNotes/1.5.3.2.txt b/Documentation/RelNotes/1.5.3.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.2.txt rename to Documentation/RelNotes/1.5.3.2.adoc diff --git a/Documentation/RelNotes/1.5.3.3.txt b/Documentation/RelNotes/1.5.3.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.3.txt rename to Documentation/RelNotes/1.5.3.3.adoc diff --git a/Documentation/RelNotes/1.5.3.4.txt b/Documentation/RelNotes/1.5.3.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.4.txt rename to Documentation/RelNotes/1.5.3.4.adoc diff --git a/Documentation/RelNotes/1.5.3.5.txt b/Documentation/RelNotes/1.5.3.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.5.txt rename to Documentation/RelNotes/1.5.3.5.adoc diff --git a/Documentation/RelNotes/1.5.3.6.txt b/Documentation/RelNotes/1.5.3.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.6.txt rename to Documentation/RelNotes/1.5.3.6.adoc diff --git a/Documentation/RelNotes/1.5.3.7.txt b/Documentation/RelNotes/1.5.3.7.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.7.txt rename to Documentation/RelNotes/1.5.3.7.adoc diff --git a/Documentation/RelNotes/1.5.3.8.txt b/Documentation/RelNotes/1.5.3.8.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.8.txt rename to Documentation/RelNotes/1.5.3.8.adoc diff --git a/Documentation/RelNotes/1.5.3.txt b/Documentation/RelNotes/1.5.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.3.txt rename to Documentation/RelNotes/1.5.3.adoc diff --git a/Documentation/RelNotes/1.5.4.1.txt b/Documentation/RelNotes/1.5.4.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.1.txt rename to Documentation/RelNotes/1.5.4.1.adoc diff --git a/Documentation/RelNotes/1.5.4.2.txt b/Documentation/RelNotes/1.5.4.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.2.txt rename to Documentation/RelNotes/1.5.4.2.adoc diff --git a/Documentation/RelNotes/1.5.4.3.txt b/Documentation/RelNotes/1.5.4.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.3.txt rename to Documentation/RelNotes/1.5.4.3.adoc diff --git a/Documentation/RelNotes/1.5.4.4.txt b/Documentation/RelNotes/1.5.4.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.4.txt rename to Documentation/RelNotes/1.5.4.4.adoc diff --git a/Documentation/RelNotes/1.5.4.5.txt b/Documentation/RelNotes/1.5.4.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.5.txt rename to Documentation/RelNotes/1.5.4.5.adoc diff --git a/Documentation/RelNotes/1.5.4.6.txt b/Documentation/RelNotes/1.5.4.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.6.txt rename to Documentation/RelNotes/1.5.4.6.adoc diff --git a/Documentation/RelNotes/1.5.4.7.txt b/Documentation/RelNotes/1.5.4.7.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.7.txt rename to Documentation/RelNotes/1.5.4.7.adoc diff --git a/Documentation/RelNotes/1.5.4.txt b/Documentation/RelNotes/1.5.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.4.txt rename to Documentation/RelNotes/1.5.4.adoc diff --git a/Documentation/RelNotes/1.5.5.1.txt b/Documentation/RelNotes/1.5.5.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.1.txt rename to Documentation/RelNotes/1.5.5.1.adoc diff --git a/Documentation/RelNotes/1.5.5.2.txt b/Documentation/RelNotes/1.5.5.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.2.txt rename to Documentation/RelNotes/1.5.5.2.adoc diff --git a/Documentation/RelNotes/1.5.5.3.txt b/Documentation/RelNotes/1.5.5.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.3.txt rename to Documentation/RelNotes/1.5.5.3.adoc diff --git a/Documentation/RelNotes/1.5.5.4.txt b/Documentation/RelNotes/1.5.5.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.4.txt rename to Documentation/RelNotes/1.5.5.4.adoc diff --git a/Documentation/RelNotes/1.5.5.5.txt b/Documentation/RelNotes/1.5.5.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.5.txt rename to Documentation/RelNotes/1.5.5.5.adoc diff --git a/Documentation/RelNotes/1.5.5.6.txt b/Documentation/RelNotes/1.5.5.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.6.txt rename to Documentation/RelNotes/1.5.5.6.adoc diff --git a/Documentation/RelNotes/1.5.5.txt b/Documentation/RelNotes/1.5.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.5.txt rename to Documentation/RelNotes/1.5.5.adoc diff --git a/Documentation/RelNotes/1.5.6.1.txt b/Documentation/RelNotes/1.5.6.1.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.1.txt rename to Documentation/RelNotes/1.5.6.1.adoc diff --git a/Documentation/RelNotes/1.5.6.2.txt b/Documentation/RelNotes/1.5.6.2.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.2.txt rename to Documentation/RelNotes/1.5.6.2.adoc diff --git a/Documentation/RelNotes/1.5.6.3.txt b/Documentation/RelNotes/1.5.6.3.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.3.txt rename to Documentation/RelNotes/1.5.6.3.adoc diff --git a/Documentation/RelNotes/1.5.6.4.txt b/Documentation/RelNotes/1.5.6.4.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.4.txt rename to Documentation/RelNotes/1.5.6.4.adoc diff --git a/Documentation/RelNotes/1.5.6.5.txt b/Documentation/RelNotes/1.5.6.5.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.5.txt rename to Documentation/RelNotes/1.5.6.5.adoc diff --git a/Documentation/RelNotes/1.5.6.6.txt b/Documentation/RelNotes/1.5.6.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.6.txt rename to Documentation/RelNotes/1.5.6.6.adoc diff --git a/Documentation/RelNotes/1.5.6.txt b/Documentation/RelNotes/1.5.6.adoc similarity index 100% rename from Documentation/RelNotes/1.5.6.txt rename to Documentation/RelNotes/1.5.6.adoc diff --git a/Documentation/RelNotes/1.6.0.1.txt b/Documentation/RelNotes/1.6.0.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.1.txt rename to Documentation/RelNotes/1.6.0.1.adoc diff --git a/Documentation/RelNotes/1.6.0.2.txt b/Documentation/RelNotes/1.6.0.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.2.txt rename to Documentation/RelNotes/1.6.0.2.adoc diff --git a/Documentation/RelNotes/1.6.0.3.txt b/Documentation/RelNotes/1.6.0.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.3.txt rename to Documentation/RelNotes/1.6.0.3.adoc diff --git a/Documentation/RelNotes/1.6.0.4.txt b/Documentation/RelNotes/1.6.0.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.4.txt rename to Documentation/RelNotes/1.6.0.4.adoc diff --git a/Documentation/RelNotes/1.6.0.5.txt b/Documentation/RelNotes/1.6.0.5.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.5.txt rename to Documentation/RelNotes/1.6.0.5.adoc diff --git a/Documentation/RelNotes/1.6.0.6.txt b/Documentation/RelNotes/1.6.0.6.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.6.txt rename to Documentation/RelNotes/1.6.0.6.adoc diff --git a/Documentation/RelNotes/1.6.0.txt b/Documentation/RelNotes/1.6.0.adoc similarity index 100% rename from Documentation/RelNotes/1.6.0.txt rename to Documentation/RelNotes/1.6.0.adoc diff --git a/Documentation/RelNotes/1.6.1.1.txt b/Documentation/RelNotes/1.6.1.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.1.1.txt rename to Documentation/RelNotes/1.6.1.1.adoc diff --git a/Documentation/RelNotes/1.6.1.2.txt b/Documentation/RelNotes/1.6.1.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.1.2.txt rename to Documentation/RelNotes/1.6.1.2.adoc diff --git a/Documentation/RelNotes/1.6.1.3.txt b/Documentation/RelNotes/1.6.1.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.1.3.txt rename to Documentation/RelNotes/1.6.1.3.adoc diff --git a/Documentation/RelNotes/1.6.1.4.txt b/Documentation/RelNotes/1.6.1.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.1.4.txt rename to Documentation/RelNotes/1.6.1.4.adoc diff --git a/Documentation/RelNotes/1.6.1.txt b/Documentation/RelNotes/1.6.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.1.txt rename to Documentation/RelNotes/1.6.1.adoc diff --git a/Documentation/RelNotes/1.6.2.1.txt b/Documentation/RelNotes/1.6.2.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.2.1.txt rename to Documentation/RelNotes/1.6.2.1.adoc diff --git a/Documentation/RelNotes/1.6.2.2.txt b/Documentation/RelNotes/1.6.2.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.2.2.txt rename to Documentation/RelNotes/1.6.2.2.adoc diff --git a/Documentation/RelNotes/1.6.2.3.txt b/Documentation/RelNotes/1.6.2.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.2.3.txt rename to Documentation/RelNotes/1.6.2.3.adoc diff --git a/Documentation/RelNotes/1.6.2.4.txt b/Documentation/RelNotes/1.6.2.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.2.4.txt rename to Documentation/RelNotes/1.6.2.4.adoc diff --git a/Documentation/RelNotes/1.6.2.5.txt b/Documentation/RelNotes/1.6.2.5.adoc similarity index 100% rename from Documentation/RelNotes/1.6.2.5.txt rename to Documentation/RelNotes/1.6.2.5.adoc diff --git a/Documentation/RelNotes/1.6.2.txt b/Documentation/RelNotes/1.6.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.2.txt rename to Documentation/RelNotes/1.6.2.adoc diff --git a/Documentation/RelNotes/1.6.3.1.txt b/Documentation/RelNotes/1.6.3.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.3.1.txt rename to Documentation/RelNotes/1.6.3.1.adoc diff --git a/Documentation/RelNotes/1.6.3.2.txt b/Documentation/RelNotes/1.6.3.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.3.2.txt rename to Documentation/RelNotes/1.6.3.2.adoc diff --git a/Documentation/RelNotes/1.6.3.3.txt b/Documentation/RelNotes/1.6.3.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.3.3.txt rename to Documentation/RelNotes/1.6.3.3.adoc diff --git a/Documentation/RelNotes/1.6.3.4.txt b/Documentation/RelNotes/1.6.3.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.3.4.txt rename to Documentation/RelNotes/1.6.3.4.adoc diff --git a/Documentation/RelNotes/1.6.3.txt b/Documentation/RelNotes/1.6.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.3.txt rename to Documentation/RelNotes/1.6.3.adoc diff --git a/Documentation/RelNotes/1.6.4.1.txt b/Documentation/RelNotes/1.6.4.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.4.1.txt rename to Documentation/RelNotes/1.6.4.1.adoc diff --git a/Documentation/RelNotes/1.6.4.2.txt b/Documentation/RelNotes/1.6.4.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.4.2.txt rename to Documentation/RelNotes/1.6.4.2.adoc diff --git a/Documentation/RelNotes/1.6.4.3.txt b/Documentation/RelNotes/1.6.4.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.4.3.txt rename to Documentation/RelNotes/1.6.4.3.adoc diff --git a/Documentation/RelNotes/1.6.4.4.txt b/Documentation/RelNotes/1.6.4.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.4.4.txt rename to Documentation/RelNotes/1.6.4.4.adoc diff --git a/Documentation/RelNotes/1.6.4.5.txt b/Documentation/RelNotes/1.6.4.5.adoc similarity index 100% rename from Documentation/RelNotes/1.6.4.5.txt rename to Documentation/RelNotes/1.6.4.5.adoc diff --git a/Documentation/RelNotes/1.6.4.txt b/Documentation/RelNotes/1.6.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.4.txt rename to Documentation/RelNotes/1.6.4.adoc diff --git a/Documentation/RelNotes/1.6.5.1.txt b/Documentation/RelNotes/1.6.5.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.1.txt rename to Documentation/RelNotes/1.6.5.1.adoc diff --git a/Documentation/RelNotes/1.6.5.2.txt b/Documentation/RelNotes/1.6.5.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.2.txt rename to Documentation/RelNotes/1.6.5.2.adoc diff --git a/Documentation/RelNotes/1.6.5.3.txt b/Documentation/RelNotes/1.6.5.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.3.txt rename to Documentation/RelNotes/1.6.5.3.adoc diff --git a/Documentation/RelNotes/1.6.5.4.txt b/Documentation/RelNotes/1.6.5.4.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.4.txt rename to Documentation/RelNotes/1.6.5.4.adoc diff --git a/Documentation/RelNotes/1.6.5.5.txt b/Documentation/RelNotes/1.6.5.5.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.5.txt rename to Documentation/RelNotes/1.6.5.5.adoc diff --git a/Documentation/RelNotes/1.6.5.6.txt b/Documentation/RelNotes/1.6.5.6.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.6.txt rename to Documentation/RelNotes/1.6.5.6.adoc diff --git a/Documentation/RelNotes/1.6.5.7.txt b/Documentation/RelNotes/1.6.5.7.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.7.txt rename to Documentation/RelNotes/1.6.5.7.adoc diff --git a/Documentation/RelNotes/1.6.5.8.txt b/Documentation/RelNotes/1.6.5.8.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.8.txt rename to Documentation/RelNotes/1.6.5.8.adoc diff --git a/Documentation/RelNotes/1.6.5.9.txt b/Documentation/RelNotes/1.6.5.9.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.9.txt rename to Documentation/RelNotes/1.6.5.9.adoc diff --git a/Documentation/RelNotes/1.6.5.txt b/Documentation/RelNotes/1.6.5.adoc similarity index 100% rename from Documentation/RelNotes/1.6.5.txt rename to Documentation/RelNotes/1.6.5.adoc diff --git a/Documentation/RelNotes/1.6.6.1.txt b/Documentation/RelNotes/1.6.6.1.adoc similarity index 100% rename from Documentation/RelNotes/1.6.6.1.txt rename to Documentation/RelNotes/1.6.6.1.adoc diff --git a/Documentation/RelNotes/1.6.6.2.txt b/Documentation/RelNotes/1.6.6.2.adoc similarity index 100% rename from Documentation/RelNotes/1.6.6.2.txt rename to Documentation/RelNotes/1.6.6.2.adoc diff --git a/Documentation/RelNotes/1.6.6.3.txt b/Documentation/RelNotes/1.6.6.3.adoc similarity index 100% rename from Documentation/RelNotes/1.6.6.3.txt rename to Documentation/RelNotes/1.6.6.3.adoc diff --git a/Documentation/RelNotes/1.6.6.txt b/Documentation/RelNotes/1.6.6.adoc similarity index 100% rename from Documentation/RelNotes/1.6.6.txt rename to Documentation/RelNotes/1.6.6.adoc diff --git a/Documentation/RelNotes/1.7.0.1.txt b/Documentation/RelNotes/1.7.0.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.1.txt rename to Documentation/RelNotes/1.7.0.1.adoc diff --git a/Documentation/RelNotes/1.7.0.2.txt b/Documentation/RelNotes/1.7.0.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.2.txt rename to Documentation/RelNotes/1.7.0.2.adoc diff --git a/Documentation/RelNotes/1.7.0.3.txt b/Documentation/RelNotes/1.7.0.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.3.txt rename to Documentation/RelNotes/1.7.0.3.adoc diff --git a/Documentation/RelNotes/1.7.0.4.txt b/Documentation/RelNotes/1.7.0.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.4.txt rename to Documentation/RelNotes/1.7.0.4.adoc diff --git a/Documentation/RelNotes/1.7.0.5.txt b/Documentation/RelNotes/1.7.0.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.5.txt rename to Documentation/RelNotes/1.7.0.5.adoc diff --git a/Documentation/RelNotes/1.7.0.6.txt b/Documentation/RelNotes/1.7.0.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.6.txt rename to Documentation/RelNotes/1.7.0.6.adoc diff --git a/Documentation/RelNotes/1.7.0.7.txt b/Documentation/RelNotes/1.7.0.7.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.7.txt rename to Documentation/RelNotes/1.7.0.7.adoc diff --git a/Documentation/RelNotes/1.7.0.8.txt b/Documentation/RelNotes/1.7.0.8.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.8.txt rename to Documentation/RelNotes/1.7.0.8.adoc diff --git a/Documentation/RelNotes/1.7.0.9.txt b/Documentation/RelNotes/1.7.0.9.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.9.txt rename to Documentation/RelNotes/1.7.0.9.adoc diff --git a/Documentation/RelNotes/1.7.0.txt b/Documentation/RelNotes/1.7.0.adoc similarity index 100% rename from Documentation/RelNotes/1.7.0.txt rename to Documentation/RelNotes/1.7.0.adoc diff --git a/Documentation/RelNotes/1.7.1.1.txt b/Documentation/RelNotes/1.7.1.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.1.1.txt rename to Documentation/RelNotes/1.7.1.1.adoc diff --git a/Documentation/RelNotes/1.7.1.2.txt b/Documentation/RelNotes/1.7.1.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.1.2.txt rename to Documentation/RelNotes/1.7.1.2.adoc diff --git a/Documentation/RelNotes/1.7.1.3.txt b/Documentation/RelNotes/1.7.1.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.1.3.txt rename to Documentation/RelNotes/1.7.1.3.adoc diff --git a/Documentation/RelNotes/1.7.1.4.txt b/Documentation/RelNotes/1.7.1.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.1.4.txt rename to Documentation/RelNotes/1.7.1.4.adoc diff --git a/Documentation/RelNotes/1.7.1.txt b/Documentation/RelNotes/1.7.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.1.txt rename to Documentation/RelNotes/1.7.1.adoc diff --git a/Documentation/RelNotes/1.7.10.1.txt b/Documentation/RelNotes/1.7.10.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.10.1.txt rename to Documentation/RelNotes/1.7.10.1.adoc diff --git a/Documentation/RelNotes/1.7.10.2.txt b/Documentation/RelNotes/1.7.10.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.10.2.txt rename to Documentation/RelNotes/1.7.10.2.adoc diff --git a/Documentation/RelNotes/1.7.10.3.txt b/Documentation/RelNotes/1.7.10.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.10.3.txt rename to Documentation/RelNotes/1.7.10.3.adoc diff --git a/Documentation/RelNotes/1.7.10.4.txt b/Documentation/RelNotes/1.7.10.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.10.4.txt rename to Documentation/RelNotes/1.7.10.4.adoc diff --git a/Documentation/RelNotes/1.7.10.5.txt b/Documentation/RelNotes/1.7.10.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.10.5.txt rename to Documentation/RelNotes/1.7.10.5.adoc diff --git a/Documentation/RelNotes/1.7.10.txt b/Documentation/RelNotes/1.7.10.adoc similarity index 100% rename from Documentation/RelNotes/1.7.10.txt rename to Documentation/RelNotes/1.7.10.adoc diff --git a/Documentation/RelNotes/1.7.11.1.txt b/Documentation/RelNotes/1.7.11.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.1.txt rename to Documentation/RelNotes/1.7.11.1.adoc diff --git a/Documentation/RelNotes/1.7.11.2.txt b/Documentation/RelNotes/1.7.11.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.2.txt rename to Documentation/RelNotes/1.7.11.2.adoc diff --git a/Documentation/RelNotes/1.7.11.3.txt b/Documentation/RelNotes/1.7.11.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.3.txt rename to Documentation/RelNotes/1.7.11.3.adoc diff --git a/Documentation/RelNotes/1.7.11.4.txt b/Documentation/RelNotes/1.7.11.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.4.txt rename to Documentation/RelNotes/1.7.11.4.adoc diff --git a/Documentation/RelNotes/1.7.11.5.txt b/Documentation/RelNotes/1.7.11.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.5.txt rename to Documentation/RelNotes/1.7.11.5.adoc diff --git a/Documentation/RelNotes/1.7.11.6.txt b/Documentation/RelNotes/1.7.11.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.6.txt rename to Documentation/RelNotes/1.7.11.6.adoc diff --git a/Documentation/RelNotes/1.7.11.7.txt b/Documentation/RelNotes/1.7.11.7.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.7.txt rename to Documentation/RelNotes/1.7.11.7.adoc diff --git a/Documentation/RelNotes/1.7.11.txt b/Documentation/RelNotes/1.7.11.adoc similarity index 100% rename from Documentation/RelNotes/1.7.11.txt rename to Documentation/RelNotes/1.7.11.adoc diff --git a/Documentation/RelNotes/1.7.12.1.txt b/Documentation/RelNotes/1.7.12.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.12.1.txt rename to Documentation/RelNotes/1.7.12.1.adoc diff --git a/Documentation/RelNotes/1.7.12.2.txt b/Documentation/RelNotes/1.7.12.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.12.2.txt rename to Documentation/RelNotes/1.7.12.2.adoc diff --git a/Documentation/RelNotes/1.7.12.3.txt b/Documentation/RelNotes/1.7.12.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.12.3.txt rename to Documentation/RelNotes/1.7.12.3.adoc diff --git a/Documentation/RelNotes/1.7.12.4.txt b/Documentation/RelNotes/1.7.12.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.12.4.txt rename to Documentation/RelNotes/1.7.12.4.adoc diff --git a/Documentation/RelNotes/1.7.12.txt b/Documentation/RelNotes/1.7.12.adoc similarity index 100% rename from Documentation/RelNotes/1.7.12.txt rename to Documentation/RelNotes/1.7.12.adoc diff --git a/Documentation/RelNotes/1.7.2.1.txt b/Documentation/RelNotes/1.7.2.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.2.1.txt rename to Documentation/RelNotes/1.7.2.1.adoc diff --git a/Documentation/RelNotes/1.7.2.2.txt b/Documentation/RelNotes/1.7.2.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.2.2.txt rename to Documentation/RelNotes/1.7.2.2.adoc diff --git a/Documentation/RelNotes/1.7.2.3.txt b/Documentation/RelNotes/1.7.2.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.2.3.txt rename to Documentation/RelNotes/1.7.2.3.adoc diff --git a/Documentation/RelNotes/1.7.2.4.txt b/Documentation/RelNotes/1.7.2.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.2.4.txt rename to Documentation/RelNotes/1.7.2.4.adoc diff --git a/Documentation/RelNotes/1.7.2.5.txt b/Documentation/RelNotes/1.7.2.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.2.5.txt rename to Documentation/RelNotes/1.7.2.5.adoc diff --git a/Documentation/RelNotes/1.7.2.txt b/Documentation/RelNotes/1.7.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.2.txt rename to Documentation/RelNotes/1.7.2.adoc diff --git a/Documentation/RelNotes/1.7.3.1.txt b/Documentation/RelNotes/1.7.3.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.3.1.txt rename to Documentation/RelNotes/1.7.3.1.adoc diff --git a/Documentation/RelNotes/1.7.3.2.txt b/Documentation/RelNotes/1.7.3.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.3.2.txt rename to Documentation/RelNotes/1.7.3.2.adoc diff --git a/Documentation/RelNotes/1.7.3.3.txt b/Documentation/RelNotes/1.7.3.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.3.3.txt rename to Documentation/RelNotes/1.7.3.3.adoc diff --git a/Documentation/RelNotes/1.7.3.4.txt b/Documentation/RelNotes/1.7.3.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.3.4.txt rename to Documentation/RelNotes/1.7.3.4.adoc diff --git a/Documentation/RelNotes/1.7.3.5.txt b/Documentation/RelNotes/1.7.3.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.3.5.txt rename to Documentation/RelNotes/1.7.3.5.adoc diff --git a/Documentation/RelNotes/1.7.3.txt b/Documentation/RelNotes/1.7.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.3.txt rename to Documentation/RelNotes/1.7.3.adoc diff --git a/Documentation/RelNotes/1.7.4.1.txt b/Documentation/RelNotes/1.7.4.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.4.1.txt rename to Documentation/RelNotes/1.7.4.1.adoc diff --git a/Documentation/RelNotes/1.7.4.2.txt b/Documentation/RelNotes/1.7.4.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.4.2.txt rename to Documentation/RelNotes/1.7.4.2.adoc diff --git a/Documentation/RelNotes/1.7.4.3.txt b/Documentation/RelNotes/1.7.4.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.4.3.txt rename to Documentation/RelNotes/1.7.4.3.adoc diff --git a/Documentation/RelNotes/1.7.4.4.txt b/Documentation/RelNotes/1.7.4.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.4.4.txt rename to Documentation/RelNotes/1.7.4.4.adoc diff --git a/Documentation/RelNotes/1.7.4.5.txt b/Documentation/RelNotes/1.7.4.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.4.5.txt rename to Documentation/RelNotes/1.7.4.5.adoc diff --git a/Documentation/RelNotes/1.7.4.txt b/Documentation/RelNotes/1.7.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.4.txt rename to Documentation/RelNotes/1.7.4.adoc diff --git a/Documentation/RelNotes/1.7.5.1.txt b/Documentation/RelNotes/1.7.5.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.5.1.txt rename to Documentation/RelNotes/1.7.5.1.adoc diff --git a/Documentation/RelNotes/1.7.5.2.txt b/Documentation/RelNotes/1.7.5.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.5.2.txt rename to Documentation/RelNotes/1.7.5.2.adoc diff --git a/Documentation/RelNotes/1.7.5.3.txt b/Documentation/RelNotes/1.7.5.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.5.3.txt rename to Documentation/RelNotes/1.7.5.3.adoc diff --git a/Documentation/RelNotes/1.7.5.4.txt b/Documentation/RelNotes/1.7.5.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.5.4.txt rename to Documentation/RelNotes/1.7.5.4.adoc diff --git a/Documentation/RelNotes/1.7.5.txt b/Documentation/RelNotes/1.7.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.5.txt rename to Documentation/RelNotes/1.7.5.adoc diff --git a/Documentation/RelNotes/1.7.6.1.txt b/Documentation/RelNotes/1.7.6.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.1.txt rename to Documentation/RelNotes/1.7.6.1.adoc diff --git a/Documentation/RelNotes/1.7.6.2.txt b/Documentation/RelNotes/1.7.6.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.2.txt rename to Documentation/RelNotes/1.7.6.2.adoc diff --git a/Documentation/RelNotes/1.7.6.3.txt b/Documentation/RelNotes/1.7.6.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.3.txt rename to Documentation/RelNotes/1.7.6.3.adoc diff --git a/Documentation/RelNotes/1.7.6.4.txt b/Documentation/RelNotes/1.7.6.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.4.txt rename to Documentation/RelNotes/1.7.6.4.adoc diff --git a/Documentation/RelNotes/1.7.6.5.txt b/Documentation/RelNotes/1.7.6.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.5.txt rename to Documentation/RelNotes/1.7.6.5.adoc diff --git a/Documentation/RelNotes/1.7.6.6.txt b/Documentation/RelNotes/1.7.6.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.6.txt rename to Documentation/RelNotes/1.7.6.6.adoc diff --git a/Documentation/RelNotes/1.7.6.txt b/Documentation/RelNotes/1.7.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.6.txt rename to Documentation/RelNotes/1.7.6.adoc diff --git a/Documentation/RelNotes/1.7.7.1.txt b/Documentation/RelNotes/1.7.7.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.1.txt rename to Documentation/RelNotes/1.7.7.1.adoc diff --git a/Documentation/RelNotes/1.7.7.2.txt b/Documentation/RelNotes/1.7.7.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.2.txt rename to Documentation/RelNotes/1.7.7.2.adoc diff --git a/Documentation/RelNotes/1.7.7.3.txt b/Documentation/RelNotes/1.7.7.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.3.txt rename to Documentation/RelNotes/1.7.7.3.adoc diff --git a/Documentation/RelNotes/1.7.7.4.txt b/Documentation/RelNotes/1.7.7.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.4.txt rename to Documentation/RelNotes/1.7.7.4.adoc diff --git a/Documentation/RelNotes/1.7.7.5.txt b/Documentation/RelNotes/1.7.7.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.5.txt rename to Documentation/RelNotes/1.7.7.5.adoc diff --git a/Documentation/RelNotes/1.7.7.6.txt b/Documentation/RelNotes/1.7.7.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.6.txt rename to Documentation/RelNotes/1.7.7.6.adoc diff --git a/Documentation/RelNotes/1.7.7.7.txt b/Documentation/RelNotes/1.7.7.7.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.7.txt rename to Documentation/RelNotes/1.7.7.7.adoc diff --git a/Documentation/RelNotes/1.7.7.txt b/Documentation/RelNotes/1.7.7.adoc similarity index 100% rename from Documentation/RelNotes/1.7.7.txt rename to Documentation/RelNotes/1.7.7.adoc diff --git a/Documentation/RelNotes/1.7.8.1.txt b/Documentation/RelNotes/1.7.8.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.1.txt rename to Documentation/RelNotes/1.7.8.1.adoc diff --git a/Documentation/RelNotes/1.7.8.2.txt b/Documentation/RelNotes/1.7.8.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.2.txt rename to Documentation/RelNotes/1.7.8.2.adoc diff --git a/Documentation/RelNotes/1.7.8.3.txt b/Documentation/RelNotes/1.7.8.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.3.txt rename to Documentation/RelNotes/1.7.8.3.adoc diff --git a/Documentation/RelNotes/1.7.8.4.txt b/Documentation/RelNotes/1.7.8.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.4.txt rename to Documentation/RelNotes/1.7.8.4.adoc diff --git a/Documentation/RelNotes/1.7.8.5.txt b/Documentation/RelNotes/1.7.8.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.5.txt rename to Documentation/RelNotes/1.7.8.5.adoc diff --git a/Documentation/RelNotes/1.7.8.6.txt b/Documentation/RelNotes/1.7.8.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.6.txt rename to Documentation/RelNotes/1.7.8.6.adoc diff --git a/Documentation/RelNotes/1.7.8.txt b/Documentation/RelNotes/1.7.8.adoc similarity index 100% rename from Documentation/RelNotes/1.7.8.txt rename to Documentation/RelNotes/1.7.8.adoc diff --git a/Documentation/RelNotes/1.7.9.1.txt b/Documentation/RelNotes/1.7.9.1.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.1.txt rename to Documentation/RelNotes/1.7.9.1.adoc diff --git a/Documentation/RelNotes/1.7.9.2.txt b/Documentation/RelNotes/1.7.9.2.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.2.txt rename to Documentation/RelNotes/1.7.9.2.adoc diff --git a/Documentation/RelNotes/1.7.9.3.txt b/Documentation/RelNotes/1.7.9.3.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.3.txt rename to Documentation/RelNotes/1.7.9.3.adoc diff --git a/Documentation/RelNotes/1.7.9.4.txt b/Documentation/RelNotes/1.7.9.4.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.4.txt rename to Documentation/RelNotes/1.7.9.4.adoc diff --git a/Documentation/RelNotes/1.7.9.5.txt b/Documentation/RelNotes/1.7.9.5.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.5.txt rename to Documentation/RelNotes/1.7.9.5.adoc diff --git a/Documentation/RelNotes/1.7.9.6.txt b/Documentation/RelNotes/1.7.9.6.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.6.txt rename to Documentation/RelNotes/1.7.9.6.adoc diff --git a/Documentation/RelNotes/1.7.9.7.txt b/Documentation/RelNotes/1.7.9.7.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.7.txt rename to Documentation/RelNotes/1.7.9.7.adoc diff --git a/Documentation/RelNotes/1.7.9.txt b/Documentation/RelNotes/1.7.9.adoc similarity index 100% rename from Documentation/RelNotes/1.7.9.txt rename to Documentation/RelNotes/1.7.9.adoc diff --git a/Documentation/RelNotes/1.8.0.1.txt b/Documentation/RelNotes/1.8.0.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.0.1.txt rename to Documentation/RelNotes/1.8.0.1.adoc diff --git a/Documentation/RelNotes/1.8.0.2.txt b/Documentation/RelNotes/1.8.0.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.0.2.txt rename to Documentation/RelNotes/1.8.0.2.adoc diff --git a/Documentation/RelNotes/1.8.0.3.txt b/Documentation/RelNotes/1.8.0.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.0.3.txt rename to Documentation/RelNotes/1.8.0.3.adoc diff --git a/Documentation/RelNotes/1.8.0.txt b/Documentation/RelNotes/1.8.0.adoc similarity index 100% rename from Documentation/RelNotes/1.8.0.txt rename to Documentation/RelNotes/1.8.0.adoc diff --git a/Documentation/RelNotes/1.8.1.1.txt b/Documentation/RelNotes/1.8.1.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.1.txt rename to Documentation/RelNotes/1.8.1.1.adoc diff --git a/Documentation/RelNotes/1.8.1.2.txt b/Documentation/RelNotes/1.8.1.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.2.txt rename to Documentation/RelNotes/1.8.1.2.adoc diff --git a/Documentation/RelNotes/1.8.1.3.txt b/Documentation/RelNotes/1.8.1.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.3.txt rename to Documentation/RelNotes/1.8.1.3.adoc diff --git a/Documentation/RelNotes/1.8.1.4.txt b/Documentation/RelNotes/1.8.1.4.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.4.txt rename to Documentation/RelNotes/1.8.1.4.adoc diff --git a/Documentation/RelNotes/1.8.1.5.txt b/Documentation/RelNotes/1.8.1.5.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.5.txt rename to Documentation/RelNotes/1.8.1.5.adoc diff --git a/Documentation/RelNotes/1.8.1.6.txt b/Documentation/RelNotes/1.8.1.6.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.6.txt rename to Documentation/RelNotes/1.8.1.6.adoc diff --git a/Documentation/RelNotes/1.8.1.txt b/Documentation/RelNotes/1.8.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.1.txt rename to Documentation/RelNotes/1.8.1.adoc diff --git a/Documentation/RelNotes/1.8.2.1.txt b/Documentation/RelNotes/1.8.2.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.2.1.txt rename to Documentation/RelNotes/1.8.2.1.adoc diff --git a/Documentation/RelNotes/1.8.2.2.txt b/Documentation/RelNotes/1.8.2.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.2.2.txt rename to Documentation/RelNotes/1.8.2.2.adoc diff --git a/Documentation/RelNotes/1.8.2.3.txt b/Documentation/RelNotes/1.8.2.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.2.3.txt rename to Documentation/RelNotes/1.8.2.3.adoc diff --git a/Documentation/RelNotes/1.8.2.txt b/Documentation/RelNotes/1.8.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.2.txt rename to Documentation/RelNotes/1.8.2.adoc diff --git a/Documentation/RelNotes/1.8.3.1.txt b/Documentation/RelNotes/1.8.3.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.3.1.txt rename to Documentation/RelNotes/1.8.3.1.adoc diff --git a/Documentation/RelNotes/1.8.3.2.txt b/Documentation/RelNotes/1.8.3.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.3.2.txt rename to Documentation/RelNotes/1.8.3.2.adoc diff --git a/Documentation/RelNotes/1.8.3.3.txt b/Documentation/RelNotes/1.8.3.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.3.3.txt rename to Documentation/RelNotes/1.8.3.3.adoc diff --git a/Documentation/RelNotes/1.8.3.4.txt b/Documentation/RelNotes/1.8.3.4.adoc similarity index 100% rename from Documentation/RelNotes/1.8.3.4.txt rename to Documentation/RelNotes/1.8.3.4.adoc diff --git a/Documentation/RelNotes/1.8.3.txt b/Documentation/RelNotes/1.8.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.3.txt rename to Documentation/RelNotes/1.8.3.adoc diff --git a/Documentation/RelNotes/1.8.4.1.txt b/Documentation/RelNotes/1.8.4.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.4.1.txt rename to Documentation/RelNotes/1.8.4.1.adoc diff --git a/Documentation/RelNotes/1.8.4.2.txt b/Documentation/RelNotes/1.8.4.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.4.2.txt rename to Documentation/RelNotes/1.8.4.2.adoc diff --git a/Documentation/RelNotes/1.8.4.3.txt b/Documentation/RelNotes/1.8.4.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.4.3.txt rename to Documentation/RelNotes/1.8.4.3.adoc diff --git a/Documentation/RelNotes/1.8.4.4.txt b/Documentation/RelNotes/1.8.4.4.adoc similarity index 100% rename from Documentation/RelNotes/1.8.4.4.txt rename to Documentation/RelNotes/1.8.4.4.adoc diff --git a/Documentation/RelNotes/1.8.4.5.txt b/Documentation/RelNotes/1.8.4.5.adoc similarity index 100% rename from Documentation/RelNotes/1.8.4.5.txt rename to Documentation/RelNotes/1.8.4.5.adoc diff --git a/Documentation/RelNotes/1.8.4.txt b/Documentation/RelNotes/1.8.4.adoc similarity index 100% rename from Documentation/RelNotes/1.8.4.txt rename to Documentation/RelNotes/1.8.4.adoc diff --git a/Documentation/RelNotes/1.8.5.1.txt b/Documentation/RelNotes/1.8.5.1.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.1.txt rename to Documentation/RelNotes/1.8.5.1.adoc diff --git a/Documentation/RelNotes/1.8.5.2.txt b/Documentation/RelNotes/1.8.5.2.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.2.txt rename to Documentation/RelNotes/1.8.5.2.adoc diff --git a/Documentation/RelNotes/1.8.5.3.txt b/Documentation/RelNotes/1.8.5.3.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.3.txt rename to Documentation/RelNotes/1.8.5.3.adoc diff --git a/Documentation/RelNotes/1.8.5.4.txt b/Documentation/RelNotes/1.8.5.4.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.4.txt rename to Documentation/RelNotes/1.8.5.4.adoc diff --git a/Documentation/RelNotes/1.8.5.5.txt b/Documentation/RelNotes/1.8.5.5.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.5.txt rename to Documentation/RelNotes/1.8.5.5.adoc diff --git a/Documentation/RelNotes/1.8.5.6.txt b/Documentation/RelNotes/1.8.5.6.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.6.txt rename to Documentation/RelNotes/1.8.5.6.adoc diff --git a/Documentation/RelNotes/1.8.5.txt b/Documentation/RelNotes/1.8.5.adoc similarity index 100% rename from Documentation/RelNotes/1.8.5.txt rename to Documentation/RelNotes/1.8.5.adoc diff --git a/Documentation/RelNotes/1.9.0.txt b/Documentation/RelNotes/1.9.0.adoc similarity index 100% rename from Documentation/RelNotes/1.9.0.txt rename to Documentation/RelNotes/1.9.0.adoc diff --git a/Documentation/RelNotes/1.9.1.txt b/Documentation/RelNotes/1.9.1.adoc similarity index 100% rename from Documentation/RelNotes/1.9.1.txt rename to Documentation/RelNotes/1.9.1.adoc diff --git a/Documentation/RelNotes/1.9.2.txt b/Documentation/RelNotes/1.9.2.adoc similarity index 100% rename from Documentation/RelNotes/1.9.2.txt rename to Documentation/RelNotes/1.9.2.adoc diff --git a/Documentation/RelNotes/1.9.3.txt b/Documentation/RelNotes/1.9.3.adoc similarity index 100% rename from Documentation/RelNotes/1.9.3.txt rename to Documentation/RelNotes/1.9.3.adoc diff --git a/Documentation/RelNotes/1.9.4.txt b/Documentation/RelNotes/1.9.4.adoc similarity index 100% rename from Documentation/RelNotes/1.9.4.txt rename to Documentation/RelNotes/1.9.4.adoc diff --git a/Documentation/RelNotes/1.9.5.txt b/Documentation/RelNotes/1.9.5.adoc similarity index 100% rename from Documentation/RelNotes/1.9.5.txt rename to Documentation/RelNotes/1.9.5.adoc diff --git a/Documentation/RelNotes/2.0.0.txt b/Documentation/RelNotes/2.0.0.adoc similarity index 100% rename from Documentation/RelNotes/2.0.0.txt rename to Documentation/RelNotes/2.0.0.adoc diff --git a/Documentation/RelNotes/2.0.1.txt b/Documentation/RelNotes/2.0.1.adoc similarity index 100% rename from Documentation/RelNotes/2.0.1.txt rename to Documentation/RelNotes/2.0.1.adoc diff --git a/Documentation/RelNotes/2.0.2.txt b/Documentation/RelNotes/2.0.2.adoc similarity index 100% rename from Documentation/RelNotes/2.0.2.txt rename to Documentation/RelNotes/2.0.2.adoc diff --git a/Documentation/RelNotes/2.0.3.txt b/Documentation/RelNotes/2.0.3.adoc similarity index 100% rename from Documentation/RelNotes/2.0.3.txt rename to Documentation/RelNotes/2.0.3.adoc diff --git a/Documentation/RelNotes/2.0.4.txt b/Documentation/RelNotes/2.0.4.adoc similarity index 100% rename from Documentation/RelNotes/2.0.4.txt rename to Documentation/RelNotes/2.0.4.adoc diff --git a/Documentation/RelNotes/2.0.5.txt b/Documentation/RelNotes/2.0.5.adoc similarity index 100% rename from Documentation/RelNotes/2.0.5.txt rename to Documentation/RelNotes/2.0.5.adoc diff --git a/Documentation/RelNotes/2.1.0.txt b/Documentation/RelNotes/2.1.0.adoc similarity index 100% rename from Documentation/RelNotes/2.1.0.txt rename to Documentation/RelNotes/2.1.0.adoc diff --git a/Documentation/RelNotes/2.1.1.txt b/Documentation/RelNotes/2.1.1.adoc similarity index 100% rename from Documentation/RelNotes/2.1.1.txt rename to Documentation/RelNotes/2.1.1.adoc diff --git a/Documentation/RelNotes/2.1.2.txt b/Documentation/RelNotes/2.1.2.adoc similarity index 100% rename from Documentation/RelNotes/2.1.2.txt rename to Documentation/RelNotes/2.1.2.adoc diff --git a/Documentation/RelNotes/2.1.3.txt b/Documentation/RelNotes/2.1.3.adoc similarity index 100% rename from Documentation/RelNotes/2.1.3.txt rename to Documentation/RelNotes/2.1.3.adoc diff --git a/Documentation/RelNotes/2.1.4.txt b/Documentation/RelNotes/2.1.4.adoc similarity index 100% rename from Documentation/RelNotes/2.1.4.txt rename to Documentation/RelNotes/2.1.4.adoc diff --git a/Documentation/RelNotes/2.10.0.txt b/Documentation/RelNotes/2.10.0.adoc similarity index 100% rename from Documentation/RelNotes/2.10.0.txt rename to Documentation/RelNotes/2.10.0.adoc diff --git a/Documentation/RelNotes/2.10.1.txt b/Documentation/RelNotes/2.10.1.adoc similarity index 100% rename from Documentation/RelNotes/2.10.1.txt rename to Documentation/RelNotes/2.10.1.adoc diff --git a/Documentation/RelNotes/2.10.2.txt b/Documentation/RelNotes/2.10.2.adoc similarity index 100% rename from Documentation/RelNotes/2.10.2.txt rename to Documentation/RelNotes/2.10.2.adoc diff --git a/Documentation/RelNotes/2.10.3.txt b/Documentation/RelNotes/2.10.3.adoc similarity index 100% rename from Documentation/RelNotes/2.10.3.txt rename to Documentation/RelNotes/2.10.3.adoc diff --git a/Documentation/RelNotes/2.10.4.txt b/Documentation/RelNotes/2.10.4.adoc similarity index 100% rename from Documentation/RelNotes/2.10.4.txt rename to Documentation/RelNotes/2.10.4.adoc diff --git a/Documentation/RelNotes/2.10.5.txt b/Documentation/RelNotes/2.10.5.adoc similarity index 100% rename from Documentation/RelNotes/2.10.5.txt rename to Documentation/RelNotes/2.10.5.adoc diff --git a/Documentation/RelNotes/2.11.0.txt b/Documentation/RelNotes/2.11.0.adoc similarity index 100% rename from Documentation/RelNotes/2.11.0.txt rename to Documentation/RelNotes/2.11.0.adoc diff --git a/Documentation/RelNotes/2.11.1.txt b/Documentation/RelNotes/2.11.1.adoc similarity index 100% rename from Documentation/RelNotes/2.11.1.txt rename to Documentation/RelNotes/2.11.1.adoc diff --git a/Documentation/RelNotes/2.11.2.txt b/Documentation/RelNotes/2.11.2.adoc similarity index 100% rename from Documentation/RelNotes/2.11.2.txt rename to Documentation/RelNotes/2.11.2.adoc diff --git a/Documentation/RelNotes/2.11.3.txt b/Documentation/RelNotes/2.11.3.adoc similarity index 100% rename from Documentation/RelNotes/2.11.3.txt rename to Documentation/RelNotes/2.11.3.adoc diff --git a/Documentation/RelNotes/2.11.4.txt b/Documentation/RelNotes/2.11.4.adoc similarity index 100% rename from Documentation/RelNotes/2.11.4.txt rename to Documentation/RelNotes/2.11.4.adoc diff --git a/Documentation/RelNotes/2.12.0.txt b/Documentation/RelNotes/2.12.0.adoc similarity index 100% rename from Documentation/RelNotes/2.12.0.txt rename to Documentation/RelNotes/2.12.0.adoc diff --git a/Documentation/RelNotes/2.12.1.txt b/Documentation/RelNotes/2.12.1.adoc similarity index 100% rename from Documentation/RelNotes/2.12.1.txt rename to Documentation/RelNotes/2.12.1.adoc diff --git a/Documentation/RelNotes/2.12.2.txt b/Documentation/RelNotes/2.12.2.adoc similarity index 100% rename from Documentation/RelNotes/2.12.2.txt rename to Documentation/RelNotes/2.12.2.adoc diff --git a/Documentation/RelNotes/2.12.3.txt b/Documentation/RelNotes/2.12.3.adoc similarity index 100% rename from Documentation/RelNotes/2.12.3.txt rename to Documentation/RelNotes/2.12.3.adoc diff --git a/Documentation/RelNotes/2.12.4.txt b/Documentation/RelNotes/2.12.4.adoc similarity index 100% rename from Documentation/RelNotes/2.12.4.txt rename to Documentation/RelNotes/2.12.4.adoc diff --git a/Documentation/RelNotes/2.12.5.txt b/Documentation/RelNotes/2.12.5.adoc similarity index 100% rename from Documentation/RelNotes/2.12.5.txt rename to Documentation/RelNotes/2.12.5.adoc diff --git a/Documentation/RelNotes/2.13.0.txt b/Documentation/RelNotes/2.13.0.adoc similarity index 100% rename from Documentation/RelNotes/2.13.0.txt rename to Documentation/RelNotes/2.13.0.adoc diff --git a/Documentation/RelNotes/2.13.1.txt b/Documentation/RelNotes/2.13.1.adoc similarity index 100% rename from Documentation/RelNotes/2.13.1.txt rename to Documentation/RelNotes/2.13.1.adoc diff --git a/Documentation/RelNotes/2.13.2.txt b/Documentation/RelNotes/2.13.2.adoc similarity index 100% rename from Documentation/RelNotes/2.13.2.txt rename to Documentation/RelNotes/2.13.2.adoc diff --git a/Documentation/RelNotes/2.13.3.txt b/Documentation/RelNotes/2.13.3.adoc similarity index 100% rename from Documentation/RelNotes/2.13.3.txt rename to Documentation/RelNotes/2.13.3.adoc diff --git a/Documentation/RelNotes/2.13.4.txt b/Documentation/RelNotes/2.13.4.adoc similarity index 100% rename from Documentation/RelNotes/2.13.4.txt rename to Documentation/RelNotes/2.13.4.adoc diff --git a/Documentation/RelNotes/2.13.5.txt b/Documentation/RelNotes/2.13.5.adoc similarity index 100% rename from Documentation/RelNotes/2.13.5.txt rename to Documentation/RelNotes/2.13.5.adoc diff --git a/Documentation/RelNotes/2.13.6.txt b/Documentation/RelNotes/2.13.6.adoc similarity index 100% rename from Documentation/RelNotes/2.13.6.txt rename to Documentation/RelNotes/2.13.6.adoc diff --git a/Documentation/RelNotes/2.13.7.txt b/Documentation/RelNotes/2.13.7.adoc similarity index 100% rename from Documentation/RelNotes/2.13.7.txt rename to Documentation/RelNotes/2.13.7.adoc diff --git a/Documentation/RelNotes/2.14.0.txt b/Documentation/RelNotes/2.14.0.adoc similarity index 100% rename from Documentation/RelNotes/2.14.0.txt rename to Documentation/RelNotes/2.14.0.adoc diff --git a/Documentation/RelNotes/2.14.1.txt b/Documentation/RelNotes/2.14.1.adoc similarity index 100% rename from Documentation/RelNotes/2.14.1.txt rename to Documentation/RelNotes/2.14.1.adoc diff --git a/Documentation/RelNotes/2.14.2.txt b/Documentation/RelNotes/2.14.2.adoc similarity index 100% rename from Documentation/RelNotes/2.14.2.txt rename to Documentation/RelNotes/2.14.2.adoc diff --git a/Documentation/RelNotes/2.14.3.txt b/Documentation/RelNotes/2.14.3.adoc similarity index 100% rename from Documentation/RelNotes/2.14.3.txt rename to Documentation/RelNotes/2.14.3.adoc diff --git a/Documentation/RelNotes/2.14.4.txt b/Documentation/RelNotes/2.14.4.adoc similarity index 100% rename from Documentation/RelNotes/2.14.4.txt rename to Documentation/RelNotes/2.14.4.adoc diff --git a/Documentation/RelNotes/2.14.5.txt b/Documentation/RelNotes/2.14.5.adoc similarity index 100% rename from Documentation/RelNotes/2.14.5.txt rename to Documentation/RelNotes/2.14.5.adoc diff --git a/Documentation/RelNotes/2.14.6.txt b/Documentation/RelNotes/2.14.6.adoc similarity index 100% rename from Documentation/RelNotes/2.14.6.txt rename to Documentation/RelNotes/2.14.6.adoc diff --git a/Documentation/RelNotes/2.15.0.txt b/Documentation/RelNotes/2.15.0.adoc similarity index 100% rename from Documentation/RelNotes/2.15.0.txt rename to Documentation/RelNotes/2.15.0.adoc diff --git a/Documentation/RelNotes/2.15.1.txt b/Documentation/RelNotes/2.15.1.adoc similarity index 100% rename from Documentation/RelNotes/2.15.1.txt rename to Documentation/RelNotes/2.15.1.adoc diff --git a/Documentation/RelNotes/2.15.2.txt b/Documentation/RelNotes/2.15.2.adoc similarity index 100% rename from Documentation/RelNotes/2.15.2.txt rename to Documentation/RelNotes/2.15.2.adoc diff --git a/Documentation/RelNotes/2.15.3.txt b/Documentation/RelNotes/2.15.3.adoc similarity index 100% rename from Documentation/RelNotes/2.15.3.txt rename to Documentation/RelNotes/2.15.3.adoc diff --git a/Documentation/RelNotes/2.15.4.txt b/Documentation/RelNotes/2.15.4.adoc similarity index 100% rename from Documentation/RelNotes/2.15.4.txt rename to Documentation/RelNotes/2.15.4.adoc diff --git a/Documentation/RelNotes/2.16.0.txt b/Documentation/RelNotes/2.16.0.adoc similarity index 100% rename from Documentation/RelNotes/2.16.0.txt rename to Documentation/RelNotes/2.16.0.adoc diff --git a/Documentation/RelNotes/2.16.1.txt b/Documentation/RelNotes/2.16.1.adoc similarity index 100% rename from Documentation/RelNotes/2.16.1.txt rename to Documentation/RelNotes/2.16.1.adoc diff --git a/Documentation/RelNotes/2.16.2.txt b/Documentation/RelNotes/2.16.2.adoc similarity index 100% rename from Documentation/RelNotes/2.16.2.txt rename to Documentation/RelNotes/2.16.2.adoc diff --git a/Documentation/RelNotes/2.16.3.txt b/Documentation/RelNotes/2.16.3.adoc similarity index 100% rename from Documentation/RelNotes/2.16.3.txt rename to Documentation/RelNotes/2.16.3.adoc diff --git a/Documentation/RelNotes/2.16.4.txt b/Documentation/RelNotes/2.16.4.adoc similarity index 100% rename from Documentation/RelNotes/2.16.4.txt rename to Documentation/RelNotes/2.16.4.adoc diff --git a/Documentation/RelNotes/2.16.5.txt b/Documentation/RelNotes/2.16.5.adoc similarity index 100% rename from Documentation/RelNotes/2.16.5.txt rename to Documentation/RelNotes/2.16.5.adoc diff --git a/Documentation/RelNotes/2.16.6.txt b/Documentation/RelNotes/2.16.6.adoc similarity index 100% rename from Documentation/RelNotes/2.16.6.txt rename to Documentation/RelNotes/2.16.6.adoc diff --git a/Documentation/RelNotes/2.17.0.txt b/Documentation/RelNotes/2.17.0.adoc similarity index 100% rename from Documentation/RelNotes/2.17.0.txt rename to Documentation/RelNotes/2.17.0.adoc diff --git a/Documentation/RelNotes/2.17.1.txt b/Documentation/RelNotes/2.17.1.adoc similarity index 100% rename from Documentation/RelNotes/2.17.1.txt rename to Documentation/RelNotes/2.17.1.adoc diff --git a/Documentation/RelNotes/2.17.2.txt b/Documentation/RelNotes/2.17.2.adoc similarity index 100% rename from Documentation/RelNotes/2.17.2.txt rename to Documentation/RelNotes/2.17.2.adoc diff --git a/Documentation/RelNotes/2.17.3.txt b/Documentation/RelNotes/2.17.3.adoc similarity index 100% rename from Documentation/RelNotes/2.17.3.txt rename to Documentation/RelNotes/2.17.3.adoc diff --git a/Documentation/RelNotes/2.17.4.txt b/Documentation/RelNotes/2.17.4.adoc similarity index 100% rename from Documentation/RelNotes/2.17.4.txt rename to Documentation/RelNotes/2.17.4.adoc diff --git a/Documentation/RelNotes/2.17.5.txt b/Documentation/RelNotes/2.17.5.adoc similarity index 100% rename from Documentation/RelNotes/2.17.5.txt rename to Documentation/RelNotes/2.17.5.adoc diff --git a/Documentation/RelNotes/2.17.6.txt b/Documentation/RelNotes/2.17.6.adoc similarity index 100% rename from Documentation/RelNotes/2.17.6.txt rename to Documentation/RelNotes/2.17.6.adoc diff --git a/Documentation/RelNotes/2.18.0.txt b/Documentation/RelNotes/2.18.0.adoc similarity index 100% rename from Documentation/RelNotes/2.18.0.txt rename to Documentation/RelNotes/2.18.0.adoc diff --git a/Documentation/RelNotes/2.18.1.txt b/Documentation/RelNotes/2.18.1.adoc similarity index 100% rename from Documentation/RelNotes/2.18.1.txt rename to Documentation/RelNotes/2.18.1.adoc diff --git a/Documentation/RelNotes/2.18.2.txt b/Documentation/RelNotes/2.18.2.adoc similarity index 100% rename from Documentation/RelNotes/2.18.2.txt rename to Documentation/RelNotes/2.18.2.adoc diff --git a/Documentation/RelNotes/2.18.3.txt b/Documentation/RelNotes/2.18.3.adoc similarity index 100% rename from Documentation/RelNotes/2.18.3.txt rename to Documentation/RelNotes/2.18.3.adoc diff --git a/Documentation/RelNotes/2.18.4.txt b/Documentation/RelNotes/2.18.4.adoc similarity index 100% rename from Documentation/RelNotes/2.18.4.txt rename to Documentation/RelNotes/2.18.4.adoc diff --git a/Documentation/RelNotes/2.18.5.txt b/Documentation/RelNotes/2.18.5.adoc similarity index 100% rename from Documentation/RelNotes/2.18.5.txt rename to Documentation/RelNotes/2.18.5.adoc diff --git a/Documentation/RelNotes/2.19.0.txt b/Documentation/RelNotes/2.19.0.adoc similarity index 100% rename from Documentation/RelNotes/2.19.0.txt rename to Documentation/RelNotes/2.19.0.adoc diff --git a/Documentation/RelNotes/2.19.1.txt b/Documentation/RelNotes/2.19.1.adoc similarity index 100% rename from Documentation/RelNotes/2.19.1.txt rename to Documentation/RelNotes/2.19.1.adoc diff --git a/Documentation/RelNotes/2.19.2.txt b/Documentation/RelNotes/2.19.2.adoc similarity index 100% rename from Documentation/RelNotes/2.19.2.txt rename to Documentation/RelNotes/2.19.2.adoc diff --git a/Documentation/RelNotes/2.19.3.txt b/Documentation/RelNotes/2.19.3.adoc similarity index 100% rename from Documentation/RelNotes/2.19.3.txt rename to Documentation/RelNotes/2.19.3.adoc diff --git a/Documentation/RelNotes/2.19.4.txt b/Documentation/RelNotes/2.19.4.adoc similarity index 100% rename from Documentation/RelNotes/2.19.4.txt rename to Documentation/RelNotes/2.19.4.adoc diff --git a/Documentation/RelNotes/2.19.5.txt b/Documentation/RelNotes/2.19.5.adoc similarity index 100% rename from Documentation/RelNotes/2.19.5.txt rename to Documentation/RelNotes/2.19.5.adoc diff --git a/Documentation/RelNotes/2.19.6.txt b/Documentation/RelNotes/2.19.6.adoc similarity index 100% rename from Documentation/RelNotes/2.19.6.txt rename to Documentation/RelNotes/2.19.6.adoc diff --git a/Documentation/RelNotes/2.2.0.txt b/Documentation/RelNotes/2.2.0.adoc similarity index 100% rename from Documentation/RelNotes/2.2.0.txt rename to Documentation/RelNotes/2.2.0.adoc diff --git a/Documentation/RelNotes/2.2.1.txt b/Documentation/RelNotes/2.2.1.adoc similarity index 100% rename from Documentation/RelNotes/2.2.1.txt rename to Documentation/RelNotes/2.2.1.adoc diff --git a/Documentation/RelNotes/2.2.2.txt b/Documentation/RelNotes/2.2.2.adoc similarity index 100% rename from Documentation/RelNotes/2.2.2.txt rename to Documentation/RelNotes/2.2.2.adoc diff --git a/Documentation/RelNotes/2.2.3.txt b/Documentation/RelNotes/2.2.3.adoc similarity index 100% rename from Documentation/RelNotes/2.2.3.txt rename to Documentation/RelNotes/2.2.3.adoc diff --git a/Documentation/RelNotes/2.20.0.txt b/Documentation/RelNotes/2.20.0.adoc similarity index 100% rename from Documentation/RelNotes/2.20.0.txt rename to Documentation/RelNotes/2.20.0.adoc diff --git a/Documentation/RelNotes/2.20.1.txt b/Documentation/RelNotes/2.20.1.adoc similarity index 100% rename from Documentation/RelNotes/2.20.1.txt rename to Documentation/RelNotes/2.20.1.adoc diff --git a/Documentation/RelNotes/2.20.2.txt b/Documentation/RelNotes/2.20.2.adoc similarity index 100% rename from Documentation/RelNotes/2.20.2.txt rename to Documentation/RelNotes/2.20.2.adoc diff --git a/Documentation/RelNotes/2.20.3.txt b/Documentation/RelNotes/2.20.3.adoc similarity index 100% rename from Documentation/RelNotes/2.20.3.txt rename to Documentation/RelNotes/2.20.3.adoc diff --git a/Documentation/RelNotes/2.20.4.txt b/Documentation/RelNotes/2.20.4.adoc similarity index 100% rename from Documentation/RelNotes/2.20.4.txt rename to Documentation/RelNotes/2.20.4.adoc diff --git a/Documentation/RelNotes/2.20.5.txt b/Documentation/RelNotes/2.20.5.adoc similarity index 100% rename from Documentation/RelNotes/2.20.5.txt rename to Documentation/RelNotes/2.20.5.adoc diff --git a/Documentation/RelNotes/2.21.0.txt b/Documentation/RelNotes/2.21.0.adoc similarity index 100% rename from Documentation/RelNotes/2.21.0.txt rename to Documentation/RelNotes/2.21.0.adoc diff --git a/Documentation/RelNotes/2.21.1.txt b/Documentation/RelNotes/2.21.1.adoc similarity index 100% rename from Documentation/RelNotes/2.21.1.txt rename to Documentation/RelNotes/2.21.1.adoc diff --git a/Documentation/RelNotes/2.21.2.txt b/Documentation/RelNotes/2.21.2.adoc similarity index 100% rename from Documentation/RelNotes/2.21.2.txt rename to Documentation/RelNotes/2.21.2.adoc diff --git a/Documentation/RelNotes/2.21.3.txt b/Documentation/RelNotes/2.21.3.adoc similarity index 100% rename from Documentation/RelNotes/2.21.3.txt rename to Documentation/RelNotes/2.21.3.adoc diff --git a/Documentation/RelNotes/2.21.4.txt b/Documentation/RelNotes/2.21.4.adoc similarity index 100% rename from Documentation/RelNotes/2.21.4.txt rename to Documentation/RelNotes/2.21.4.adoc diff --git a/Documentation/RelNotes/2.22.0.txt b/Documentation/RelNotes/2.22.0.adoc similarity index 100% rename from Documentation/RelNotes/2.22.0.txt rename to Documentation/RelNotes/2.22.0.adoc diff --git a/Documentation/RelNotes/2.22.1.txt b/Documentation/RelNotes/2.22.1.adoc similarity index 100% rename from Documentation/RelNotes/2.22.1.txt rename to Documentation/RelNotes/2.22.1.adoc diff --git a/Documentation/RelNotes/2.22.2.txt b/Documentation/RelNotes/2.22.2.adoc similarity index 100% rename from Documentation/RelNotes/2.22.2.txt rename to Documentation/RelNotes/2.22.2.adoc diff --git a/Documentation/RelNotes/2.22.3.txt b/Documentation/RelNotes/2.22.3.adoc similarity index 100% rename from Documentation/RelNotes/2.22.3.txt rename to Documentation/RelNotes/2.22.3.adoc diff --git a/Documentation/RelNotes/2.22.4.txt b/Documentation/RelNotes/2.22.4.adoc similarity index 100% rename from Documentation/RelNotes/2.22.4.txt rename to Documentation/RelNotes/2.22.4.adoc diff --git a/Documentation/RelNotes/2.22.5.txt b/Documentation/RelNotes/2.22.5.adoc similarity index 100% rename from Documentation/RelNotes/2.22.5.txt rename to Documentation/RelNotes/2.22.5.adoc diff --git a/Documentation/RelNotes/2.23.0.txt b/Documentation/RelNotes/2.23.0.adoc similarity index 100% rename from Documentation/RelNotes/2.23.0.txt rename to Documentation/RelNotes/2.23.0.adoc diff --git a/Documentation/RelNotes/2.23.1.txt b/Documentation/RelNotes/2.23.1.adoc similarity index 100% rename from Documentation/RelNotes/2.23.1.txt rename to Documentation/RelNotes/2.23.1.adoc diff --git a/Documentation/RelNotes/2.23.2.txt b/Documentation/RelNotes/2.23.2.adoc similarity index 100% rename from Documentation/RelNotes/2.23.2.txt rename to Documentation/RelNotes/2.23.2.adoc diff --git a/Documentation/RelNotes/2.23.3.txt b/Documentation/RelNotes/2.23.3.adoc similarity index 100% rename from Documentation/RelNotes/2.23.3.txt rename to Documentation/RelNotes/2.23.3.adoc diff --git a/Documentation/RelNotes/2.23.4.txt b/Documentation/RelNotes/2.23.4.adoc similarity index 100% rename from Documentation/RelNotes/2.23.4.txt rename to Documentation/RelNotes/2.23.4.adoc diff --git a/Documentation/RelNotes/2.24.0.txt b/Documentation/RelNotes/2.24.0.adoc similarity index 100% rename from Documentation/RelNotes/2.24.0.txt rename to Documentation/RelNotes/2.24.0.adoc diff --git a/Documentation/RelNotes/2.24.1.txt b/Documentation/RelNotes/2.24.1.adoc similarity index 100% rename from Documentation/RelNotes/2.24.1.txt rename to Documentation/RelNotes/2.24.1.adoc diff --git a/Documentation/RelNotes/2.24.2.txt b/Documentation/RelNotes/2.24.2.adoc similarity index 100% rename from Documentation/RelNotes/2.24.2.txt rename to Documentation/RelNotes/2.24.2.adoc diff --git a/Documentation/RelNotes/2.24.3.txt b/Documentation/RelNotes/2.24.3.adoc similarity index 100% rename from Documentation/RelNotes/2.24.3.txt rename to Documentation/RelNotes/2.24.3.adoc diff --git a/Documentation/RelNotes/2.24.4.txt b/Documentation/RelNotes/2.24.4.adoc similarity index 100% rename from Documentation/RelNotes/2.24.4.txt rename to Documentation/RelNotes/2.24.4.adoc diff --git a/Documentation/RelNotes/2.25.0.txt b/Documentation/RelNotes/2.25.0.adoc similarity index 100% rename from Documentation/RelNotes/2.25.0.txt rename to Documentation/RelNotes/2.25.0.adoc diff --git a/Documentation/RelNotes/2.25.1.txt b/Documentation/RelNotes/2.25.1.adoc similarity index 100% rename from Documentation/RelNotes/2.25.1.txt rename to Documentation/RelNotes/2.25.1.adoc diff --git a/Documentation/RelNotes/2.25.2.txt b/Documentation/RelNotes/2.25.2.adoc similarity index 100% rename from Documentation/RelNotes/2.25.2.txt rename to Documentation/RelNotes/2.25.2.adoc diff --git a/Documentation/RelNotes/2.25.3.txt b/Documentation/RelNotes/2.25.3.adoc similarity index 100% rename from Documentation/RelNotes/2.25.3.txt rename to Documentation/RelNotes/2.25.3.adoc diff --git a/Documentation/RelNotes/2.25.4.txt b/Documentation/RelNotes/2.25.4.adoc similarity index 100% rename from Documentation/RelNotes/2.25.4.txt rename to Documentation/RelNotes/2.25.4.adoc diff --git a/Documentation/RelNotes/2.25.5.txt b/Documentation/RelNotes/2.25.5.adoc similarity index 100% rename from Documentation/RelNotes/2.25.5.txt rename to Documentation/RelNotes/2.25.5.adoc diff --git a/Documentation/RelNotes/2.26.0.txt b/Documentation/RelNotes/2.26.0.adoc similarity index 100% rename from Documentation/RelNotes/2.26.0.txt rename to Documentation/RelNotes/2.26.0.adoc diff --git a/Documentation/RelNotes/2.26.1.txt b/Documentation/RelNotes/2.26.1.adoc similarity index 100% rename from Documentation/RelNotes/2.26.1.txt rename to Documentation/RelNotes/2.26.1.adoc diff --git a/Documentation/RelNotes/2.26.2.txt b/Documentation/RelNotes/2.26.2.adoc similarity index 100% rename from Documentation/RelNotes/2.26.2.txt rename to Documentation/RelNotes/2.26.2.adoc diff --git a/Documentation/RelNotes/2.26.3.txt b/Documentation/RelNotes/2.26.3.adoc similarity index 100% rename from Documentation/RelNotes/2.26.3.txt rename to Documentation/RelNotes/2.26.3.adoc diff --git a/Documentation/RelNotes/2.27.0.txt b/Documentation/RelNotes/2.27.0.adoc similarity index 100% rename from Documentation/RelNotes/2.27.0.txt rename to Documentation/RelNotes/2.27.0.adoc diff --git a/Documentation/RelNotes/2.27.1.txt b/Documentation/RelNotes/2.27.1.adoc similarity index 100% rename from Documentation/RelNotes/2.27.1.txt rename to Documentation/RelNotes/2.27.1.adoc diff --git a/Documentation/RelNotes/2.28.0.txt b/Documentation/RelNotes/2.28.0.adoc similarity index 100% rename from Documentation/RelNotes/2.28.0.txt rename to Documentation/RelNotes/2.28.0.adoc diff --git a/Documentation/RelNotes/2.28.1.txt b/Documentation/RelNotes/2.28.1.adoc similarity index 100% rename from Documentation/RelNotes/2.28.1.txt rename to Documentation/RelNotes/2.28.1.adoc diff --git a/Documentation/RelNotes/2.29.0.txt b/Documentation/RelNotes/2.29.0.adoc similarity index 100% rename from Documentation/RelNotes/2.29.0.txt rename to Documentation/RelNotes/2.29.0.adoc diff --git a/Documentation/RelNotes/2.29.1.txt b/Documentation/RelNotes/2.29.1.adoc similarity index 100% rename from Documentation/RelNotes/2.29.1.txt rename to Documentation/RelNotes/2.29.1.adoc diff --git a/Documentation/RelNotes/2.29.2.txt b/Documentation/RelNotes/2.29.2.adoc similarity index 100% rename from Documentation/RelNotes/2.29.2.txt rename to Documentation/RelNotes/2.29.2.adoc diff --git a/Documentation/RelNotes/2.29.3.txt b/Documentation/RelNotes/2.29.3.adoc similarity index 100% rename from Documentation/RelNotes/2.29.3.txt rename to Documentation/RelNotes/2.29.3.adoc diff --git a/Documentation/RelNotes/2.3.0.txt b/Documentation/RelNotes/2.3.0.adoc similarity index 100% rename from Documentation/RelNotes/2.3.0.txt rename to Documentation/RelNotes/2.3.0.adoc diff --git a/Documentation/RelNotes/2.3.1.txt b/Documentation/RelNotes/2.3.1.adoc similarity index 100% rename from Documentation/RelNotes/2.3.1.txt rename to Documentation/RelNotes/2.3.1.adoc diff --git a/Documentation/RelNotes/2.3.10.txt b/Documentation/RelNotes/2.3.10.adoc similarity index 100% rename from Documentation/RelNotes/2.3.10.txt rename to Documentation/RelNotes/2.3.10.adoc diff --git a/Documentation/RelNotes/2.3.2.txt b/Documentation/RelNotes/2.3.2.adoc similarity index 100% rename from Documentation/RelNotes/2.3.2.txt rename to Documentation/RelNotes/2.3.2.adoc diff --git a/Documentation/RelNotes/2.3.3.txt b/Documentation/RelNotes/2.3.3.adoc similarity index 100% rename from Documentation/RelNotes/2.3.3.txt rename to Documentation/RelNotes/2.3.3.adoc diff --git a/Documentation/RelNotes/2.3.4.txt b/Documentation/RelNotes/2.3.4.adoc similarity index 100% rename from Documentation/RelNotes/2.3.4.txt rename to Documentation/RelNotes/2.3.4.adoc diff --git a/Documentation/RelNotes/2.3.5.txt b/Documentation/RelNotes/2.3.5.adoc similarity index 100% rename from Documentation/RelNotes/2.3.5.txt rename to Documentation/RelNotes/2.3.5.adoc diff --git a/Documentation/RelNotes/2.3.6.txt b/Documentation/RelNotes/2.3.6.adoc similarity index 100% rename from Documentation/RelNotes/2.3.6.txt rename to Documentation/RelNotes/2.3.6.adoc diff --git a/Documentation/RelNotes/2.3.7.txt b/Documentation/RelNotes/2.3.7.adoc similarity index 100% rename from Documentation/RelNotes/2.3.7.txt rename to Documentation/RelNotes/2.3.7.adoc diff --git a/Documentation/RelNotes/2.3.8.txt b/Documentation/RelNotes/2.3.8.adoc similarity index 100% rename from Documentation/RelNotes/2.3.8.txt rename to Documentation/RelNotes/2.3.8.adoc diff --git a/Documentation/RelNotes/2.3.9.txt b/Documentation/RelNotes/2.3.9.adoc similarity index 100% rename from Documentation/RelNotes/2.3.9.txt rename to Documentation/RelNotes/2.3.9.adoc diff --git a/Documentation/RelNotes/2.30.0.txt b/Documentation/RelNotes/2.30.0.adoc similarity index 100% rename from Documentation/RelNotes/2.30.0.txt rename to Documentation/RelNotes/2.30.0.adoc diff --git a/Documentation/RelNotes/2.30.1.txt b/Documentation/RelNotes/2.30.1.adoc similarity index 100% rename from Documentation/RelNotes/2.30.1.txt rename to Documentation/RelNotes/2.30.1.adoc diff --git a/Documentation/RelNotes/2.30.2.txt b/Documentation/RelNotes/2.30.2.adoc similarity index 100% rename from Documentation/RelNotes/2.30.2.txt rename to Documentation/RelNotes/2.30.2.adoc diff --git a/Documentation/RelNotes/2.30.3.txt b/Documentation/RelNotes/2.30.3.adoc similarity index 100% rename from Documentation/RelNotes/2.30.3.txt rename to Documentation/RelNotes/2.30.3.adoc diff --git a/Documentation/RelNotes/2.30.4.txt b/Documentation/RelNotes/2.30.4.adoc similarity index 100% rename from Documentation/RelNotes/2.30.4.txt rename to Documentation/RelNotes/2.30.4.adoc diff --git a/Documentation/RelNotes/2.30.5.txt b/Documentation/RelNotes/2.30.5.adoc similarity index 100% rename from Documentation/RelNotes/2.30.5.txt rename to Documentation/RelNotes/2.30.5.adoc diff --git a/Documentation/RelNotes/2.30.6.txt b/Documentation/RelNotes/2.30.6.adoc similarity index 100% rename from Documentation/RelNotes/2.30.6.txt rename to Documentation/RelNotes/2.30.6.adoc diff --git a/Documentation/RelNotes/2.30.7.txt b/Documentation/RelNotes/2.30.7.adoc similarity index 100% rename from Documentation/RelNotes/2.30.7.txt rename to Documentation/RelNotes/2.30.7.adoc diff --git a/Documentation/RelNotes/2.30.8.txt b/Documentation/RelNotes/2.30.8.adoc similarity index 100% rename from Documentation/RelNotes/2.30.8.txt rename to Documentation/RelNotes/2.30.8.adoc diff --git a/Documentation/RelNotes/2.30.9.txt b/Documentation/RelNotes/2.30.9.adoc similarity index 100% rename from Documentation/RelNotes/2.30.9.txt rename to Documentation/RelNotes/2.30.9.adoc diff --git a/Documentation/RelNotes/2.31.0.txt b/Documentation/RelNotes/2.31.0.adoc similarity index 100% rename from Documentation/RelNotes/2.31.0.txt rename to Documentation/RelNotes/2.31.0.adoc diff --git a/Documentation/RelNotes/2.31.1.txt b/Documentation/RelNotes/2.31.1.adoc similarity index 100% rename from Documentation/RelNotes/2.31.1.txt rename to Documentation/RelNotes/2.31.1.adoc diff --git a/Documentation/RelNotes/2.31.2.txt b/Documentation/RelNotes/2.31.2.adoc similarity index 100% rename from Documentation/RelNotes/2.31.2.txt rename to Documentation/RelNotes/2.31.2.adoc diff --git a/Documentation/RelNotes/2.31.3.txt b/Documentation/RelNotes/2.31.3.adoc similarity index 100% rename from Documentation/RelNotes/2.31.3.txt rename to Documentation/RelNotes/2.31.3.adoc diff --git a/Documentation/RelNotes/2.31.4.txt b/Documentation/RelNotes/2.31.4.adoc similarity index 100% rename from Documentation/RelNotes/2.31.4.txt rename to Documentation/RelNotes/2.31.4.adoc diff --git a/Documentation/RelNotes/2.31.5.txt b/Documentation/RelNotes/2.31.5.adoc similarity index 100% rename from Documentation/RelNotes/2.31.5.txt rename to Documentation/RelNotes/2.31.5.adoc diff --git a/Documentation/RelNotes/2.31.6.txt b/Documentation/RelNotes/2.31.6.adoc similarity index 100% rename from Documentation/RelNotes/2.31.6.txt rename to Documentation/RelNotes/2.31.6.adoc diff --git a/Documentation/RelNotes/2.31.7.txt b/Documentation/RelNotes/2.31.7.adoc similarity index 100% rename from Documentation/RelNotes/2.31.7.txt rename to Documentation/RelNotes/2.31.7.adoc diff --git a/Documentation/RelNotes/2.31.8.txt b/Documentation/RelNotes/2.31.8.adoc similarity index 100% rename from Documentation/RelNotes/2.31.8.txt rename to Documentation/RelNotes/2.31.8.adoc diff --git a/Documentation/RelNotes/2.32.0.txt b/Documentation/RelNotes/2.32.0.adoc similarity index 100% rename from Documentation/RelNotes/2.32.0.txt rename to Documentation/RelNotes/2.32.0.adoc diff --git a/Documentation/RelNotes/2.32.1.txt b/Documentation/RelNotes/2.32.1.adoc similarity index 100% rename from Documentation/RelNotes/2.32.1.txt rename to Documentation/RelNotes/2.32.1.adoc diff --git a/Documentation/RelNotes/2.32.2.txt b/Documentation/RelNotes/2.32.2.adoc similarity index 100% rename from Documentation/RelNotes/2.32.2.txt rename to Documentation/RelNotes/2.32.2.adoc diff --git a/Documentation/RelNotes/2.32.3.txt b/Documentation/RelNotes/2.32.3.adoc similarity index 100% rename from Documentation/RelNotes/2.32.3.txt rename to Documentation/RelNotes/2.32.3.adoc diff --git a/Documentation/RelNotes/2.32.4.txt b/Documentation/RelNotes/2.32.4.adoc similarity index 100% rename from Documentation/RelNotes/2.32.4.txt rename to Documentation/RelNotes/2.32.4.adoc diff --git a/Documentation/RelNotes/2.32.5.txt b/Documentation/RelNotes/2.32.5.adoc similarity index 100% rename from Documentation/RelNotes/2.32.5.txt rename to Documentation/RelNotes/2.32.5.adoc diff --git a/Documentation/RelNotes/2.32.6.txt b/Documentation/RelNotes/2.32.6.adoc similarity index 100% rename from Documentation/RelNotes/2.32.6.txt rename to Documentation/RelNotes/2.32.6.adoc diff --git a/Documentation/RelNotes/2.32.7.txt b/Documentation/RelNotes/2.32.7.adoc similarity index 100% rename from Documentation/RelNotes/2.32.7.txt rename to Documentation/RelNotes/2.32.7.adoc diff --git a/Documentation/RelNotes/2.33.0.txt b/Documentation/RelNotes/2.33.0.adoc similarity index 100% rename from Documentation/RelNotes/2.33.0.txt rename to Documentation/RelNotes/2.33.0.adoc diff --git a/Documentation/RelNotes/2.33.1.txt b/Documentation/RelNotes/2.33.1.adoc similarity index 100% rename from Documentation/RelNotes/2.33.1.txt rename to Documentation/RelNotes/2.33.1.adoc diff --git a/Documentation/RelNotes/2.33.2.txt b/Documentation/RelNotes/2.33.2.adoc similarity index 100% rename from Documentation/RelNotes/2.33.2.txt rename to Documentation/RelNotes/2.33.2.adoc diff --git a/Documentation/RelNotes/2.33.3.txt b/Documentation/RelNotes/2.33.3.adoc similarity index 100% rename from Documentation/RelNotes/2.33.3.txt rename to Documentation/RelNotes/2.33.3.adoc diff --git a/Documentation/RelNotes/2.33.4.txt b/Documentation/RelNotes/2.33.4.adoc similarity index 100% rename from Documentation/RelNotes/2.33.4.txt rename to Documentation/RelNotes/2.33.4.adoc diff --git a/Documentation/RelNotes/2.33.5.txt b/Documentation/RelNotes/2.33.5.adoc similarity index 100% rename from Documentation/RelNotes/2.33.5.txt rename to Documentation/RelNotes/2.33.5.adoc diff --git a/Documentation/RelNotes/2.33.6.txt b/Documentation/RelNotes/2.33.6.adoc similarity index 100% rename from Documentation/RelNotes/2.33.6.txt rename to Documentation/RelNotes/2.33.6.adoc diff --git a/Documentation/RelNotes/2.33.7.txt b/Documentation/RelNotes/2.33.7.adoc similarity index 100% rename from Documentation/RelNotes/2.33.7.txt rename to Documentation/RelNotes/2.33.7.adoc diff --git a/Documentation/RelNotes/2.33.8.txt b/Documentation/RelNotes/2.33.8.adoc similarity index 100% rename from Documentation/RelNotes/2.33.8.txt rename to Documentation/RelNotes/2.33.8.adoc diff --git a/Documentation/RelNotes/2.34.0.txt b/Documentation/RelNotes/2.34.0.adoc similarity index 100% rename from Documentation/RelNotes/2.34.0.txt rename to Documentation/RelNotes/2.34.0.adoc diff --git a/Documentation/RelNotes/2.34.1.txt b/Documentation/RelNotes/2.34.1.adoc similarity index 100% rename from Documentation/RelNotes/2.34.1.txt rename to Documentation/RelNotes/2.34.1.adoc diff --git a/Documentation/RelNotes/2.34.2.txt b/Documentation/RelNotes/2.34.2.adoc similarity index 100% rename from Documentation/RelNotes/2.34.2.txt rename to Documentation/RelNotes/2.34.2.adoc diff --git a/Documentation/RelNotes/2.34.3.txt b/Documentation/RelNotes/2.34.3.adoc similarity index 100% rename from Documentation/RelNotes/2.34.3.txt rename to Documentation/RelNotes/2.34.3.adoc diff --git a/Documentation/RelNotes/2.34.4.txt b/Documentation/RelNotes/2.34.4.adoc similarity index 100% rename from Documentation/RelNotes/2.34.4.txt rename to Documentation/RelNotes/2.34.4.adoc diff --git a/Documentation/RelNotes/2.34.5.txt b/Documentation/RelNotes/2.34.5.adoc similarity index 100% rename from Documentation/RelNotes/2.34.5.txt rename to Documentation/RelNotes/2.34.5.adoc diff --git a/Documentation/RelNotes/2.34.6.txt b/Documentation/RelNotes/2.34.6.adoc similarity index 100% rename from Documentation/RelNotes/2.34.6.txt rename to Documentation/RelNotes/2.34.6.adoc diff --git a/Documentation/RelNotes/2.34.7.txt b/Documentation/RelNotes/2.34.7.adoc similarity index 100% rename from Documentation/RelNotes/2.34.7.txt rename to Documentation/RelNotes/2.34.7.adoc diff --git a/Documentation/RelNotes/2.34.8.txt b/Documentation/RelNotes/2.34.8.adoc similarity index 100% rename from Documentation/RelNotes/2.34.8.txt rename to Documentation/RelNotes/2.34.8.adoc diff --git a/Documentation/RelNotes/2.35.0.txt b/Documentation/RelNotes/2.35.0.adoc similarity index 100% rename from Documentation/RelNotes/2.35.0.txt rename to Documentation/RelNotes/2.35.0.adoc diff --git a/Documentation/RelNotes/2.35.1.txt b/Documentation/RelNotes/2.35.1.adoc similarity index 100% rename from Documentation/RelNotes/2.35.1.txt rename to Documentation/RelNotes/2.35.1.adoc diff --git a/Documentation/RelNotes/2.35.2.txt b/Documentation/RelNotes/2.35.2.adoc similarity index 100% rename from Documentation/RelNotes/2.35.2.txt rename to Documentation/RelNotes/2.35.2.adoc diff --git a/Documentation/RelNotes/2.35.3.txt b/Documentation/RelNotes/2.35.3.adoc similarity index 100% rename from Documentation/RelNotes/2.35.3.txt rename to Documentation/RelNotes/2.35.3.adoc diff --git a/Documentation/RelNotes/2.35.4.txt b/Documentation/RelNotes/2.35.4.adoc similarity index 100% rename from Documentation/RelNotes/2.35.4.txt rename to Documentation/RelNotes/2.35.4.adoc diff --git a/Documentation/RelNotes/2.35.5.txt b/Documentation/RelNotes/2.35.5.adoc similarity index 100% rename from Documentation/RelNotes/2.35.5.txt rename to Documentation/RelNotes/2.35.5.adoc diff --git a/Documentation/RelNotes/2.35.6.txt b/Documentation/RelNotes/2.35.6.adoc similarity index 100% rename from Documentation/RelNotes/2.35.6.txt rename to Documentation/RelNotes/2.35.6.adoc diff --git a/Documentation/RelNotes/2.35.7.txt b/Documentation/RelNotes/2.35.7.adoc similarity index 100% rename from Documentation/RelNotes/2.35.7.txt rename to Documentation/RelNotes/2.35.7.adoc diff --git a/Documentation/RelNotes/2.35.8.txt b/Documentation/RelNotes/2.35.8.adoc similarity index 100% rename from Documentation/RelNotes/2.35.8.txt rename to Documentation/RelNotes/2.35.8.adoc diff --git a/Documentation/RelNotes/2.36.0.txt b/Documentation/RelNotes/2.36.0.adoc similarity index 100% rename from Documentation/RelNotes/2.36.0.txt rename to Documentation/RelNotes/2.36.0.adoc diff --git a/Documentation/RelNotes/2.36.1.txt b/Documentation/RelNotes/2.36.1.adoc similarity index 100% rename from Documentation/RelNotes/2.36.1.txt rename to Documentation/RelNotes/2.36.1.adoc diff --git a/Documentation/RelNotes/2.36.2.txt b/Documentation/RelNotes/2.36.2.adoc similarity index 100% rename from Documentation/RelNotes/2.36.2.txt rename to Documentation/RelNotes/2.36.2.adoc diff --git a/Documentation/RelNotes/2.36.3.txt b/Documentation/RelNotes/2.36.3.adoc similarity index 100% rename from Documentation/RelNotes/2.36.3.txt rename to Documentation/RelNotes/2.36.3.adoc diff --git a/Documentation/RelNotes/2.36.4.txt b/Documentation/RelNotes/2.36.4.adoc similarity index 100% rename from Documentation/RelNotes/2.36.4.txt rename to Documentation/RelNotes/2.36.4.adoc diff --git a/Documentation/RelNotes/2.36.5.txt b/Documentation/RelNotes/2.36.5.adoc similarity index 100% rename from Documentation/RelNotes/2.36.5.txt rename to Documentation/RelNotes/2.36.5.adoc diff --git a/Documentation/RelNotes/2.36.6.txt b/Documentation/RelNotes/2.36.6.adoc similarity index 100% rename from Documentation/RelNotes/2.36.6.txt rename to Documentation/RelNotes/2.36.6.adoc diff --git a/Documentation/RelNotes/2.37.0.txt b/Documentation/RelNotes/2.37.0.adoc similarity index 100% rename from Documentation/RelNotes/2.37.0.txt rename to Documentation/RelNotes/2.37.0.adoc diff --git a/Documentation/RelNotes/2.37.1.txt b/Documentation/RelNotes/2.37.1.adoc similarity index 100% rename from Documentation/RelNotes/2.37.1.txt rename to Documentation/RelNotes/2.37.1.adoc diff --git a/Documentation/RelNotes/2.37.2.txt b/Documentation/RelNotes/2.37.2.adoc similarity index 100% rename from Documentation/RelNotes/2.37.2.txt rename to Documentation/RelNotes/2.37.2.adoc diff --git a/Documentation/RelNotes/2.37.3.txt b/Documentation/RelNotes/2.37.3.adoc similarity index 100% rename from Documentation/RelNotes/2.37.3.txt rename to Documentation/RelNotes/2.37.3.adoc diff --git a/Documentation/RelNotes/2.37.4.txt b/Documentation/RelNotes/2.37.4.adoc similarity index 100% rename from Documentation/RelNotes/2.37.4.txt rename to Documentation/RelNotes/2.37.4.adoc diff --git a/Documentation/RelNotes/2.37.5.txt b/Documentation/RelNotes/2.37.5.adoc similarity index 100% rename from Documentation/RelNotes/2.37.5.txt rename to Documentation/RelNotes/2.37.5.adoc diff --git a/Documentation/RelNotes/2.37.6.txt b/Documentation/RelNotes/2.37.6.adoc similarity index 100% rename from Documentation/RelNotes/2.37.6.txt rename to Documentation/RelNotes/2.37.6.adoc diff --git a/Documentation/RelNotes/2.37.7.txt b/Documentation/RelNotes/2.37.7.adoc similarity index 100% rename from Documentation/RelNotes/2.37.7.txt rename to Documentation/RelNotes/2.37.7.adoc diff --git a/Documentation/RelNotes/2.38.0.txt b/Documentation/RelNotes/2.38.0.adoc similarity index 100% rename from Documentation/RelNotes/2.38.0.txt rename to Documentation/RelNotes/2.38.0.adoc diff --git a/Documentation/RelNotes/2.38.1.txt b/Documentation/RelNotes/2.38.1.adoc similarity index 100% rename from Documentation/RelNotes/2.38.1.txt rename to Documentation/RelNotes/2.38.1.adoc diff --git a/Documentation/RelNotes/2.38.2.txt b/Documentation/RelNotes/2.38.2.adoc similarity index 100% rename from Documentation/RelNotes/2.38.2.txt rename to Documentation/RelNotes/2.38.2.adoc diff --git a/Documentation/RelNotes/2.38.3.txt b/Documentation/RelNotes/2.38.3.adoc similarity index 100% rename from Documentation/RelNotes/2.38.3.txt rename to Documentation/RelNotes/2.38.3.adoc diff --git a/Documentation/RelNotes/2.38.4.txt b/Documentation/RelNotes/2.38.4.adoc similarity index 100% rename from Documentation/RelNotes/2.38.4.txt rename to Documentation/RelNotes/2.38.4.adoc diff --git a/Documentation/RelNotes/2.38.5.txt b/Documentation/RelNotes/2.38.5.adoc similarity index 100% rename from Documentation/RelNotes/2.38.5.txt rename to Documentation/RelNotes/2.38.5.adoc diff --git a/Documentation/RelNotes/2.39.0.txt b/Documentation/RelNotes/2.39.0.adoc similarity index 100% rename from Documentation/RelNotes/2.39.0.txt rename to Documentation/RelNotes/2.39.0.adoc diff --git a/Documentation/RelNotes/2.39.1.txt b/Documentation/RelNotes/2.39.1.adoc similarity index 100% rename from Documentation/RelNotes/2.39.1.txt rename to Documentation/RelNotes/2.39.1.adoc diff --git a/Documentation/RelNotes/2.39.2.txt b/Documentation/RelNotes/2.39.2.adoc similarity index 100% rename from Documentation/RelNotes/2.39.2.txt rename to Documentation/RelNotes/2.39.2.adoc diff --git a/Documentation/RelNotes/2.39.3.txt b/Documentation/RelNotes/2.39.3.adoc similarity index 100% rename from Documentation/RelNotes/2.39.3.txt rename to Documentation/RelNotes/2.39.3.adoc diff --git a/Documentation/RelNotes/2.39.4.txt b/Documentation/RelNotes/2.39.4.adoc similarity index 100% rename from Documentation/RelNotes/2.39.4.txt rename to Documentation/RelNotes/2.39.4.adoc diff --git a/Documentation/RelNotes/2.39.5.txt b/Documentation/RelNotes/2.39.5.adoc similarity index 100% rename from Documentation/RelNotes/2.39.5.txt rename to Documentation/RelNotes/2.39.5.adoc diff --git a/Documentation/RelNotes/2.4.0.txt b/Documentation/RelNotes/2.4.0.adoc similarity index 100% rename from Documentation/RelNotes/2.4.0.txt rename to Documentation/RelNotes/2.4.0.adoc diff --git a/Documentation/RelNotes/2.4.1.txt b/Documentation/RelNotes/2.4.1.adoc similarity index 100% rename from Documentation/RelNotes/2.4.1.txt rename to Documentation/RelNotes/2.4.1.adoc diff --git a/Documentation/RelNotes/2.4.10.txt b/Documentation/RelNotes/2.4.10.adoc similarity index 100% rename from Documentation/RelNotes/2.4.10.txt rename to Documentation/RelNotes/2.4.10.adoc diff --git a/Documentation/RelNotes/2.4.11.txt b/Documentation/RelNotes/2.4.11.adoc similarity index 100% rename from Documentation/RelNotes/2.4.11.txt rename to Documentation/RelNotes/2.4.11.adoc diff --git a/Documentation/RelNotes/2.4.12.txt b/Documentation/RelNotes/2.4.12.adoc similarity index 100% rename from Documentation/RelNotes/2.4.12.txt rename to Documentation/RelNotes/2.4.12.adoc diff --git a/Documentation/RelNotes/2.4.2.txt b/Documentation/RelNotes/2.4.2.adoc similarity index 100% rename from Documentation/RelNotes/2.4.2.txt rename to Documentation/RelNotes/2.4.2.adoc diff --git a/Documentation/RelNotes/2.4.3.txt b/Documentation/RelNotes/2.4.3.adoc similarity index 100% rename from Documentation/RelNotes/2.4.3.txt rename to Documentation/RelNotes/2.4.3.adoc diff --git a/Documentation/RelNotes/2.4.4.txt b/Documentation/RelNotes/2.4.4.adoc similarity index 100% rename from Documentation/RelNotes/2.4.4.txt rename to Documentation/RelNotes/2.4.4.adoc diff --git a/Documentation/RelNotes/2.4.5.txt b/Documentation/RelNotes/2.4.5.adoc similarity index 100% rename from Documentation/RelNotes/2.4.5.txt rename to Documentation/RelNotes/2.4.5.adoc diff --git a/Documentation/RelNotes/2.4.6.txt b/Documentation/RelNotes/2.4.6.adoc similarity index 100% rename from Documentation/RelNotes/2.4.6.txt rename to Documentation/RelNotes/2.4.6.adoc diff --git a/Documentation/RelNotes/2.4.7.txt b/Documentation/RelNotes/2.4.7.adoc similarity index 100% rename from Documentation/RelNotes/2.4.7.txt rename to Documentation/RelNotes/2.4.7.adoc diff --git a/Documentation/RelNotes/2.4.8.txt b/Documentation/RelNotes/2.4.8.adoc similarity index 100% rename from Documentation/RelNotes/2.4.8.txt rename to Documentation/RelNotes/2.4.8.adoc diff --git a/Documentation/RelNotes/2.4.9.txt b/Documentation/RelNotes/2.4.9.adoc similarity index 100% rename from Documentation/RelNotes/2.4.9.txt rename to Documentation/RelNotes/2.4.9.adoc diff --git a/Documentation/RelNotes/2.40.0.txt b/Documentation/RelNotes/2.40.0.adoc similarity index 100% rename from Documentation/RelNotes/2.40.0.txt rename to Documentation/RelNotes/2.40.0.adoc diff --git a/Documentation/RelNotes/2.40.1.txt b/Documentation/RelNotes/2.40.1.adoc similarity index 100% rename from Documentation/RelNotes/2.40.1.txt rename to Documentation/RelNotes/2.40.1.adoc diff --git a/Documentation/RelNotes/2.40.2.txt b/Documentation/RelNotes/2.40.2.adoc similarity index 100% rename from Documentation/RelNotes/2.40.2.txt rename to Documentation/RelNotes/2.40.2.adoc diff --git a/Documentation/RelNotes/2.40.3.txt b/Documentation/RelNotes/2.40.3.adoc similarity index 100% rename from Documentation/RelNotes/2.40.3.txt rename to Documentation/RelNotes/2.40.3.adoc diff --git a/Documentation/RelNotes/2.40.4.adoc b/Documentation/RelNotes/2.40.4.adoc new file mode 100644 index 00000000000000..0ff29f3cfcfefe --- /dev/null +++ b/Documentation/RelNotes/2.40.4.adoc @@ -0,0 +1,5 @@ +Git v2.40.4 Release Notes +========================= + +This release lets Git refuse to accept URLs that contain control +sequences. This addresses CVE-2024-50349 and CVE-2024-52006. diff --git a/Documentation/RelNotes/2.41.0.txt b/Documentation/RelNotes/2.41.0.adoc similarity index 100% rename from Documentation/RelNotes/2.41.0.txt rename to Documentation/RelNotes/2.41.0.adoc diff --git a/Documentation/RelNotes/2.41.1.txt b/Documentation/RelNotes/2.41.1.adoc similarity index 100% rename from Documentation/RelNotes/2.41.1.txt rename to Documentation/RelNotes/2.41.1.adoc diff --git a/Documentation/RelNotes/2.41.2.txt b/Documentation/RelNotes/2.41.2.adoc similarity index 100% rename from Documentation/RelNotes/2.41.2.txt rename to Documentation/RelNotes/2.41.2.adoc diff --git a/Documentation/RelNotes/2.41.3.adoc b/Documentation/RelNotes/2.41.3.adoc new file mode 100644 index 00000000000000..b5aba88790c2c0 --- /dev/null +++ b/Documentation/RelNotes/2.41.3.adoc @@ -0,0 +1,6 @@ +Git v2.41.3 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4 to address +the security issues CVE-2024-50349 and CVE-2024-52006; see the +release notes for that version for details. diff --git a/Documentation/RelNotes/2.42.0.txt b/Documentation/RelNotes/2.42.0.adoc similarity index 100% rename from Documentation/RelNotes/2.42.0.txt rename to Documentation/RelNotes/2.42.0.adoc diff --git a/Documentation/RelNotes/2.42.1.txt b/Documentation/RelNotes/2.42.1.adoc similarity index 100% rename from Documentation/RelNotes/2.42.1.txt rename to Documentation/RelNotes/2.42.1.adoc diff --git a/Documentation/RelNotes/2.42.2.txt b/Documentation/RelNotes/2.42.2.adoc similarity index 100% rename from Documentation/RelNotes/2.42.2.txt rename to Documentation/RelNotes/2.42.2.adoc diff --git a/Documentation/RelNotes/2.42.3.txt b/Documentation/RelNotes/2.42.3.adoc similarity index 100% rename from Documentation/RelNotes/2.42.3.txt rename to Documentation/RelNotes/2.42.3.adoc diff --git a/Documentation/RelNotes/2.42.4.adoc b/Documentation/RelNotes/2.42.4.adoc new file mode 100644 index 00000000000000..3129d76e751dab --- /dev/null +++ b/Documentation/RelNotes/2.42.4.adoc @@ -0,0 +1,6 @@ +Git v2.42.4 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4 and v2.41.3 +to address the security issues CVE-2024-50349 and CVE-2024-52006; +see the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.43.0.txt b/Documentation/RelNotes/2.43.0.adoc similarity index 100% rename from Documentation/RelNotes/2.43.0.txt rename to Documentation/RelNotes/2.43.0.adoc diff --git a/Documentation/RelNotes/2.43.1.txt b/Documentation/RelNotes/2.43.1.adoc similarity index 100% rename from Documentation/RelNotes/2.43.1.txt rename to Documentation/RelNotes/2.43.1.adoc diff --git a/Documentation/RelNotes/2.43.2.txt b/Documentation/RelNotes/2.43.2.adoc similarity index 100% rename from Documentation/RelNotes/2.43.2.txt rename to Documentation/RelNotes/2.43.2.adoc diff --git a/Documentation/RelNotes/2.43.3.txt b/Documentation/RelNotes/2.43.3.adoc similarity index 100% rename from Documentation/RelNotes/2.43.3.txt rename to Documentation/RelNotes/2.43.3.adoc diff --git a/Documentation/RelNotes/2.43.4.txt b/Documentation/RelNotes/2.43.4.adoc similarity index 100% rename from Documentation/RelNotes/2.43.4.txt rename to Documentation/RelNotes/2.43.4.adoc diff --git a/Documentation/RelNotes/2.43.5.txt b/Documentation/RelNotes/2.43.5.adoc similarity index 100% rename from Documentation/RelNotes/2.43.5.txt rename to Documentation/RelNotes/2.43.5.adoc diff --git a/Documentation/RelNotes/2.43.6.adoc b/Documentation/RelNotes/2.43.6.adoc new file mode 100644 index 00000000000000..2114b9f78d3b20 --- /dev/null +++ b/Documentation/RelNotes/2.43.6.adoc @@ -0,0 +1,7 @@ +Git v2.43.6 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4, v2.41.3 +and v2.42.4 to address the security issues CVE-2024-50349 and +CVE-2024-52006; see the release notes for these versions for +details. diff --git a/Documentation/RelNotes/2.44.0.txt b/Documentation/RelNotes/2.44.0.adoc similarity index 100% rename from Documentation/RelNotes/2.44.0.txt rename to Documentation/RelNotes/2.44.0.adoc diff --git a/Documentation/RelNotes/2.44.1.txt b/Documentation/RelNotes/2.44.1.adoc similarity index 100% rename from Documentation/RelNotes/2.44.1.txt rename to Documentation/RelNotes/2.44.1.adoc diff --git a/Documentation/RelNotes/2.44.2.txt b/Documentation/RelNotes/2.44.2.adoc similarity index 100% rename from Documentation/RelNotes/2.44.2.txt rename to Documentation/RelNotes/2.44.2.adoc diff --git a/Documentation/RelNotes/2.44.3.adoc b/Documentation/RelNotes/2.44.3.adoc new file mode 100644 index 00000000000000..58628454583da9 --- /dev/null +++ b/Documentation/RelNotes/2.44.3.adoc @@ -0,0 +1,7 @@ +Git v2.44.3 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4, v2.41.3, +v2.42.4 and v2.43.6 to address the security issues CVE-2024-50349 +and CVE-2024-52006; see the release notes for these versions +for details. diff --git a/Documentation/RelNotes/2.45.0.txt b/Documentation/RelNotes/2.45.0.adoc similarity index 99% rename from Documentation/RelNotes/2.45.0.txt rename to Documentation/RelNotes/2.45.0.adoc index fec193679f7048..aa0315259b7fa1 100644 --- a/Documentation/RelNotes/2.45.0.txt +++ b/Documentation/RelNotes/2.45.0.adoc @@ -9,7 +9,7 @@ UI, Workflows & Features 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 + * "git checkout -p" and friends learned that "@" is a synonym for "HEAD". * Variants of vimdiff learned to honor mergetool.<variant>.layout diff --git a/Documentation/RelNotes/2.45.1.txt b/Documentation/RelNotes/2.45.1.adoc similarity index 100% rename from Documentation/RelNotes/2.45.1.txt rename to Documentation/RelNotes/2.45.1.adoc diff --git a/Documentation/RelNotes/2.45.2.txt b/Documentation/RelNotes/2.45.2.adoc similarity index 100% rename from Documentation/RelNotes/2.45.2.txt rename to Documentation/RelNotes/2.45.2.adoc diff --git a/Documentation/RelNotes/2.45.3.txt b/Documentation/RelNotes/2.45.3.adoc similarity index 93% rename from Documentation/RelNotes/2.45.3.txt rename to Documentation/RelNotes/2.45.3.adoc index 2a1e9aa60879aa..ddb3cb694b518e 100644 --- a/Documentation/RelNotes/2.45.3.txt +++ b/Documentation/RelNotes/2.45.3.adoc @@ -1,7 +1,12 @@ Git v2.45.3 Release Notes ========================= -This primarily is to backport various small fixes accumulated on the +This release merges up the fix that appears in v2.40.4, v2.41.3, +v2.42.4, v2.43.6 and v2.44.3 to address the security issues +CVE-2024-50349 and CVE-2024-52006; see the release notes for +these versions for details. + +This version also backports various small fixes accumulated on the 'master' front during the development towards Git 2.46, the next feature release. diff --git a/Documentation/RelNotes/2.46.0.txt b/Documentation/RelNotes/2.46.0.adoc similarity index 99% rename from Documentation/RelNotes/2.46.0.txt rename to Documentation/RelNotes/2.46.0.adoc index b25475918a08c7..c06a04a91bced8 100644 --- a/Documentation/RelNotes/2.46.0.txt +++ b/Documentation/RelNotes/2.46.0.adoc @@ -78,7 +78,7 @@ UI, Workflows & Features turn on cover letters automatically (unless told never to enable cover letter with "--no-cover-letter" and such). - * The "--heads" option of "ls-remote" and "show-ref" has been been + * The "--heads" option of "ls-remote" and "show-ref" has been deprecated; "--branches" replaces "--heads". * For over a year, setting add.interactive.useBuiltin configuration diff --git a/Documentation/RelNotes/2.46.1.txt b/Documentation/RelNotes/2.46.1.adoc similarity index 100% rename from Documentation/RelNotes/2.46.1.txt rename to Documentation/RelNotes/2.46.1.adoc diff --git a/Documentation/RelNotes/2.46.2.txt b/Documentation/RelNotes/2.46.2.adoc similarity index 100% rename from Documentation/RelNotes/2.46.2.txt rename to Documentation/RelNotes/2.46.2.adoc diff --git a/Documentation/RelNotes/2.46.3.adoc b/Documentation/RelNotes/2.46.3.adoc new file mode 100644 index 00000000000000..4af032b63c7053 --- /dev/null +++ b/Documentation/RelNotes/2.46.3.adoc @@ -0,0 +1,6 @@ +Git v2.46.3 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4, v2.41.3, v2.42.4, +v2.43.6, v2.44.3 and v2.45.3 to address the security issues CVE-2024-50349 and +CVE-2024-52006; see the release notes for these versions for details. diff --git a/Documentation/RelNotes/2.47.0.txt b/Documentation/RelNotes/2.47.0.adoc similarity index 94% rename from Documentation/RelNotes/2.47.0.txt rename to Documentation/RelNotes/2.47.0.adoc index fbbea257a9bcc2..b63c3364af5088 100644 --- a/Documentation/RelNotes/2.47.0.txt +++ b/Documentation/RelNotes/2.47.0.adoc @@ -162,6 +162,11 @@ Performance, Internal Implementation, Development Support etc. * Give timeout to the locking code to write to reftable, instead of failing on the first failure without retrying. + * The checksum at the tail of files are now computed without + collision detection protection. This is safe as the consumer of + the information to protect itself from replay attacks checks for + hash collisions independently. + Fixes since v2.46 ----------------- @@ -317,6 +322,15 @@ Fixes since v2.46 wasn't in any repository while processing includeIf.onbranch configuration and instead crashed. + * When "git sparse-checkout disable" turns a sparse checkout into a + regular checkout, the index is fully expanded. This totally + expected behaviour however had an "oops, we are expanding the + index" advice message, which has been corrected. + (merge 537e516a39 ds/sparse-checkout-expansion-advice later to maint). + + * macOS with fsmonitor daemon can hang forever when a submodule is + involved, which has been corrected. + * Other code cleanup, docfix, build fix, etc. (merge be10ac7037 jc/mailinfo-header-cleanup later to maint). (merge 4460e052e0 jc/range-diff-lazy-setup later to maint). @@ -324,3 +338,5 @@ Fixes since v2.46 (merge 83799f1500 jk/t9001-deflake later to maint). (merge e02cc08a88 ak/typofix-2.46-maint later to maint). (merge 5c5d29e1c4 ps/ci-gitlab-upgrade later to maint). + (merge 9c4c840901 jc/doc-discarding-stalled-topics later to maint). + (merge 5e6f359f6b ds/read-cache-mempool-leakfix later to maint). diff --git a/Documentation/RelNotes/2.47.1.adoc b/Documentation/RelNotes/2.47.1.adoc new file mode 100644 index 00000000000000..39206c09fdbe62 --- /dev/null +++ b/Documentation/RelNotes/2.47.1.adoc @@ -0,0 +1,31 @@ +Git 2.47.1 Release Notes +======================== + +This is to flush accumulated fixes since 2.47.0 on the 'master' +front down to the maintenance track. + + +Fixes since Git 2.47 +-------------------- + + * Use after free and double freeing at the end in "git log -L... -p" + had been identified and fixed. + + * On macOS, fsmonitor can fall into a race condition that results in + a client waiting forever to be notified for an event that have + already happened. This problem has been corrected. + + * "git maintenance start" crashed due to an uninitialized variable + reference, which has been corrected. + + * Fail gracefully instead of crashing when attempting to write the + contents of a corrupt in-core index as a tree object. + + * A "git fetch" from the superproject going down to a submodule used + a wrong remote when the default remote names are set differently + between them. + + * The "gitk" project tree has been synchronized again with its new + maintainer, Johannes Sixt. + +Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.47.2.adoc b/Documentation/RelNotes/2.47.2.adoc new file mode 100644 index 00000000000000..7a52ad8cb44a69 --- /dev/null +++ b/Documentation/RelNotes/2.47.2.adoc @@ -0,0 +1,7 @@ +Git v2.47.2 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4, v2.41.3, +v2.42.4, v2.43.6, v2.44.3, v2.45.3 and v2.46.3 to address the +security issues CVE-2024-50349 and CVE-2024-52006; see the release +notes for these versions for details. diff --git a/Documentation/RelNotes/2.48.0.adoc b/Documentation/RelNotes/2.48.0.adoc new file mode 100644 index 00000000000000..eff93be37a2269 --- /dev/null +++ b/Documentation/RelNotes/2.48.0.adoc @@ -0,0 +1,330 @@ +Git v2.48 Release Notes +======================= + +UI, Workflows & Features +------------------------ + + * A new configuration variable remote.<name>.serverOption makes the + transport layer act as if the --serverOption=<value> option is + given from the command line. + + * "git rebase --rebase-merges" now uses branch names as labels when + able. + + * Describe the policy to introduce breaking changes. + + * Teach 'git notes add' and 'git notes append' a new '-e' flag, + instructing them to open the note in $GIT_EDITOR before saving. + + * Documentation for "git bundle" saw improvements to more prominently + call out the use of '--all' when creating bundles. + + * Drop support for older libcURL and Perl. + + * End-user experience of "git mergetool" when the command errors out + has been improved. + + * "git bundle --unbundle" and "git clone" running on a bundle file + both learned to trigger fsck over the new objects with configurable + fck check levels. + + * When "git fetch $remote" notices that refs/remotes/$remote/HEAD is + missing and discovers what branch the other side points with its + HEAD, refs/remotes/$remote/HEAD is updated to point to it. + + * "git fetch" honors "remote.<remote>.followRemoteHEAD" settings to + tweak the remote-tracking HEAD in "refs/remotes/<remote>/HEAD". + + * "git range-diff" learned to optionally show and compare merge + commits in the ranges being compared, with the --diff-merges + option. + + +Performance, Internal Implementation, Development Support etc. +-------------------------------------------------------------- + + * Document "amlog" notes. + + * The way AsciiDoc is used for SYNOPSIS part of the manual pages has + been revamped. The sources, at least for the simple cases, got + vastly more pleasant to work with. + + * The reftable library is now prepared to expect that the memory + allocation function given to it may fail to allocate and to deal + with such an error. + + * An extra worktree attached to a repository points at each other to + allow finding the repository from the worktree (and vice versa) + possible. Use relative paths for this linkage. + + * Enable Windows-based CI in GitLab. + + * Commands that can also work outside Git have learned to take the + repository instance "repo" when we know we are in a repository, and + NULL when we are not, in a parameter. The uses of the_repository + variable in a few of them have been removed using the new calling + convention. + + * The reftable sub-system grew a new reftable-specific strbuf + replacement to reduce its dependency on Git-specific data + structures. + + * The ref-filter machinery learns to recognize and avoid cases where + sorting would be redundant. + + * Various platform compatibility fixes split out of the larger effort + to use Meson as the primary build tool. + + * Treat ECONNABORTED the same as ECONNRESET in 'git credential-cache' + to work around a possible Cygwin regression. This resolves a race + condition caused by changes in Cygwin's handling of socket + closures, allowing the client to exit cleanly when encountering + ECONNABORTED. + + * Demonstrate an assertion failure in 'git mv'. + + * Documentation update to clarify that 'uploadpack.allowAnySHA1InWant' + implies both 'allowTipSHA1InWant' and 'allowReachableSHA1InWant'. + + * Replace various calls to atoi() with strtol_i() and strtoul_ui(), + and add improved error handling. + + * Documentation updates to 'git-update-ref(1)'. + + * Update the project's CodingGuidelines to discourage naming functions + with a "_1()" suffix. + + * Update '.clang-format' to match project conventions. + + * Centralize documentation for repository extensions into a single place. + + * Buildfix and upgrade of Clar to a newer version. + + * Documentation mark-up updates. + + * Renaming a handful of variables and structure fields. + + * Fix for clar unit tests to support CMake build. + + * C23 compatibility updates. + + * GCC 15 compatibility updates. + + * We now ensure "index-pack" is used with the "--promisor" option + only during a "git fetch". + + * The migration procedure between two ref backends has been optimized. + + * "git fsck" learned to issue warnings on "curiously formatted" ref + contents that have always been treated as valid but that Git + wouldn't have written itself (e.g., missing terminating end-of-line + after the full object name). + + * Work around Coverity warning that would not trigger in practice. + + * Built-in Git subcommands are supplied the repository object to work + with; they learned to do the same when they invoke sub-subcommands. + + * Drop support for ancient environments in various CI jobs. + + * Isolate the reftable subsystem from the rest of Git's codebase by + using fewer pieces of Git's infrastructure. + + * Optimize reading random references out of the reftable backend by + allowing reuse of iterator objects. + + * Backport oss-fuzz tests to our codebase. + + * Introduce a new repository extension to prevent older Git versions + from mis-interpreting worktrees created with relative paths. + + * Yet another "pass the repository through the callchain" topic. + + * "git describe" learned to stop digging the history needlessly + deeper. + + * Build procedure update plus introduction of Meson based builds. + + * Recent reftable updates mistook a NULL return from a request for + 0-byte allocation as OOM and died unnecessarily, which has been + corrected. + + * Reftable backend adds check for upper limit of log's update_index. + + * Start working to make the codebase buildable with -Wsign-compare. + + * Regression fix for 'show-index' when run outside of a repository. + + * The meson-build procedure is integrated into CI to catch and + prevent bitrotting. + + * "git refs migrate" learned to also migrate the reflog data across + backends. + + * The developer documentation has been updated to give the latest + info on gitk and git-gui maintainer. + + + * CI jobs that run threaded programs under LSan has been giving false + positives from time to time, which has been worked around. + + +Fixes since v2.47 +----------------- + + * Doc update to clarify how periodical maintenance are scheduled, + spread across time to avoid thundering herds. + + * Use after free and double freeing at the end in "git log -L... -p" + had been identified and fixed. + + * On macOS, fsmonitor can fall into a race condition that results in + a client waiting forever to be notified about an event that has + already happened. This problem has been corrected. + + * "git maintenance start" crashed due to an uninitialized variable + reference, which has been corrected. + + * Fail gracefully instead of crashing when attempting to write the + contents of a corrupt in-core index as a tree object. + + * A "git fetch" from the superproject going down to a submodule used + a wrong remote when the default remote names are set differently + between them. + + * Fixes compile time warnings with 64-bit MSVC. + + * Teaches 'shortlog' to explicitly use SHA-1 when operating outside + of a repository. + + * Fix 'git grep' regression on macOS by disabling lookahead when + encountering invalid UTF-8 byte sequences. + + * The dumb-http code regressed when the result of re-indexing a pack + yielded an *.idx file that differs in content from the *.idx file + it downloaded from the remote. This has been corrected by no longer + relying on the *.idx file we got from the remote. + + * When called with '--left-right' and '--use-bitmap-index', 'rev-list' + will produce output without any left/right markers, which has been + corrected. + + * More leakfixes. + + * Test modernization. + + * The "--shallow-exclude=<ref>" option to various history transfer + commands takes a ref, not an arbitrary revision. + + * A regression where commit objects missing from a commit-graph can + cause an infinite loop when doing a fetch in a partial clone has + been fixed. + + * The MinGW compatibility layer has been taught to support POSIX + semantics for atomic renames when other process(es) have a file + opened at the destination path. + + * "git gc" discards any objects that are outside promisor packs that + are referred to by an object in a promisor pack, and we do not + refetch them from the promisor at runtime, resulting an unusable + repository. Work around it by including these objects in the + referring promisor pack at the receiving end of the fetch. + + * Avoid build/test breakage on a system without working malloc debug + support dynamic library. + (merge 72ad6dc368 jk/test-malloc-debug-check later to maint). + + * Double-free fix. + (merge fe17a25905 jk/fetch-prefetch-double-free-fix later to maint). + + * Use of some uninitialized variables in "git difftool" has been + corrected. + + * Object reuse code based on multi-pack-index sent an unwanted copy + of object. + (merge e199290592 tb/multi-pack-reuse-dupfix later to maint). + + * "git fast-import" can be tricked into a replace ref that maps an + object to itself, which is a useless thing to do. + (merge 5e904f1a4a en/fast-import-avoid-self-replace later to maint). + + * The ref-transaction hook triggered for reflog updates, which has + been corrected. + (merge b886db48c6 kn/ref-transaction-hook-with-reflog later to maint). + + * Give a bit of advice/hint message when "git maintenance" stops finding a + lock file left by another instance that still is potentially running. + (merge ba874d1dac ps/gc-stale-lock-warning later to maint). + + * Use the right helper program to measure file size in performance tests. + (merge 3f97f1bce6 tb/use-test-file-size-more later to maint). + + * A double-free that may not trigger in practice by luck has been + corrected in the reference resolution code. + (merge b6318cf23a sj/refs-symref-referent-fix later to maint). + + * The sequencer failed to honor core.commentString in some places. + + * Describe a case where an option value needs to be spelled as a + separate argument, i.e. "--opt val", not "--opt=val". + (merge 1bc1e94091 jc/doc-opt-tilde-expand later to maint). + + * Loosen overly strict ownership check introduced in the recent past, + to keep the promise "cloning a suspicious repository is a safe + first step to inspect it". + (merge 0ffb5a6bf1 bc/allow-upload-pack-from-other-people later to maint). + + * "git fast-import" learned to reject paths with ".." and "." as + their components to avoid creating invalid tree objects. + (merge 8cb4c6e62f en/fast-import-verify-path later to maint). + + * The --ancestry-path option is designed to be given a commit that is + on the path, which was not documented, which has been corrected. + (merge bc1a980759 kk/doc-ancestry-path later to maint). + + * "git tag" has been taught to refuse to create refs/tags/HEAD + since such a tag will be confusing in the context of the UI provided by + the Git Porcelain commands. + (merge bbd445d5ef jc/forbid-head-as-tagname later to maint). + + * The advice messages now tell the newer 'git config set' command to + set the advice.token configuration variable to squelch a message. + (merge 6c397d0104 bf/explicit-config-set-in-advice-messages later to maint). + + * The syntax ":/<text>" to name the latest commit with the matching + text was broken with a recent change, which has been corrected. + (merge 0ff919e87a ps/commit-with-message-syntax-fix later to maint). + + * Fix performance regression of a recent "fatten promisor pack with + local objects" protection against an unwanted gc. + + * "git log -p --remerge-diff --reverse" was completely broken. + (merge f94bfa1516 js/log-remerge-keep-ancestry later to maint). + + * "git bundle create" with an annotated tag on the positive end of + the revision range had a workaround code for older limitation in + the revision walker, which has become unnecessary. + (merge dd1072dfa8 tc/bundle-with-tag-remove-workaround later to maint). + + * GitLab CI updates. + (merge c6b43f663e ps/ci-gitlab-update later to maint). + + * Code to reuse objects based on bitmap contents have been tightened + to avoid race condition even when multiple packs are involved. + (merge 62b3ec8a3f tb/bitmap-fix-pack-reuse later to maint). + + * An earlier "csum-file checksum does not have to be computed with + sha1dc" topic had a few code paths that had initialized an + implementation of a hash function to be used by an unmatching hash + by mistake, which have been corrected. + (merge 599a63409b ps/weak-sha1-for-tail-sum-fix later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 77af53f56f aa/t7300-modernize later to maint). + (merge dcd590a39d bf/t-readme-mention-reftable later to maint). + (merge 68e3c69efa kh/trailer-in-glossary later to maint). + (merge 91f88f76e6 tb/boundary-traversal-fix later to maint). + (merge 168ebb7159 jc/doc-error-message-guidelines later to maint). + (merge 18693d7d65 kh/doc-bundle-typofix later to maint). + (merge e2f5d3b491 kh/doc-update-ref-grammofix later to maint). + (merge 8525e92886 mh/doc-windows-home-env later to maint). diff --git a/Documentation/RelNotes/2.48.1.adoc b/Documentation/RelNotes/2.48.1.adoc new file mode 100644 index 00000000000000..26c59b6e3bf31c --- /dev/null +++ b/Documentation/RelNotes/2.48.1.adoc @@ -0,0 +1,7 @@ +Git v2.48.1 Release Notes +========================= + +This release merges up the fix that appears in v2.40.4, v2.41.3, +v2.42.4, v2.43.6, v2.44.3, v2.45.3, v2.46.3, and v2.47.2 to address +the security issues CVE-2024-50349 and CVE-2024-52006; see the release +notes for these versions for details. diff --git a/Documentation/RelNotes/2.49.0.adoc b/Documentation/RelNotes/2.49.0.adoc new file mode 100644 index 00000000000000..494c83096fae8d --- /dev/null +++ b/Documentation/RelNotes/2.49.0.adoc @@ -0,0 +1,288 @@ +Git v2.49 Release Notes +======================= + +UI, Workflows & Features +------------------------ + + * Completion script updates for zsh + + * "git pack-objects" and its wrapper "git repack" learned an option + to use an alternative path-hash function to improve delta-base + selection to produce a packfile with deeper history than window + size. + + * "git gc" learned the "--expire-to" option and passes it down to + underlying "git repack". + + * "[help] autocorrect = 1" used to be a way to say "please wait for + 0.1 second after suggesting a typofix of the command name before + running that command"; now it means "yes, if there is a plausible + typofix for the command name, please run it immediately". + + * "git clone" learned to make a shallow clone for a single commit + that is not necessarily be at the tip of any branch. + + * Lazy-loading missing files in a blobless clone on demand is costly + as it tends to be one-blob-at-a-time. "git backfill" is introduced + to help bulk-download necessary files beforehand. + + * "git push --atomic --porcelain" used to ignore failures from the + other side, losing the error status from the child process, which + has been corrected. + + * "git rev-list --missing=" learned to accept "print-info" that gives + known details expected of the missing objects, like path and type. + + * Comes with an updated "gitk". + + * The documentation of "git commit" and "git rebase" now refer to + commit titles as such, not "subject". + + * The value of "uname -s" is by default sent over the wire as a part + of the "version" capability. + + * "git refs migrate" can optionally be told not to migrate the reflog. + + * The netrc support (via the cURL library) for the HTTP transport has + been re-enabled. + + * Removal of ".git/branches" and ".git/remotes" support in the + BreakingChanges document has been further clarified. + + * What happens to submodules during merge has been documented in a + bit more detail. + + +Performance, Internal Implementation, Development Support etc. +-------------------------------------------------------------- + + * More -Wsign-compare fixes. + + * meson-based build now supports the unsafe-sha1 build knob. + + * The meson-based build procedure covers contrib/ and other places as + well. + + * The code to check LSan results has been simplified and made more + robust. + (merge 164a2516eb jk/lsan-race-ignore-false-positive later to maint). + + * More code paths have a repository passed through the callchain, + instead of assuming the primary the_repository object. + + * Move a few more unit tests to the clar test framework. + + * Introduce a new API to visit objects in batches based on a common + path, or by type. + + * Following the procedure we established to introduce breaking + changes for Git 3.0, allow an early opt-in for removing support of + $GIT_DIR/branches/ and $GIT_DIR/remotes/ directories to configure + remotes. + + * The code paths to interact with zlib has been cleaned up in + preparation for building with zlib-ng. + + * Foreign language interface for Rust into our code base has been added. + + * All the documentation .txt files have been renamed to .adoc to help + content aware editors. + + * "git difftool" code clean-up. + + * Rename processing in the recursive merge backend has seen a micro + optimization. + + * The path.[ch] API takes an explicit repository parameter passed + throughout the callchain, instead of relying on the_repository + singleton instance. + + * Large-object promisor protocol extension has been introduced. + + * The editorconfig file is updated to tell us that bash scripts are + similar to general Bourne shell scripts. + + * Meson-based build procedure forgot to build some docs, which has + been corrected. + + +Fixes since v2.48 +----------------- + + * "git submodule" learned various ways to spell the same option, + e.g. "--branch=B" can be spelled "--branch B" or "-bB". + (merge b86f0f9071 re/submodule-parse-opt later to maint). + + * Tweak the help text used for the option value placeholders by + parse-options API so that translations can customize the "<>" + placeholder signal (e.g. "--option=<value>"). + (merge 5b34dd08d0 as/long-option-help-i18n later to maint). + + * CI jobs gave sporadic failures, which turns out that that the + object finalization code was giving an error when it did not have + to. + (merge d7fcbe2c56 ps/object-collision-check later to maint). + + * The code to compute "unique" name used git_rand() which can fail or + get stuck; the callsite does not require cryptographic security. + Introduce the "insecure" mode and use it appropriately. + (merge 0b4f8afef6 ps/reftable-get-random-fix later to maint). + + * A misconfigured "fsck.skiplist" configuration variable was not + diagnosed as an error, which has been corrected. + (merge ca7158076f jt/fsck-skiplist-parse-fix later to maint). + + * Extended SHA-1 expression parser did not work well when a branch + with an unusual name (e.g. "foo{bar") is involved. + (merge 191f0c8db2 en/object-name-with-funny-refname-fix later to maint). + + * The meson build procedure looked for the 'version-def.h' file in a + wrong directory, which has been corrected. + (merge 4771501c0a tc/meson-use-our-version-def-h later to maint). + + * The meson build procedure for Documentation/technical/ hierarchy was + missing necessary dependencies, which has been corrected. + (merge 1dca492edd sj/meson-doc-technical-dependency-fix later to maint). + + * The "instaweb" bound only to local IP address without "--local" and + to all addresses with "--local", which was the other way around, when + using Python's http.server class, which has been corrected. + (merge 76baf97fa1 ak/instaweb-python-port-binding-fix later to maint). + + * Document that it is insecure to use Personal Access Tokens, which + some hosting providers take as username/password, embedded in URLs. + (merge a90ff409f0 mh/doc-credential-helpers-with-pat later to maint). + + * The help text from "git $cmd -h" appear on the standard output for + some $cmd and the standard error for others. The built-in commands + have been fixed to show them on the standard output consistently. + (merge f66d1423f5 jc/show-usage-help later to maint). + + * The meson-driven build is now aware of "git-subtree" housed in + contrib/subtree hierarchy. + (merge 8454b42f94 ps/build-meson-subtree later to maint). + + * It was possible for "git unpack-objects" and "git index-pack" to + make an unaligned access, which has been corrected. + (merge 98046591b9 jk/pack-header-parse-alignment-fix later to maint). + + * The "cache" credential back-end did not handle authtype correctly, + which has been corrected. + (merge 0b43274850 mh/credential-cache-authtype-request-fix later to maint). + + * "git branch --sort=..." and "git for-each-ref --format=... --sort=..." + did not work as expected with some atoms, which has been corrected. + (merge c5490ce9d1 rs/ref-fitler-used-atoms-value-fix later to maint). + + * reflog entries for symbolic ref updates were broken, which has been + corrected. + (merge 3519492430 kn/reflog-symref-fix later to maint). + + * The trace2 code was not prepared to show a configuration variable + that is set to true using the valueless true syntax, which has been + corrected. + (merge 2fd367cf63 am/trace2-with-valueless-true later to maint). + + * The "git refs migrate" command did not migrate the reflog for + refs/stash, which is the contents of the stashes, which has been + corrected. + (merge a0bea0978f ps/reflog-migration-with-logall-fix later to maint). + + * Doc and short-help text for "show-index" has been clarified to + stress that the command reads its data from the standard input. + (merge 49edce4ff9 jc/show-index-h-update later to maint). + + * The API around choosing to use unsafe variant of SHA-1 + implementation has been updated in an attempt to make it harder to + abuse. + (merge 04292c3796 tb/unsafe-hash-cleanup later to maint). + + * Fix bugs in an earlier attempt to fix "git refs migration". + (merge f11f0a5a2d kn/reflog-migration-fix-fix later to maint). + + * The code path used when "git fetch" fetches from a bundle file + closed the same file descriptor twice, which sometimes broke things + unexpectedly when the file descriptor was reused, which has been + corrected. + (merge 9a84794ad8 js/bundle-unbundle-fd-reuse-fix later to maint). + + * "git init" to reinitialize a repository that already exists cannot + change the hash function and ref backends; such a request is + silently ignored now. + (merge 7e88640cd1 ps/setup-reinit-fixes later to maint). + + * "git apply" internally uses unsigned long for line numbers and uses + strtoul() to parse numbers on the hunk headers. It however forgot + to check parse errors. + (merge a206058fda pw/apply-ulong-overflow-check later to maint). + + * Two CI tasks, whitespace check and style check, work on the + difference from the base version and the version being checked, but + the base was computed incorrectly in GitLab CI in some cases, which + has been corrected. + (merge acc4fb302b jt/gitlab-ci-base-fix later to maint). + + * "git repack --keep-unreachable" to send unreachable objects to the + main pack "git repack -ad" produces did not work when there is no + existing packs, which has been corrected. + (merge 414c82300a ps/repack-keep-unreachable-in-unpacked-repo later to maint). + + * Going into a secondary worktree and asking "is the main worktree + bare?" did not work correctly when per-worktree configuration + option was in use, which has been corrected. + + * Fetching into a bare repository incorrectly assumed it always used + a mirror layout when deciding to update remote-tracking HEAD, which + has been corrected. + (merge 93dc16483a bf/fetch-set-head-fix later to maint). + + * A thunderbird helper script lost its bashism. + (merge 59d26bd961 bc/contrib-thunderbird-patch-inline-fix later to maint). + + * The -G/-S options to the "diff" family of commands caused us to hit + a BUG() when they get no values; they have been corrected. + (merge a620046b29 bc/diff-reject-empty-arg-to-pickaxe later to maint). + + * "git merge-tree --stdin" has been improved (including a workaround + for a deadlock). + (merge 6a9ae81015 pw/merge-tree-stdin-deadlock-fix later to maint). + + * Correct the default target in Documentation/Makefile, and + future-proof all Makefiles from similar breakages by declaring the + default target (which happens to be "all") upfront. + (merge 5309c1e9fb ad/set-default-target-in-makefiles later to maint). + + * "git check-mailmap" used to segfault when queried without human + readable name. + (merge bb60c52131 jk/check-mailmap-wo-name-fix later to maint). + + * Support for renaming of symbolic links on Windows has been improved. + + * "git rebase -i" failed to allow rewording an empty commit that has + been fast-forwarded. + (merge af8fc7be10 pw/rebase-i-ff-empty-commit later to maint). + + * The use of "paste" command for aggregating the test results have + been corrected. + (merge ce98863204 dk/test-aggregate-results-paste-fix later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge ddb5287894 jk/t7407-use-test-grep later to maint). + (merge 21e1b44865 aj/difftool-config-doc-fix later to maint). + (merge 6a63995335 mh/gitattr-doc-markup-fix later to maint). + (merge 43850dcf9c sk/unit-test-hash later to maint). + (merge 4ad47d2de3 jc/cli-doc-option-and-config later to maint). + (merge 2d0ff147e5 jp/t8002-printf-fix later to maint). + (merge 69666e6746 ja/doc-restore-markup-update later to maint). + (merge d11d003ba5 sk/strlen-returns-size_t later to maint). + (merge 77b2d29e91 ja/doc-notes-markup-updates later to maint). + (merge 6979bf6f8f jk/combine-diff-cleanup later to maint). + (merge 8705c9bd13 kn/pack-write-with-reduced-globals later to maint). + (merge 087740d65a ps/leakfixes-0129 later to maint). + (merge 6bba6f604b jp/doc-trailer-config later to maint). + (merge f1cc562b77 lo/t7603-path-is-file-update later to maint). + (merge 45761988ac en/doc-renormalize later to maint). + (merge 832f56f06a jc/doc-boolean-synonyms later to maint). + (merge 3eeed876a9 ac/doc-http-ssl-type-config later to maint). + (merge c268e3285d jc/breaking-changes-early-adopter-option later to maint). + (merge 0d03fda6a5 pb/doc-follow-remote-head later to maint). diff --git a/Documentation/RelNotes/2.5.0.txt b/Documentation/RelNotes/2.5.0.adoc similarity index 100% rename from Documentation/RelNotes/2.5.0.txt rename to Documentation/RelNotes/2.5.0.adoc diff --git a/Documentation/RelNotes/2.5.1.txt b/Documentation/RelNotes/2.5.1.adoc similarity index 100% rename from Documentation/RelNotes/2.5.1.txt rename to Documentation/RelNotes/2.5.1.adoc diff --git a/Documentation/RelNotes/2.5.2.txt b/Documentation/RelNotes/2.5.2.adoc similarity index 100% rename from Documentation/RelNotes/2.5.2.txt rename to Documentation/RelNotes/2.5.2.adoc diff --git a/Documentation/RelNotes/2.5.3.txt b/Documentation/RelNotes/2.5.3.adoc similarity index 100% rename from Documentation/RelNotes/2.5.3.txt rename to Documentation/RelNotes/2.5.3.adoc diff --git a/Documentation/RelNotes/2.5.4.txt b/Documentation/RelNotes/2.5.4.adoc similarity index 100% rename from Documentation/RelNotes/2.5.4.txt rename to Documentation/RelNotes/2.5.4.adoc diff --git a/Documentation/RelNotes/2.5.5.txt b/Documentation/RelNotes/2.5.5.adoc similarity index 100% rename from Documentation/RelNotes/2.5.5.txt rename to Documentation/RelNotes/2.5.5.adoc diff --git a/Documentation/RelNotes/2.5.6.txt b/Documentation/RelNotes/2.5.6.adoc similarity index 100% rename from Documentation/RelNotes/2.5.6.txt rename to Documentation/RelNotes/2.5.6.adoc diff --git a/Documentation/RelNotes/2.6.0.txt b/Documentation/RelNotes/2.6.0.adoc similarity index 100% rename from Documentation/RelNotes/2.6.0.txt rename to Documentation/RelNotes/2.6.0.adoc diff --git a/Documentation/RelNotes/2.6.1.txt b/Documentation/RelNotes/2.6.1.adoc similarity index 100% rename from Documentation/RelNotes/2.6.1.txt rename to Documentation/RelNotes/2.6.1.adoc diff --git a/Documentation/RelNotes/2.6.2.txt b/Documentation/RelNotes/2.6.2.adoc similarity index 100% rename from Documentation/RelNotes/2.6.2.txt rename to Documentation/RelNotes/2.6.2.adoc diff --git a/Documentation/RelNotes/2.6.3.txt b/Documentation/RelNotes/2.6.3.adoc similarity index 100% rename from Documentation/RelNotes/2.6.3.txt rename to Documentation/RelNotes/2.6.3.adoc diff --git a/Documentation/RelNotes/2.6.4.txt b/Documentation/RelNotes/2.6.4.adoc similarity index 100% rename from Documentation/RelNotes/2.6.4.txt rename to Documentation/RelNotes/2.6.4.adoc diff --git a/Documentation/RelNotes/2.6.5.txt b/Documentation/RelNotes/2.6.5.adoc similarity index 100% rename from Documentation/RelNotes/2.6.5.txt rename to Documentation/RelNotes/2.6.5.adoc diff --git a/Documentation/RelNotes/2.6.6.txt b/Documentation/RelNotes/2.6.6.adoc similarity index 100% rename from Documentation/RelNotes/2.6.6.txt rename to Documentation/RelNotes/2.6.6.adoc diff --git a/Documentation/RelNotes/2.6.7.txt b/Documentation/RelNotes/2.6.7.adoc similarity index 100% rename from Documentation/RelNotes/2.6.7.txt rename to Documentation/RelNotes/2.6.7.adoc diff --git a/Documentation/RelNotes/2.7.0.txt b/Documentation/RelNotes/2.7.0.adoc similarity index 100% rename from Documentation/RelNotes/2.7.0.txt rename to Documentation/RelNotes/2.7.0.adoc diff --git a/Documentation/RelNotes/2.7.1.txt b/Documentation/RelNotes/2.7.1.adoc similarity index 100% rename from Documentation/RelNotes/2.7.1.txt rename to Documentation/RelNotes/2.7.1.adoc diff --git a/Documentation/RelNotes/2.7.2.txt b/Documentation/RelNotes/2.7.2.adoc similarity index 100% rename from Documentation/RelNotes/2.7.2.txt rename to Documentation/RelNotes/2.7.2.adoc diff --git a/Documentation/RelNotes/2.7.3.txt b/Documentation/RelNotes/2.7.3.adoc similarity index 100% rename from Documentation/RelNotes/2.7.3.txt rename to Documentation/RelNotes/2.7.3.adoc diff --git a/Documentation/RelNotes/2.7.4.txt b/Documentation/RelNotes/2.7.4.adoc similarity index 100% rename from Documentation/RelNotes/2.7.4.txt rename to Documentation/RelNotes/2.7.4.adoc diff --git a/Documentation/RelNotes/2.7.5.txt b/Documentation/RelNotes/2.7.5.adoc similarity index 100% rename from Documentation/RelNotes/2.7.5.txt rename to Documentation/RelNotes/2.7.5.adoc diff --git a/Documentation/RelNotes/2.7.6.txt b/Documentation/RelNotes/2.7.6.adoc similarity index 100% rename from Documentation/RelNotes/2.7.6.txt rename to Documentation/RelNotes/2.7.6.adoc diff --git a/Documentation/RelNotes/2.8.0.txt b/Documentation/RelNotes/2.8.0.adoc similarity index 100% rename from Documentation/RelNotes/2.8.0.txt rename to Documentation/RelNotes/2.8.0.adoc diff --git a/Documentation/RelNotes/2.8.1.txt b/Documentation/RelNotes/2.8.1.adoc similarity index 100% rename from Documentation/RelNotes/2.8.1.txt rename to Documentation/RelNotes/2.8.1.adoc diff --git a/Documentation/RelNotes/2.8.2.txt b/Documentation/RelNotes/2.8.2.adoc similarity index 100% rename from Documentation/RelNotes/2.8.2.txt rename to Documentation/RelNotes/2.8.2.adoc diff --git a/Documentation/RelNotes/2.8.3.txt b/Documentation/RelNotes/2.8.3.adoc similarity index 100% rename from Documentation/RelNotes/2.8.3.txt rename to Documentation/RelNotes/2.8.3.adoc diff --git a/Documentation/RelNotes/2.8.4.txt b/Documentation/RelNotes/2.8.4.adoc similarity index 100% rename from Documentation/RelNotes/2.8.4.txt rename to Documentation/RelNotes/2.8.4.adoc diff --git a/Documentation/RelNotes/2.8.5.txt b/Documentation/RelNotes/2.8.5.adoc similarity index 100% rename from Documentation/RelNotes/2.8.5.txt rename to Documentation/RelNotes/2.8.5.adoc diff --git a/Documentation/RelNotes/2.8.6.txt b/Documentation/RelNotes/2.8.6.adoc similarity index 100% rename from Documentation/RelNotes/2.8.6.txt rename to Documentation/RelNotes/2.8.6.adoc diff --git a/Documentation/RelNotes/2.9.0.txt b/Documentation/RelNotes/2.9.0.adoc similarity index 100% rename from Documentation/RelNotes/2.9.0.txt rename to Documentation/RelNotes/2.9.0.adoc diff --git a/Documentation/RelNotes/2.9.1.txt b/Documentation/RelNotes/2.9.1.adoc similarity index 100% rename from Documentation/RelNotes/2.9.1.txt rename to Documentation/RelNotes/2.9.1.adoc diff --git a/Documentation/RelNotes/2.9.2.txt b/Documentation/RelNotes/2.9.2.adoc similarity index 100% rename from Documentation/RelNotes/2.9.2.txt rename to Documentation/RelNotes/2.9.2.adoc diff --git a/Documentation/RelNotes/2.9.3.txt b/Documentation/RelNotes/2.9.3.adoc similarity index 100% rename from Documentation/RelNotes/2.9.3.txt rename to Documentation/RelNotes/2.9.3.adoc diff --git a/Documentation/RelNotes/2.9.4.txt b/Documentation/RelNotes/2.9.4.adoc similarity index 100% rename from Documentation/RelNotes/2.9.4.txt rename to Documentation/RelNotes/2.9.4.adoc diff --git a/Documentation/RelNotes/2.9.5.txt b/Documentation/RelNotes/2.9.5.adoc similarity index 100% rename from Documentation/RelNotes/2.9.5.txt rename to Documentation/RelNotes/2.9.5.adoc diff --git a/Documentation/ReviewingGuidelines.txt b/Documentation/ReviewingGuidelines.adoc similarity index 100% rename from Documentation/ReviewingGuidelines.txt rename to Documentation/ReviewingGuidelines.adoc diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index d8a8caa7916980..958e3cc3d54741 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -412,13 +412,13 @@ Also notice that a real name is used in the `Signed-off-by` trailer. Please don't hide your real name. [[commit-trailers]] -If you like, you can put extra tags at the end: +If you like, you can put extra trailers at the end: . `Reported-by:` is used to credit someone who found the bug that the patch attempts to fix. . `Acked-by:` says that the person who is more familiar with the area the patch attempts to modify liked the patch. -. `Reviewed-by:`, unlike the other tags, can only be offered by the +. `Reviewed-by:`, unlike the other trailers, can only be offered by the reviewers themselves when they are completely satisfied with the patch after a detailed analysis. . `Tested-by:` is used to indicate that the person applied the patch @@ -436,7 +436,7 @@ 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 +Only capitalize the very first letter of the trailer, i.e. favor "Signed-off-by" over "Signed-Off-By" and "Acked-by:" over "Acked-By". [[git-tools]] @@ -692,16 +692,17 @@ rebase when I receive your patches). Some parts of the system have dedicated maintainers with their own repositories. -- `git-gui/` comes from git-gui project, maintained by Johannes Sixt: +- `git-gui/` comes from the git-gui project, maintained by Johannes Sixt: https://github.com/j6t/git-gui -- `gitk-git/` comes from Paul Mackerras's gitk project: + Contibutions should go via the git mailing list. - git://git.ozlabs.org/~paulus/gitk +- `gitk-git/` comes from the gitk project, maintained by Johannes Sixt: - Those who are interested in improving gitk can volunteer to help Paul - maintain it, cf. <YntxL/fTplFm8lr6@cleo>. + https://github.com/j6t/gitk + + Contibutions should go via the git mailing list. - `po/` comes from the localization coordinator, Jiang Xin: diff --git a/Documentation/ToolsForGit.txt b/Documentation/ToolsForGit.adoc similarity index 100% rename from Documentation/ToolsForGit.txt rename to Documentation/ToolsForGit.adoc diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf deleted file mode 100644 index 60f76f43edab75..00000000000000 --- a/Documentation/asciidoc.conf +++ /dev/null @@ -1,59 +0,0 @@ -## linkgit: macro -# -# Usage: linkgit:command[manpage-section] -# -# Note, {0} is the manpage section, while {target} is the command. -# -# Show Git link as: <command>(<section>); if section is defined, else just show -# the command. - -[macros] -(?su)[\\]?(?P<name>linkgit):(?P<target>\S*?)\[(?P<attrlist>.*?)\]= - -[attributes] -asterisk=* -plus=+ -caret=^ -startsb=[ -endsb=] -backslash=\ -tilde=~ -apostrophe=' -backtick=` -litdd=-- - -ifdef::backend-docbook[] -[linkgit-inlinemacro] -{0%{target}} -{0#<citerefentry>} -{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>} -{0#</citerefentry>} -endif::backend-docbook[] - -ifdef::backend-docbook[] -ifdef::doctype-manpage[] -# The following two small workarounds insert a simple paragraph after screen -[listingblock] -<example><title>{title}</title> -<literallayout class="monospaced"> -| -</literallayout><simpara></simpara> -{title#}</example> - -[verseblock] -<formalpara{id? id="{id}"}><title>{title}</title><para> -{title%}<literallayout{id? id="{id}"}> -{title#}<literallayout> -| -</literallayout> -{title#}</para></formalpara> -{title%}<simpara></simpara> -endif::doctype-manpage[] -endif::backend-docbook[] - -ifdef::backend-xhtml11[] -[attributes] -git-relative-html-prefix= -[linkgit-inlinemacro] -<a href="{git-relative-html-prefix}{target}.html">{target}{0?({0})}</a> -endif::backend-xhtml11[] diff --git a/Documentation/asciidoc.conf.in b/Documentation/asciidoc.conf.in new file mode 100644 index 00000000000000..f2aef6cb79f47c --- /dev/null +++ b/Documentation/asciidoc.conf.in @@ -0,0 +1,92 @@ +## linkgit: macro +# +# Usage: linkgit:command[manpage-section] +# +# Note, {0} is the manpage section, while {target} is the command. +# +# Show Git link as: <command>(<section>); if section is defined, else just show +# the command. + +[macros] +(?su)[\\]?(?P<name>linkgit):(?P<target>\S*?)\[(?P<attrlist>.*?)\]= + +[attributes] +asterisk=* +plus=+ +caret=^ +startsb=[ +endsb=] +backslash=\ +tilde=~ +apostrophe=' +backtick=` +litdd=-- +manmanual=Git Manual +mansource=Git @GIT_VERSION@ +revdate=@GIT_DATE@ + +ifdef::doctype-book[] +[titles] + underlines="__","==","--","~~","^^" +endif::doctype-book[] + +ifdef::backend-docbook[] +[linkgit-inlinemacro] +ifndef::doctype-book[] +{0%{target}} +{0#<citerefentry>} +{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>} +{0#</citerefentry>} +endif::doctype-book[] +ifdef::doctype-book[] +<ulink url="{target}.html">{target}{0?({0})}</ulink> +endif::doctype-book[] + +[literal-inlinemacro] +{eval:re.sub(r'(<[-a-zA-Z0-9.]+>)', r'<emphasis>\1</emphasis>', re.sub(r'([\[\s|()>]|^|\]|>)(\.?([-a-zA-Z0-9:+=~@,\/_^\$]+\.?)+)',r'\1<literal>\2</literal>', re.sub(r'(\.\.\.?)([^\]$.])', r'<literal>\1</literal>\2', macros.passthroughs[int(attrs['passtext'][1:-1])] if attrs['passtext'][1:-1].isnumeric() else attrs['passtext'][1:-1])))} + +endif::backend-docbook[] + +ifdef::backend-docbook[] +ifdef::doctype-manpage[] +# The following two small workarounds insert a simple paragraph after screen +[listingblock] +<example><title>{title}</title> +<literallayout class="monospaced"> +| +</literallayout><simpara></simpara> +{title#}</example> + +[verseblock] +<formalpara{id? id="{id}"}><title>{title}</title><para> +{title%}<literallayout{id? id="{id}"}> +{title#}<literallayout> +| +</literallayout> +{title#}</para></formalpara> +{title%}<simpara></simpara> +endif::doctype-manpage[] +endif::backend-docbook[] + +ifdef::backend-xhtml11[] +[attributes] +git-relative-html-prefix= +[linkgit-inlinemacro] +<a href="{git-relative-html-prefix}{target}.html">{target}{0?({0})}</a> + +[literal-inlinemacro] +{eval:re.sub(r'(<[-a-zA-Z0-9.]+>)', r'<em>\1</em>', re.sub(r'([\[\s|()>]|^|\]|>)(\.?([-a-zA-Z0-9:+=~@,\/_^\$]+\.?)+)',r'\1<code>\2</code>', re.sub(r'(\.\.\.?)([^\]$.])', r'<code>\1</code>\2', macros.passthroughs[int(attrs['passtext'][1:-1])] if attrs['passtext'][1:-1].isnumeric() else attrs['passtext'][1:-1])))} + +endif::backend-xhtml11[] + +ifdef::backend-docbook[] +ifdef::doctype-manpage[] +[paradef-default] +synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.]\\+\\|…\\)!\\1<literal>\\2</literal>!g;s!<[-a-zA-Z0-9.]\\+>!<emphasis>\\0</emphasis>!g'" +endif::doctype-manpage[] +endif::backend-docbook[] + +ifdef::backend-xhtml11[] +[paradef-default] +synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.]\\+\\|…\\)!\\1<code>\\2</code>!g;s!<[-a-zA-Z0-9.]\\+>!<em>\\0</em>!g'" +endif::backend-xhtml11[] diff --git a/Documentation/asciidoctor-extensions.rb b/Documentation/asciidoctor-extensions.rb deleted file mode 100644 index d906a008039cf5..00000000000000 --- a/Documentation/asciidoctor-extensions.rb +++ /dev/null @@ -1,48 +0,0 @@ -require 'asciidoctor' -require 'asciidoctor/extensions' - -module Git - module Documentation - class LinkGitProcessor < Asciidoctor::Extensions::InlineMacroProcessor - use_dsl - - named :chrome - - def process(parent, target, attrs) - prefix = parent.document.attr('git-relative-html-prefix') - if parent.document.doctype == 'book' - "<ulink url=\"#{prefix}#{target}.html\">" \ - "#{target}(#{attrs[1]})</ulink>" - elsif parent.document.basebackend? 'html' - %(<a href="#{prefix}#{target}.html">#{target}(#{attrs[1]})</a>) - elsif parent.document.basebackend? 'docbook' - "<citerefentry>\n" \ - "<refentrytitle>#{target}</refentrytitle>" \ - "<manvolnum>#{attrs[1]}</manvolnum>\n" \ - "</citerefentry>" - end - end - end - - class DocumentPostProcessor < Asciidoctor::Extensions::Postprocessor - def process document, output - if document.basebackend? 'docbook' - mansource = document.attributes['mansource'] - manversion = document.attributes['manversion'] - manmanual = document.attributes['manmanual'] - new_tags = "" \ - "<refmiscinfo class=\"source\">#{mansource}</refmiscinfo>\n" \ - "<refmiscinfo class=\"version\">#{manversion}</refmiscinfo>\n" \ - "<refmiscinfo class=\"manual\">#{manmanual}</refmiscinfo>\n" - output = output.sub(/<\/refmeta>/, new_tags + "</refmeta>") - end - output - end - end - end -end - -Asciidoctor::Extensions.register do - inline_macro Git::Documentation::LinkGitProcessor, :linkgit - postprocessor Git::Documentation::DocumentPostProcessor -end diff --git a/Documentation/asciidoctor-extensions.rb.in b/Documentation/asciidoctor-extensions.rb.in new file mode 100644 index 00000000000000..2494f17a514d9d --- /dev/null +++ b/Documentation/asciidoctor-extensions.rb.in @@ -0,0 +1,134 @@ +require 'asciidoctor' +require 'asciidoctor/extensions' +require 'asciidoctor/converter/docbook5' +require 'asciidoctor/converter/html5' + +module Git + module Documentation + class LinkGitProcessor < Asciidoctor::Extensions::InlineMacroProcessor + use_dsl + + named :chrome + + def process(parent, target, attrs) + prefix = parent.document.attr('git-relative-html-prefix') + if parent.document.doctype == 'book' + "<ulink url=\"#{prefix}#{target}.html\">" \ + "#{target}(#{attrs[1]})</ulink>" + elsif parent.document.basebackend? 'html' + %(<a href="#{prefix}#{target}.html">#{target}(#{attrs[1]})</a>) + elsif parent.document.basebackend? 'docbook' + "<citerefentry>\n" \ + "<refentrytitle>#{target}</refentrytitle>" \ + "<manvolnum>#{attrs[1]}</manvolnum>\n" \ + "</citerefentry>" + end + end + end + + class DocumentPostProcessor < Asciidoctor::Extensions::Postprocessor + def process document, output + if document.basebackend? 'docbook' + output = output.sub(/<refmiscinfo class="source">.*?<\/refmiscinfo>/, "") + output = output.sub(/<refmiscinfo class="manual">.*?<\/refmiscinfo>/, "") + output = output.sub(/<date>.*?<\/date>/, "<date>@GIT_DATE@</date>") + new_tags = "" \ + "<refmiscinfo class=\"source\">Git @GIT_VERSION@</refmiscinfo>\n" \ + "<refmiscinfo class=\"manual\">Git Manual</refmiscinfo>\n" + output = output.sub(/<\/refmeta>/, new_tags + "</refmeta>") + end + output + end + end + + class SynopsisBlock < Asciidoctor::Extensions::BlockProcessor + + use_dsl + named :synopsis + parse_content_as :simple + + def process parent, reader, attrs + outlines = reader.lines.map do |l| + l.gsub(/(\.\.\.?)([^\]$.])/, '`\1`\2') + .gsub(%r{([\[\] |()>]|^)([-a-zA-Z0-9:+=~@,/_^\$]+)}, '\1{empty}`\2`{empty}') + .gsub(/(<[-a-zA-Z0-9.]+>)/, '__\\1__') + .gsub(']', ']{empty}') + end + create_block parent, :verse, outlines, attrs + end + end + + class GitDBConverter < Asciidoctor::Converter::DocBook5Converter + + extend Asciidoctor::Converter::Config + register_for 'docbook5' + + def convert_inline_quoted node + if (type = node.type) == :asciimath + # NOTE fop requires jeuclid to process mathml markup + asciimath_available? ? %(<inlineequation>#{(::AsciiMath.parse node.text).to_mathml 'mml:', 'xmlns:mml' => 'http://www.w3.org/1998/Math/MathML'}</inlineequation>) : %(<inlineequation><mathphrase><![CDATA[#{node.text}]]></mathphrase></inlineequation>) + elsif type == :latexmath + # unhandled math; pass source to alt and required mathphrase element; dblatex will process alt as LaTeX math + %(<inlineequation><alt><![CDATA[#{equation = node.text}]]></alt><mathphrase><![CDATA[#{equation}]]></mathphrase></inlineequation>) + elsif type == :monospaced + node.text.gsub(/(\.\.\.?)([^\]$.])/, '<literal>\1</literal>\2') + .gsub(%r{([\[\s|()>.]|^|\]|>)(\.?([-a-zA-Z0-9:+=~@,/_^\$]+\.{0,2})+)}, '\1<literal>\2</literal>') + .gsub(/(<[-a-zA-Z0-9.]+>)/, '<emphasis>\1</emphasis>') + else + open, close, supports_phrase = QUOTE_TAGS[type] + text = node.text + if node.role + if supports_phrase + quoted_text = %(#{open}<phrase role="#{node.role}">#{text}</phrase>#{close}) + else + quoted_text = %(#{open.chop} role="#{node.role}">#{text}#{close}) + end + else + quoted_text = %(#{open}#{text}#{close}) + end + node.id ? %(<anchor#{common_attributes node.id, nil, text}/>#{quoted_text}) : quoted_text + end + end + end + + # register a html5 converter that takes in charge to convert monospaced text into Git style synopsis + class GitHTMLConverter < Asciidoctor::Converter::Html5Converter + + extend Asciidoctor::Converter::Config + register_for 'html5' + + def convert_inline_quoted node + if node.type == :monospaced + node.text.gsub(/(\.\.\.?)([^\]$.])/, '<code>\1</code>\2') + .gsub(%r{([\[\s|()>.]|^|\]|>)(\.?([-a-zA-Z0-9:+=~@,/_^\$]+\.{0,2})+)}, '\1<code>\2</code>') + .gsub(/(<[-a-zA-Z0-9.]+>)/, '<em>\1</em>') + + else + open, close, tag = QUOTE_TAGS[node.type] + if node.id + class_attr = node.role ? %( class="#{node.role}") : '' + if tag + %(#{open.chop} id="#{node.id}"#{class_attr}>#{node.text}#{close}) + else + %(<span id="#{node.id}"#{class_attr}>#{open}#{node.text}#{close}</span>) + end + elsif node.role + if tag + %(#{open.chop} class="#{node.role}">#{node.text}#{close}) + else + %(<span class="#{node.role}">#{open}#{node.text}#{close}</span>) + end + else + %(#{open}#{node.text}#{close}) + end + end + end + end + end +end + +Asciidoctor::Extensions.register do + inline_macro Git::Documentation::LinkGitProcessor, :linkgit + block Git::Documentation::SynopsisBlock + postprocessor Git::Documentation::DocumentPostProcessor +end diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.adoc similarity index 99% rename from Documentation/blame-options.txt rename to Documentation/blame-options.adoc index 552dcc60f2a41e..aa77406d4ef335 100644 --- a/Documentation/blame-options.txt +++ b/Documentation/blame-options.adoc @@ -18,7 +18,7 @@ '<start>' and '<end>' are optional. `-L <start>` or `-L <start>,` spans from '<start>' to end of file. `-L ,<end>` spans from start of file to '<end>'. + -include::line-range-format.txt[] +include::line-range-format.adoc[] -l:: Show long rev (Default: off). diff --git a/Documentation/build-docdep.perl b/Documentation/build-docdep.perl index 1b3ac8fdd95fa1..781da12b2ee8c9 100755 --- a/Documentation/build-docdep.perl +++ b/Documentation/build-docdep.perl @@ -1,16 +1,18 @@ #!/usr/bin/perl +my ($build_dir) = @ARGV; my %include = (); my %included = (); -for my $text (<*.txt>) { - open I, '<', $text || die "cannot read: $text"; +for my $adoc (<*.adoc>) { + open I, '<', $adoc || die "cannot read: $adoc"; while (<I>) { if (/^include::/) { chomp; s/^include::\s*//; s/\[\]//; - $include{$text}{$_} = 1; + s/{build_dir}/${build_dir}/; + $include{$adoc}{$_} = 1; $included{$_} = 1; } } @@ -21,14 +23,14 @@ my $changed = 1; while ($changed) { $changed = 0; - while (my ($text, $included) = each %include) { + while (my ($adoc, $included) = each %include) { for my $i (keys %$included) { - # $text has include::$i; if $i includes $j - # $text indirectly includes $j. + # $adoc has include::$i; if $i includes $j + # $adoc indirectly includes $j. if (exists $include{$i}) { for my $j (keys %{$include{$i}}) { - if (!exists $include{$text}{$j}) { - $include{$text}{$j} = 1; + if (!exists $include{$adoc}{$j}) { + $include{$adoc}{$j} = 1; $included{$j} = 1; $changed = 1; } @@ -38,10 +40,10 @@ } } -foreach my $text (sort keys %include) { - my $included = $include{$text}; - if (! exists $included{$text} && - (my $base = $text) =~ s/\.txt$//) { +foreach my $adoc (sort keys %include) { + my $included = $include{$adoc}; + if (! exists $included{$adoc} && + (my $base = $adoc) =~ s/\.adoc$//) { print "$base.html $base.xml : ", join(" ", sort keys %$included), "\n"; } } diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index 755a110bc48d7e..0a0c1b3f611450 100755 --- a/Documentation/cmd-list.perl +++ b/Documentation/cmd-list.perl @@ -3,12 +3,13 @@ use File::Compare qw(compare); sub format_one { - my ($out, $nameattr) = @_; + my ($source_dir, $out, $nameattr) = @_; my ($name, $attr) = @$nameattr; + my ($path) = "$source_dir/Documentation/$name.adoc"; my ($state, $description); my $mansection; $state = 0; - open I, '<', "$name.txt" or die "No such file $name.txt"; + open I, '<', "$path" or die "No such file $path.adoc"; while (<I>) { if (/^(?:git|scalar)[a-z0-9-]*\(([0-9])\)$/) { $mansection = $1; @@ -29,7 +30,7 @@ sub format_one { } close I; if (!defined $description) { - die "No description found in $name.txt"; + die "No description found in $path.adoc"; } if (my ($verify_name, $text) = ($description =~ /^($name) - (.*)/)) { print $out "linkgit:$name\[$mansection\]::\n\t"; @@ -43,9 +44,9 @@ sub format_one { } } -my ($input, @categories) = @ARGV; +my ($source_dir, $build_dir, @categories) = @ARGV; -open IN, "<$input"; +open IN, "<$source_dir/command-list.txt"; while (<IN>) { last if /^### command list/; } @@ -62,18 +63,18 @@ sub format_one { close IN; for my $out (@categories) { - my ($cat) = $out =~ /^cmds-(.*)\.txt$/; - open O, '>', "$out+" or die "Cannot open output file $out+"; + my ($cat) = $out =~ /^cmds-(.*)\.adoc$/; + my ($path) = "$build_dir/$out"; + open O, '>', "$path+" or die "Cannot open output file $out+"; for (@{$cmds{$cat}}) { - format_one(\*O, $_); + format_one($source_dir, \*O, $_); } close O; - if (-f "$out" && compare("$out", "$out+") == 0) { - unlink "$out+"; + if (-f "$path" && compare("$path", "$path+") == 0) { + unlink "$path+"; } else { - print STDERR "$out\n"; - rename "$out+", "$out"; + rename "$path+", "$path"; } } diff --git a/Documentation/config.txt b/Documentation/config.adoc similarity index 84% rename from Documentation/config.txt rename to Documentation/config.adoc index 8c0b3ed8075214..959274686cd853 100644 --- a/Documentation/config.txt +++ b/Documentation/config.adoc @@ -372,186 +372,190 @@ inventing new variables for use in your own tool, make sure their names do not conflict with those that are used by Git itself and other popular tools, and describe them in your documentation. -include::config/add.txt[] +include::config/add.adoc[] -include::config/advice.txt[] +include::config/advice.adoc[] -include::config/alias.txt[] +include::config/alias.adoc[] -include::config/am.txt[] +include::config/am.adoc[] -include::config/apply.txt[] +include::config/apply.adoc[] -include::config/attr.txt[] +include::config/attr.adoc[] -include::config/bitmap-pseudo-merge.txt[] +include::config/bitmap-pseudo-merge.adoc[] -include::config/blame.txt[] +include::config/blame.adoc[] -include::config/branch.txt[] +include::config/branch.adoc[] -include::config/browser.txt[] +include::config/browser.adoc[] -include::config/bundle.txt[] +include::config/bundle.adoc[] -include::config/checkout.txt[] +include::config/checkout.adoc[] -include::config/clean.txt[] +include::config/clean.adoc[] -include::config/clone.txt[] +include::config/clone.adoc[] -include::config/color.txt[] +include::config/color.adoc[] -include::config/column.txt[] +include::config/column.adoc[] -include::config/commit.txt[] +include::config/commit.adoc[] -include::config/commitgraph.txt[] +include::config/commitgraph.adoc[] -include::config/completion.txt[] +include::config/completion.adoc[] -include::config/core.txt[] +include::config/core.adoc[] -include::config/credential.txt[] +include::config/credential.adoc[] -include::config/diff.txt[] +include::config/diff.adoc[] -include::config/difftool.txt[] +include::config/difftool.adoc[] -include::config/extensions.txt[] +include::config/extensions.adoc[] -include::config/fastimport.txt[] +include::config/fastimport.adoc[] -include::config/feature.txt[] +include::config/feature.adoc[] -include::config/fetch.txt[] +include::config/fetch.adoc[] -include::config/filter.txt[] +include::config/filter.adoc[] -include::config/format.txt[] +include::config/format.adoc[] -include::config/fsck.txt[] +include::config/fsck.adoc[] -include::config/fsmonitor--daemon.txt[] +include::config/fsmonitor--daemon.adoc[] -include::config/gc.txt[] +include::config/gc.adoc[] -include::config/gitcvs.txt[] +include::config/gitcvs.adoc[] -include::config/gitweb.txt[] +include::config/gitweb.adoc[] -include::config/gpg.txt[] +include::config/gpg.adoc[] -include::config/grep.txt[] +include::config/grep.adoc[] -include::config/gui.txt[] +include::config/gui.adoc[] -include::config/guitool.txt[] +include::config/guitool.adoc[] -include::config/help.txt[] +include::config/help.adoc[] -include::config/http.txt[] +include::config/http.adoc[] -include::config/i18n.txt[] +include::config/i18n.adoc[] -include::config/imap.txt[] +include::config/imap.adoc[] -include::config/includeif.txt[] +include::config/includeif.adoc[] -include::config/index.txt[] +include::config/index.adoc[] -include::config/init.txt[] +include::config/init.adoc[] -include::config/instaweb.txt[] +include::config/instaweb.adoc[] -include::config/interactive.txt[] +include::config/interactive.adoc[] -include::config/log.txt[] +include::config/log.adoc[] -include::config/lsrefs.txt[] +include::config/lsrefs.adoc[] -include::config/mailinfo.txt[] +include::config/mailinfo.adoc[] -include::config/mailmap.txt[] +include::config/mailmap.adoc[] -include::config/maintenance.txt[] +include::config/maintenance.adoc[] -include::config/man.txt[] +include::config/man.adoc[] -include::config/merge.txt[] +include::config/merge.adoc[] -include::config/mergetool.txt[] +include::config/mergetool.adoc[] -include::config/notes.txt[] +include::config/notes.adoc[] -include::config/pack.txt[] +include::config/pack.adoc[] -include::config/pager.txt[] +include::config/pager.adoc[] -include::config/pretty.txt[] +include::config/pretty.adoc[] -include::config/promisor.txt[] +include::config/promisor.adoc[] -include::config/protocol.txt[] +include::config/protocol.adoc[] -include::config/pull.txt[] +include::config/pull.adoc[] -include::config/push.txt[] +include::config/push.adoc[] -include::config/rebase.txt[] +include::config/rebase.adoc[] -include::config/receive.txt[] +include::config/receive.adoc[] -include::config/reftable.txt[] +include::config/reftable.adoc[] -include::config/remote.txt[] +include::config/remote.adoc[] -include::config/remotes.txt[] +include::config/remotes.adoc[] -include::config/repack.txt[] +include::config/repack.adoc[] -include::config/rerere.txt[] +include::config/rerere.adoc[] -include::config/revert.txt[] +include::config/revert.adoc[] -include::config/safe.txt[] +include::config/safe.adoc[] -include::config/sendemail.txt[] +include::config/sendemail.adoc[] -include::config/sequencer.txt[] +include::config/sequencer.adoc[] -include::config/showbranch.txt[] +include::config/showbranch.adoc[] -include::config/sparse.txt[] +include::config/sparse.adoc[] -include::config/splitindex.txt[] +include::config/splitindex.adoc[] -include::config/ssh.txt[] +include::config/ssh.adoc[] -include::config/stash.txt[] +include::config/stash.adoc[] -include::config/status.txt[] +include::config/status.adoc[] -include::config/submodule.txt[] +include::config/submodule.adoc[] -include::config/tag.txt[] +include::config/survey.adoc[] -include::config/tar.txt[] +include::config/tag.adoc[] -include::config/trace2.txt[] +include::config/tar.adoc[] -include::config/transfer.txt[] +include::config/trace2.adoc[] -include::config/uploadarchive.txt[] +include::config/trailer.adoc[] -include::config/uploadpack.txt[] +include::config/transfer.adoc[] -include::config/url.txt[] +include::config/uploadarchive.adoc[] -include::config/user.txt[] +include::config/uploadpack.adoc[] -include::config/versionsort.txt[] +include::config/url.adoc[] -include::config/web.txt[] +include::config/user.adoc[] -include::config/worktree.txt[] +include::config/versionsort.adoc[] + +include::config/web.adoc[] + +include::config/worktree.adoc[] diff --git a/Documentation/config/add.adoc b/Documentation/config/add.adoc new file mode 100644 index 00000000000000..7497533cbccf4e --- /dev/null +++ b/Documentation/config/add.adoc @@ -0,0 +1,12 @@ +`add.ignoreErrors`:: +`add.ignore-errors` (deprecated):: + Tells `git add` to continue adding files when some files cannot be + added due to indexing errors. +ifdef::git-add[] + Equivalent to the `--ignore-errors` option. +endif::git-add[] +ifndef::git-add[] + Equivalent to the `--ignore-errors` option of linkgit:git-add[1]. +endif::git-add[] + `add.ignore-errors` is deprecated, as it does not follow the usual + naming convention for configuration variables. diff --git a/Documentation/config/add.txt b/Documentation/config/add.txt deleted file mode 100644 index 4d753f006ec1ef..00000000000000 --- a/Documentation/config/add.txt +++ /dev/null @@ -1,7 +0,0 @@ -add.ignoreErrors:: -add.ignore-errors (deprecated):: - Tells 'git add' to continue adding files when some files cannot be - added due to indexing errors. Equivalent to the `--ignore-errors` - option of linkgit:git-add[1]. `add.ignore-errors` is deprecated, - as it does not follow the usual naming convention for configuration - variables. diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.adoc similarity index 100% rename from Documentation/config/advice.txt rename to Documentation/config/advice.adoc diff --git a/Documentation/config/alias.txt b/Documentation/config/alias.adoc similarity index 100% rename from Documentation/config/alias.txt rename to Documentation/config/alias.adoc diff --git a/Documentation/config/am.txt b/Documentation/config/am.adoc similarity index 100% rename from Documentation/config/am.txt rename to Documentation/config/am.adoc diff --git a/Documentation/config/apply.txt b/Documentation/config/apply.adoc similarity index 100% rename from Documentation/config/apply.txt rename to Documentation/config/apply.adoc diff --git a/Documentation/config/attr.txt b/Documentation/config/attr.adoc similarity index 100% rename from Documentation/config/attr.txt rename to Documentation/config/attr.adoc diff --git a/Documentation/config/bitmap-pseudo-merge.txt b/Documentation/config/bitmap-pseudo-merge.adoc similarity index 100% rename from Documentation/config/bitmap-pseudo-merge.txt rename to Documentation/config/bitmap-pseudo-merge.adoc diff --git a/Documentation/config/blame.txt b/Documentation/config/blame.adoc similarity index 100% rename from Documentation/config/blame.txt rename to Documentation/config/blame.adoc diff --git a/Documentation/config/branch.txt b/Documentation/config/branch.adoc similarity index 100% rename from Documentation/config/branch.txt rename to Documentation/config/branch.adoc diff --git a/Documentation/config/browser.txt b/Documentation/config/browser.adoc similarity index 100% rename from Documentation/config/browser.txt rename to Documentation/config/browser.adoc diff --git a/Documentation/config/bundle.txt b/Documentation/config/bundle.adoc similarity index 100% rename from Documentation/config/bundle.txt rename to Documentation/config/bundle.adoc diff --git a/Documentation/config/checkout.txt b/Documentation/config/checkout.adoc similarity index 100% rename from Documentation/config/checkout.txt rename to Documentation/config/checkout.adoc diff --git a/Documentation/config/clean.txt b/Documentation/config/clean.adoc similarity index 100% rename from Documentation/config/clean.txt rename to Documentation/config/clean.adoc diff --git a/Documentation/config/clone.txt b/Documentation/config/clone.adoc similarity index 100% rename from Documentation/config/clone.txt rename to Documentation/config/clone.adoc diff --git a/Documentation/config/color.txt b/Documentation/config/color.adoc similarity index 100% rename from Documentation/config/color.txt rename to Documentation/config/color.adoc diff --git a/Documentation/config/column.txt b/Documentation/config/column.adoc similarity index 100% rename from Documentation/config/column.txt rename to Documentation/config/column.adoc diff --git a/Documentation/config/commit.txt b/Documentation/config/commit.adoc similarity index 67% rename from Documentation/config/commit.txt rename to Documentation/config/commit.adoc index 62f0d92fda51de..d3f4624fd27811 100644 --- a/Documentation/config/commit.txt +++ b/Documentation/config/commit.adoc @@ -1,29 +1,34 @@ -commit.cleanup:: +ifdef::git-commit[] +:see-git-commit: +endif::git-commit[] +ifndef::git-commit[] +:see-git-commit: See linkgit:git-commit[1] for details. +endif::git-commit[] +`commit.cleanup`:: This setting overrides the default of the `--cleanup` option in - `git commit`. See linkgit:git-commit[1] for details. Changing the - default can be useful when you always want to keep lines that begin + `git commit`. {see-git-commit} Changing the default can be useful + when you always want to keep lines that begin with the comment character `#` in your log message, in which case you would do `git config commit.cleanup whitespace` (note that you will have to remove the help lines that begin with `#` in the commit log template yourself, if you do this). -commit.gpgSign:: - +`commit.gpgSign`:: A boolean to specify whether all commits should be GPG signed. Use of this option when doing operations such as rebase can result in a large number of commits being signed. It may be convenient to use an agent to avoid typing your GPG passphrase several times. -commit.status:: +`commit.status`:: A boolean to enable/disable inclusion of status information in the commit message template when using an editor to prepare the commit - message. Defaults to true. + message. Defaults to `true`. -commit.template:: +`commit.template`:: Specify the pathname of a file to use as the template for new commit messages. -commit.verbose:: +`commit.verbose`:: A boolean or int to specify the level of verbosity with `git commit`. - See linkgit:git-commit[1]. + {see-git-commit} diff --git a/Documentation/config/commitgraph.txt b/Documentation/config/commitgraph.adoc similarity index 100% rename from Documentation/config/commitgraph.txt rename to Documentation/config/commitgraph.adoc diff --git a/Documentation/config/completion.txt b/Documentation/config/completion.adoc similarity index 100% rename from Documentation/config/completion.txt rename to Documentation/config/completion.adoc diff --git a/Documentation/config/core.txt b/Documentation/config/core.adoc similarity index 99% rename from Documentation/config/core.txt rename to Documentation/config/core.adoc index 60ca9f2b686106..8f6d8e77541261 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.adoc @@ -366,7 +366,7 @@ default in a bare repository. core.repositoryFormatVersion:: Internal variable identifying the repository format and layout - version. + version. See linkgit:gitrepository-layout[5]. core.sharedRepository:: When 'group' (or 'true'), the repository is made shareable between diff --git a/Documentation/config/credential.txt b/Documentation/config/credential.adoc similarity index 80% rename from Documentation/config/credential.txt rename to Documentation/config/credential.adoc index 470482ff4c2a38..80a7c777720793 100644 --- a/Documentation/config/credential.txt +++ b/Documentation/config/credential.adoc @@ -22,6 +22,17 @@ credential.useHttpPath:: or https URL to be important. Defaults to false. See linkgit:gitcredentials[7] for more information. +credential.sanitizePrompt:: + By default, user names and hosts that are shown as part of the + password prompt are not allowed to contain control characters (they + will be URL-encoded by default). Configure this setting to `false` to + override that behavior. + +credential.protectProtocol:: + By default, Carriage Return characters are not allowed in the protocol + that is used when Git talks to a credential helper. This setting allows + users to override this default. + credential.username:: If no username is set for a network authentication, use this username by default. See credential.<context>.* below, and diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.adoc similarity index 57% rename from Documentation/config/diff.txt rename to Documentation/config/diff.adoc index 190bda17e51c57..1135a62a0ad3de 100644 --- a/Documentation/config/diff.txt +++ b/Documentation/config/diff.adoc @@ -1,18 +1,25 @@ -diff.autoRefreshIndex:: - When using 'git diff' to compare with work tree +`diff.autoRefreshIndex`:: + When using `git diff` to compare with work tree files, do not consider stat-only changes as changed. Instead, silently run `git update-index --refresh` to update the cached stat information for paths whose contents in the work tree match the contents in the - index. This option defaults to true. Note that this - affects only 'git diff' Porcelain, and not lower level - 'diff' commands such as 'git diff-files'. + index. This option defaults to `true`. Note that this + affects only `git diff` Porcelain, and not lower level + `diff` commands such as `git diff-files`. -diff.dirstat:: +`diff.dirstat`:: +ifdef::git-diff[] + A comma separated list of `--dirstat` parameters specifying the + default behavior of the `--dirstat` option to `git diff` and friends. +endif::git-diff[] +ifndef::git-diff[] A comma separated list of `--dirstat` parameters specifying the default behavior of the `--dirstat` option to linkgit:git-diff[1] - and friends. The defaults can be overridden on the command line - (using `--dirstat=<param1,param2,...>`). The fallback defaults + and friends. +endif::git-diff[] + The defaults can be overridden on the command line + (using `--dirstat=<param>,...`). The fallback defaults (when not changed by `diff.dirstat`) are `changes,noncumulative,3`. The following parameters are available: + @@ -41,7 +48,7 @@ diff.dirstat:: Note that when using `cumulative`, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the `noncumulative` parameter. -<limit>;; +_<limit>_;; An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output. @@ -52,58 +59,58 @@ directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: `files,10,cumulative`. -diff.statNameWidth:: - Limit the width of the filename part in --stat output. If set, applies - to all commands generating --stat output except format-patch. +`diff.statNameWidth`:: + Limit the width of the filename part in `--stat` output. If set, applies + to all commands generating `--stat` output except `format-patch`. -diff.statGraphWidth:: - Limit the width of the graph part in --stat output. If set, applies - to all commands generating --stat output except format-patch. +`diff.statGraphWidth`:: + Limit the width of the graph part in `--stat` output. If set, applies + to all commands generating `--stat` output except `format-patch`. -diff.context:: - Generate diffs with <n> lines of context instead of the default - of 3. This value is overridden by the -U option. +`diff.context`:: + Generate diffs with _<n>_ lines of context instead of the default + of 3. This value is overridden by the `-U` option. -diff.interHunkContext:: +`diff.interHunkContext`:: Show the context between diff hunks, up to the specified number of lines, thereby fusing the hunks that are close to each other. This value serves as the default for the `--inter-hunk-context` command line option. -diff.external:: +`diff.external`:: If this config variable is set, diff generation is not performed using the internal diff machinery, but using the - given command. Can be overridden with the `GIT_EXTERNAL_DIFF' + given command. Can be overridden with the `GIT_EXTERNAL_DIFF` environment variable. The command is called with parameters as described under "git Diffs" in linkgit:git[1]. Note: if you want to use an external diff program only on a subset of your files, you might want to use linkgit:gitattributes[5] instead. -diff.trustExitCode:: - If this boolean value is set to true then the +`diff.trustExitCode`:: + If this boolean value is set to `true` then the `diff.external` command is expected to return exit code 0 if it considers the input files to be equal or 1 if it - considers them to be different, like `diff(1)`. - If it is set to false, which is the default, then the command - is expected to return exit code 0 regardless of equality. + considers them to be different, like `diff`(1). + If it is set to `false`, which is the default, then the command + is expected to return exit code `0` regardless of equality. Any other exit code causes Git to report a fatal error. -diff.ignoreSubmodules:: - Sets the default value of --ignore-submodules. Note that this - affects only 'git diff' Porcelain, and not lower level 'diff' - commands such as 'git diff-files'. 'git checkout' - and 'git switch' also honor +`diff.ignoreSubmodules`:: + Sets the default value of `--ignore-submodules`. Note that this + affects only `git diff` Porcelain, and not lower level `diff` + commands such as `git diff-files`. `git checkout` + and `git switch` also honor this setting when reporting uncommitted changes. Setting it to - 'all' disables the submodule summary normally shown by 'git commit' - and 'git status' when `status.submoduleSummary` is set unless it is - overridden by using the --ignore-submodules command-line option. - The 'git submodule' commands are not affected by this setting. + `all` disables the submodule summary normally shown by `git commit` + and `git status` when `status.submoduleSummary` is set unless it is + overridden by using the `--ignore-submodules` command-line option. + The `git submodule` commands are not affected by this setting. By default this is set to untracked so that any untracked submodules are ignored. -diff.mnemonicPrefix:: - If set, 'git diff' uses a prefix pair that is different from the - standard "a/" and "b/" depending on what is being compared. When +`diff.mnemonicPrefix`:: + If set, `git diff` uses a prefix pair that is different from the + standard `a/` and `b/` depending on what is being compared. When this configuration is in effect, reverse diff output also swaps the order of the prefixes: `git diff`;; @@ -112,111 +119,115 @@ diff.mnemonicPrefix:: compares a (c)ommit and the (w)ork tree; `git diff --cached`;; compares a (c)ommit and the (i)ndex; -`git diff HEAD:file1 file2`;; +`git diff HEAD:<file1> <file2>`;; compares an (o)bject and a (w)ork tree entity; -`git diff --no-index a b`;; - compares two non-git things (1) and (2). +`git diff --no-index <a> <b>`;; + compares two non-git things _<a>_ and _<b>_. -diff.noPrefix:: - If set, 'git diff' does not show any source or destination prefix. +`diff.noPrefix`:: + If set, `git diff` does not show any source or destination prefix. -diff.srcPrefix:: - If set, 'git diff' uses this source prefix. Defaults to "a/". +`diff.srcPrefix`:: + If set, `git diff` uses this source prefix. Defaults to `a/`. -diff.dstPrefix:: - If set, 'git diff' uses this destination prefix. Defaults to "b/". +`diff.dstPrefix`:: + If set, `git diff` uses this destination prefix. Defaults to `b/`. -diff.relative:: - If set to 'true', 'git diff' does not show changes outside of the directory +`diff.relative`:: + If set to `true`, `git diff` does not show changes outside of the directory and show pathnames relative to the current directory. -diff.orderFile:: +`diff.orderFile`:: File indicating how to order files within a diff. - See the '-O' option to linkgit:git-diff[1] for details. +ifdef::git-diff[] + See the `-O` option for details. +endif::git-diff[] +ifndef::git-diff[] + See the `-O` option to linkgit:git-diff[1] for details. +endif::git-diff[] If `diff.orderFile` is a relative pathname, it is treated as relative to the top of the working tree. -diff.renameLimit:: +`diff.renameLimit`:: The number of files to consider in the exhaustive portion of - copy/rename detection; equivalent to the 'git diff' option + copy/rename detection; equivalent to the `git diff` option `-l`. If not set, the default value is currently 1000. This setting has no effect if rename detection is turned off. -diff.renames:: - Whether and how Git detects renames. If set to "false", - rename detection is disabled. If set to "true", basic rename - detection is enabled. If set to "copies" or "copy", Git will - detect copies, as well. Defaults to true. Note that this - affects only 'git diff' Porcelain like linkgit:git-diff[1] and +`diff.renames`:: + Whether and how Git detects renames. If set to `false`, + rename detection is disabled. If set to `true`, basic rename + detection is enabled. If set to `copies` or `copy`, Git will + detect copies, as well. Defaults to `true`. Note that this + affects only `git diff` Porcelain like linkgit:git-diff[1] and linkgit:git-log[1], and not lower level commands such as linkgit:git-diff-files[1]. -diff.suppressBlankEmpty:: +`diff.suppressBlankEmpty`:: A boolean to inhibit the standard behavior of printing a space - before each empty output line. Defaults to false. + before each empty output line. Defaults to `false`. -diff.submodule:: +`diff.submodule`:: Specify the format in which differences in submodules are - shown. The "short" format just shows the names of the commits - at the beginning and end of the range. The "log" format lists + shown. The `short` format just shows the names of the commits + at the beginning and end of the range. The `log` format lists the commits in the range like linkgit:git-submodule[1] `summary` - does. The "diff" format shows an inline diff of the changed - contents of the submodule. Defaults to "short". + does. The `diff` format shows an inline diff of the changed + contents of the submodule. Defaults to `short`. -diff.wordRegex:: +`diff.wordRegex`:: A POSIX Extended Regular Expression used to determine what is a "word" when performing word-by-word difference calculations. Character sequences that match the regular expression are "words", all other characters are *ignorable* whitespace. -diff.<driver>.command:: +`diff.<driver>.command`:: The custom diff driver command. See linkgit:gitattributes[5] for details. -diff.<driver>.trustExitCode:: - If this boolean value is set to true then the +`diff.<driver>.trustExitCode`:: + If this boolean value is set to `true` then the `diff.<driver>.command` command is expected to return exit code 0 if it considers the input files to be equal or 1 if it - considers them to be different, like `diff(1)`. - If it is set to false, which is the default, then the command + considers them to be different, like `diff`(1). + If it is set to `false`, which is the default, then the command is expected to return exit code 0 regardless of equality. Any other exit code causes Git to report a fatal error. -diff.<driver>.xfuncname:: +`diff.<driver>.xfuncname`:: The regular expression that the diff driver should use to recognize the hunk header. A built-in pattern may also be used. See linkgit:gitattributes[5] for details. -diff.<driver>.binary:: - Set this option to true to make the diff driver treat files as +`diff.<driver>.binary`:: + Set this option to `true` to make the diff driver treat files as binary. See linkgit:gitattributes[5] for details. -diff.<driver>.textconv:: +`diff.<driver>.textconv`:: The command that the diff driver should call to generate the text-converted version of a file. The result of the conversion is used to generate a human-readable diff. See linkgit:gitattributes[5] for details. -diff.<driver>.wordRegex:: +`diff.<driver>.wordRegex`:: The regular expression that the diff driver should use to split words in a line. See linkgit:gitattributes[5] for details. -diff.<driver>.cachetextconv:: - Set this option to true to make the diff driver cache the text +`diff.<driver>.cachetextconv`:: + Set this option to `true` to make the diff driver cache the text conversion outputs. See linkgit:gitattributes[5] for details. -include::../mergetools-diff.txt[] - -diff.indentHeuristic:: +`diff.indentHeuristic`:: Set this option to `false` to disable the default heuristics that shift diff hunk boundaries to make patches easier to read. -diff.algorithm:: +`diff.algorithm`:: Choose a diff algorithm. The variants are as follows: + -- -`default`, `myers`;; +`default`;; +`myers`;; The basic greedy diff algorithm. Currently, this is the default. `minimal`;; Spend extra time to make sure the smallest possible diff is @@ -229,7 +240,7 @@ diff.algorithm:: -- + -diff.wsErrorHighlight:: +`diff.wsErrorHighlight`:: Highlight whitespace errors in the `context`, `old` or `new` lines of the diff. Multiple values are separated by comma, `none` resets previous values, `default` reset the list to @@ -238,14 +249,19 @@ diff.wsErrorHighlight:: The command line option `--ws-error-highlight=<kind>` overrides this setting. -diff.colorMoved:: - If set to either a valid `<mode>` or a true value, moved lines - in a diff are colored differently, for details of valid modes - see '--color-moved' in linkgit:git-diff[1]. If simply set to - true the default color mode will be used. When set to false, - moved lines are not colored. - -diff.colorMovedWS:: +`diff.colorMoved`:: + If set to either a valid _<mode>_ or a `true` value, moved lines + in a diff are colored differently. +ifdef::git-diff[] + For details of valid modes see `--color-moved`. +endif::git-diff[] +ifndef::git-diff[] + For details of valid modes see `--color-moved` in linkgit:git-diff[1]. +endif::git-diff[] + If simply set to `true` the default color mode will be used. When + set to `false`, moved lines are not colored. + +`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/difftool.txt b/Documentation/config/difftool.adoc similarity index 97% rename from Documentation/config/difftool.txt rename to Documentation/config/difftool.adoc index 447c40d85a289d..4f7d40ce242b78 100644 --- a/Documentation/config/difftool.txt +++ b/Documentation/config/difftool.adoc @@ -13,6 +13,8 @@ diff.guitool:: and requires that a corresponding difftool.<guitool>.cmd variable is defined. +include::{build_dir}/mergetools-diff.adoc[] + difftool.<tool>.cmd:: Specify the command to invoke the specified diff tool. The specified command is evaluated in shell with the following diff --git a/Documentation/config/extensions.txt b/Documentation/config/extensions.adoc similarity index 51% rename from Documentation/config/extensions.txt rename to Documentation/config/extensions.adoc index 38dce3df359761..9e2f321a6d776f 100644 --- a/Documentation/config/extensions.txt +++ b/Documentation/config/extensions.adoc @@ -1,17 +1,13 @@ -extensions.objectFormat:: - Specify the hash algorithm to use. The acceptable values are `sha1` and - `sha256`. If not specified, `sha1` is assumed. It is an error to specify - this key unless `core.repositoryFormatVersion` is 1. +extensions.*:: + Unless otherwise stated, is an error to specify an extension if + `core.repositoryFormatVersion` is not `1`. See + linkgit:gitrepository-layout[5]. + -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.compatObjectFormat:: - - Specify a compatitbility hash algorithm to use. The acceptable values +-- +compatObjectFormat:: + Specify a compatibility hash algorithm to use. The acceptable values are `sha1` and `sha256`. The value specified must be different from the - value of extensions.objectFormat. This allows client level + value of `extensions.objectFormat`. This allows client level interoperability between git repositories whose objectFormat matches this compatObjectFormat. In particular when fully implemented the pushes and pulls from a repository in whose objectFormat matches @@ -19,18 +15,61 @@ extensions.compatObjectFormat:: compatObjectFormat in addition to oids encoded with objectFormat to locally specify objects. -extensions.refStorage:: - Specify the ref storage format to use. The acceptable values are: +noop:: + This extension does not change git's behavior at all. It is useful only + for testing format-1 compatibility. ++ +For historical reasons, this extension is respected regardless of the +`core.repositoryFormatVersion` setting. + +noop-v1:: + This extension does not change git's behavior at all. It is useful only + for testing format-1 compatibility. + +objectFormat:: + Specify the hash algorithm to use. The acceptable values are `sha1` and + `sha256`. If not specified, `sha1` is assumed. ++ +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. + +partialClone:: + When enabled, indicates that the repo was created with a partial clone + (or later performed a partial fetch) and that the remote may have + omitted sending certain unwanted objects. Such a remote is called a + "promisor remote" and it promises that all such omitted objects can + be fetched from it in the future. ++ +The value of this key is the name of the promisor remote. ++ +For historical reasons, this extension is respected regardless of the +`core.repositoryFormatVersion` setting. + +preciousObjects:: + If enabled, indicates that objects in the repository MUST NOT be deleted + (e.g., by `git-prune` or `git repack -d`). + -include::../ref-storage-format.txt[] +For historical reasons, this extension is respected regardless of the +`core.repositoryFormatVersion` setting. + +refStorage:: + Specify the ref storage format to use. The acceptable values are: + -It is an error to specify this key unless `core.repositoryFormatVersion` is 1. +include::../ref-storage-format.adoc[] + + 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:: +relativeWorktrees:: + If enabled, indicates at least one worktree has been linked with + relative paths. Automatically set if a worktree has been created or + repaired with either the `--relative-paths` option or with the + `worktree.useRelativePaths` config set to `true`. + +worktreeConfig:: If enabled, then worktrees will load config settings from the `$GIT_DIR/config.worktree` file in addition to the `$GIT_COMMON_DIR/config` file. Note that `$GIT_COMMON_DIR` and @@ -40,7 +79,7 @@ extensions.worktreeConfig:: `config.worktree` file will override settings from any other config files. + -When enabling `extensions.worktreeConfig`, you must be careful to move +When enabling this extension, you must be careful to move certain values from the common config file to the main working tree's `config.worktree` file, if present: + @@ -48,15 +87,17 @@ certain values from the common config file to the main working tree's `$GIT_COMMON_DIR/config.worktree`. * If `core.bare` is true, then it must be moved from `$GIT_COMMON_DIR/config` to `$GIT_COMMON_DIR/config.worktree`. + + It may also be beneficial to adjust the locations of `core.sparseCheckout` and `core.sparseCheckoutCone` depending on your desire for customizable sparse-checkout settings for each worktree. By default, the `git -sparse-checkout` builtin enables `extensions.worktreeConfig`, assigns +sparse-checkout` builtin enables this extension, assigns these config values on a per-worktree basis, and uses the `$GIT_DIR/info/sparse-checkout` file to specify the sparsity for each worktree independently. See linkgit:git-sparse-checkout[1] for more details. + -For historical reasons, `extensions.worktreeConfig` is respected -regardless of the `core.repositoryFormatVersion` setting. +For historical reasons, this extension is respected regardless of the +`core.repositoryFormatVersion` setting. +-- diff --git a/Documentation/config/fastimport.txt b/Documentation/config/fastimport.adoc similarity index 100% rename from Documentation/config/fastimport.txt rename to Documentation/config/fastimport.adoc diff --git a/Documentation/config/feature.txt b/Documentation/config/feature.adoc similarity index 100% rename from Documentation/config/feature.txt rename to Documentation/config/feature.adoc diff --git a/Documentation/config/fetch.txt b/Documentation/config/fetch.adoc similarity index 100% rename from Documentation/config/fetch.txt rename to Documentation/config/fetch.adoc diff --git a/Documentation/config/filter.txt b/Documentation/config/filter.adoc similarity index 100% rename from Documentation/config/filter.txt rename to Documentation/config/filter.adoc diff --git a/Documentation/config/fmt-merge-msg.txt b/Documentation/config/fmt-merge-msg.adoc similarity index 100% rename from Documentation/config/fmt-merge-msg.txt rename to Documentation/config/fmt-merge-msg.adoc diff --git a/Documentation/config/format.txt b/Documentation/config/format.adoc similarity index 100% rename from Documentation/config/format.txt rename to Documentation/config/format.adoc diff --git a/Documentation/config/fsck.txt b/Documentation/config/fsck.adoc similarity index 100% rename from Documentation/config/fsck.txt rename to Documentation/config/fsck.adoc diff --git a/Documentation/config/fsmonitor--daemon.txt b/Documentation/config/fsmonitor--daemon.adoc similarity index 100% rename from Documentation/config/fsmonitor--daemon.txt rename to Documentation/config/fsmonitor--daemon.adoc diff --git a/Documentation/config/gc.txt b/Documentation/config/gc.adoc similarity index 99% rename from Documentation/config/gc.txt rename to Documentation/config/gc.adoc index 1d4f9470ead207..21d56db2798935 100644 --- a/Documentation/config/gc.txt +++ b/Documentation/config/gc.adoc @@ -163,7 +163,7 @@ gc.repackFilterTo:: containing the filtered out objects. **WARNING:** The specified location should be accessible, using for example the Git alternates mechanism, otherwise the repo could be - considered corrupt by Git as it migh not be able to access the + considered corrupt by Git as it might not be able to access the objects in that packfile. See the `--filter-to=<dir>` option of linkgit:git-repack[1] and the `objects/info/alternates` section of linkgit:gitrepository-layout[5]. diff --git a/Documentation/config/gitcvs.txt b/Documentation/config/gitcvs.adoc similarity index 100% rename from Documentation/config/gitcvs.txt rename to Documentation/config/gitcvs.adoc diff --git a/Documentation/config/gitweb.txt b/Documentation/config/gitweb.adoc similarity index 100% rename from Documentation/config/gitweb.txt rename to Documentation/config/gitweb.adoc diff --git a/Documentation/config/gpg.txt b/Documentation/config/gpg.adoc similarity index 100% rename from Documentation/config/gpg.txt rename to Documentation/config/gpg.adoc diff --git a/Documentation/config/grep.txt b/Documentation/config/grep.adoc similarity index 100% rename from Documentation/config/grep.txt rename to Documentation/config/grep.adoc diff --git a/Documentation/config/gui.txt b/Documentation/config/gui.adoc similarity index 100% rename from Documentation/config/gui.txt rename to Documentation/config/gui.adoc diff --git a/Documentation/config/guitool.txt b/Documentation/config/guitool.adoc similarity index 100% rename from Documentation/config/guitool.txt rename to Documentation/config/guitool.adoc diff --git a/Documentation/config/help.txt b/Documentation/config/help.adoc similarity index 81% rename from Documentation/config/help.txt rename to Documentation/config/help.adoc index 610701f9a3745e..b369589cec9474 100644 --- a/Documentation/config/help.txt +++ b/Documentation/config/help.adoc @@ -11,13 +11,14 @@ help.autoCorrect:: If git detects typos and can identify exactly one valid command similar to the error, git will try to suggest the correct command or even run the suggestion automatically. Possible config values are: - - 0 (default): show the suggested command. - - positive number: run the suggested command after specified + - 0, "false", "off", "no", "show": show the suggested command (default). + - 1, "true", "on", "yes", "immediate": run the suggested command +immediately. + - positive number > 1: run the suggested command after specified deciseconds (0.1 sec). - - "immediate": run the suggested command immediately. + - "never": don't run or show any suggested command. - "prompt": show the suggestion and prompt for confirmation to run the command. - - "never": don't run or show any suggested command. help.htmlPath:: Specify the path where the HTML documentation resides. File system paths diff --git a/Documentation/config/http.txt b/Documentation/config/http.adoc similarity index 95% rename from Documentation/config/http.txt rename to Documentation/config/http.adoc index a14371b5c96a51..22a8803deaf964 100644 --- a/Documentation/config/http.txt +++ b/Documentation/config/http.adoc @@ -216,6 +216,21 @@ http.sslBackend:: This option is ignored if cURL lacks support for choosing the SSL backend at runtime. +http.sslCertType:: + Type of client certificate used when fetching or pushing over HTTPS. + "PEM", "DER" are supported when using openssl or gnutls backends. "P12" + is supported on "openssl", "schannel", "securetransport", and gnutls 8.11+. + See also libcurl `CURLOPT_SSLCERTTYPE`. Can be overridden by the + `GIT_SSL_CERT_TYPE` environment variable. + +http.sslKeyType:: + Type of client private key used when fetching or pushing over HTTPS. (e.g. + "PEM", "DER", or "ENG"). Only applicable when using "openssl" backend. "DER" + is not supported with openssl. Particularly useful when set to "ENG" for + authenticating with PKCS#11 tokens, with a PKCS#11 URL in sslCert option. + See also libcurl `CURLOPT_SSLKEYTYPE`. Can be overridden by the + `GIT_SSL_KEY_TYPE` environment variable. + http.schannelCheckRevoke:: Used to enforce or disable certificate revocation checks in cURL when http.sslBackend is set to "schannel". Defaults to `true` if diff --git a/Documentation/config/i18n.txt b/Documentation/config/i18n.adoc similarity index 100% rename from Documentation/config/i18n.txt rename to Documentation/config/i18n.adoc diff --git a/Documentation/config/imap.txt b/Documentation/config/imap.adoc similarity index 100% rename from Documentation/config/imap.txt rename to Documentation/config/imap.adoc diff --git a/Documentation/config/includeif.txt b/Documentation/config/includeif.adoc similarity index 100% rename from Documentation/config/includeif.txt rename to Documentation/config/includeif.adoc diff --git a/Documentation/config/index.txt b/Documentation/config/index.adoc similarity index 100% rename from Documentation/config/index.txt rename to Documentation/config/index.adoc diff --git a/Documentation/config/init.txt b/Documentation/config/init.adoc similarity index 100% rename from Documentation/config/init.txt rename to Documentation/config/init.adoc diff --git a/Documentation/config/instaweb.txt b/Documentation/config/instaweb.adoc similarity index 100% rename from Documentation/config/instaweb.txt rename to Documentation/config/instaweb.adoc diff --git a/Documentation/config/interactive.txt b/Documentation/config/interactive.adoc similarity index 100% rename from Documentation/config/interactive.txt rename to Documentation/config/interactive.adoc diff --git a/Documentation/config/log.txt b/Documentation/config/log.adoc similarity index 100% rename from Documentation/config/log.txt rename to Documentation/config/log.adoc diff --git a/Documentation/config/lsrefs.txt b/Documentation/config/lsrefs.adoc similarity index 100% rename from Documentation/config/lsrefs.txt rename to Documentation/config/lsrefs.adoc diff --git a/Documentation/config/mailinfo.txt b/Documentation/config/mailinfo.adoc similarity index 100% rename from Documentation/config/mailinfo.txt rename to Documentation/config/mailinfo.adoc diff --git a/Documentation/config/mailmap.txt b/Documentation/config/mailmap.adoc similarity index 100% rename from Documentation/config/mailmap.txt rename to Documentation/config/mailmap.adoc diff --git a/Documentation/config/maintenance.txt b/Documentation/config/maintenance.adoc similarity index 100% rename from Documentation/config/maintenance.txt rename to Documentation/config/maintenance.adoc diff --git a/Documentation/config/man.txt b/Documentation/config/man.adoc similarity index 100% rename from Documentation/config/man.txt rename to Documentation/config/man.adoc diff --git a/Documentation/config/merge.txt b/Documentation/config/merge.adoc similarity index 96% rename from Documentation/config/merge.txt rename to Documentation/config/merge.adoc index 8851b6cedef980..d2d0f21a712daf 100644 --- a/Documentation/config/merge.txt +++ b/Documentation/config/merge.adoc @@ -37,7 +37,7 @@ merge.verifySignatures:: If true, this is equivalent to the --verify-signatures command line option. See linkgit:git-merge[1] for details. -include::fmt-merge-msg.txt[] +include::fmt-merge-msg.adoc[] merge.renameLimit:: The number of files to consider in the exhaustive portion of @@ -69,7 +69,8 @@ merge.renormalize:: Tell Git that canonical representation of files in the repository has changed over time (e.g. earlier commits record text files with CRLF line endings, but recent ones use LF line - endings). In such a repository, Git can convert the data + endings). In such a repository, for each file where a + three-way content merge is needed, Git can convert the data recorded in commits to a canonical form before performing a merge to reduce unnecessary conflicts. For more information, see section "Merging branches with differing checkin/checkout @@ -101,7 +102,7 @@ merge.guitool:: Any other value is treated as a custom merge tool and requires that a corresponding mergetool.<guitool>.cmd variable is defined. -include::../mergetools-merge.txt[] +include::{build_dir}/mergetools-merge.adoc[] merge.verbosity:: Controls the amount of output shown by the recursive merge diff --git a/Documentation/config/mergetool.txt b/Documentation/config/mergetool.adoc similarity index 100% rename from Documentation/config/mergetool.txt rename to Documentation/config/mergetool.adoc diff --git a/Documentation/config/notes.txt b/Documentation/config/notes.adoc similarity index 73% rename from Documentation/config/notes.txt rename to Documentation/config/notes.adoc index 43db8e808d7ab7..b7e536496f51b7 100644 --- a/Documentation/config/notes.txt +++ b/Documentation/config/notes.adoc @@ -1,4 +1,4 @@ -notes.mergeStrategy:: +`notes.mergeStrategy`:: Which merge strategy to choose by default when resolving notes conflicts. Must be one of `manual`, `ours`, `theirs`, `union`, or `cat_sort_uniq`. Defaults to `manual`. See the "NOTES MERGE STRATEGIES" @@ -7,17 +7,17 @@ notes.mergeStrategy:: This setting can be overridden by passing the `--strategy` option to linkgit:git-notes[1]. -notes.<name>.mergeStrategy:: +`notes.<name>.mergeStrategy`:: Which merge strategy to choose when doing a notes merge into - refs/notes/<name>. This overrides the more general - "notes.mergeStrategy". See the "NOTES MERGE STRATEGIES" section in + `refs/notes/<name>`. This overrides the more general + `notes.mergeStrategy`. See the "NOTES MERGE STRATEGIES" section in linkgit:git-notes[1] for more information on the available strategies. -notes.displayRef:: +`notes.displayRef`:: Which ref (or refs, if a glob or specified more than once), in addition to the default set by `core.notesRef` or `GIT_NOTES_REF`, to read notes from when showing commit - messages with the 'git log' family of commands. + messages with the `git log` family of commands. + This setting can be overridden with the `GIT_NOTES_DISPLAY_REF` environment variable, which must be a colon separated list of refs or @@ -26,27 +26,27 @@ globs. A warning will be issued for refs that do not exist, but a glob that does not match any refs is silently ignored. + -This setting can be disabled by the `--no-notes` option to the 'git -log' family of commands, or by the `--notes=<ref>` option accepted by +This setting can be disabled by the `--no-notes` option to the linkgit:git-log[1] +family of commands, or by the `--notes=<ref>` option accepted by those commands. + -The effective value of "core.notesRef" (possibly overridden by -GIT_NOTES_REF) is also implicitly added to the list of refs to be +The effective value of `core.notesRef` (possibly overridden by +`GIT_NOTES_REF`) is also implicitly added to the list of refs to be displayed. -notes.rewrite.<command>:: - When rewriting commits with <command> (currently `amend` or +`notes.rewrite.<command>`:: + When rewriting commits with _<command>_ (currently `amend` or `rebase`), if this variable is `false`, git will not copy notes from the original to the rewritten commit. Defaults to - `true`. See also "`notes.rewriteRef`" below. + `true`. See also `notes.rewriteRef` below. + This setting can be overridden with the `GIT_NOTES_REWRITE_REF` environment variable, which must be a colon separated list of refs or globs. -notes.rewriteMode:: +`notes.rewriteMode`:: When copying notes during a rewrite (see the - "notes.rewrite.<command>" option), determines what to do if + `notes.rewrite.<command>` option), determines what to do if the target commit already has a note. Must be one of `overwrite`, `concatenate`, `cat_sort_uniq`, or `ignore`. Defaults to `concatenate`. @@ -54,7 +54,7 @@ notes.rewriteMode:: This setting can be overridden with the `GIT_NOTES_REWRITE_MODE` environment variable. -notes.rewriteRef:: +`notes.rewriteRef`:: When copying notes during a rewrite, specifies the (fully qualified) ref whose notes should be copied. May be a glob, in which case notes in all matching refs will be copied. You diff --git a/Documentation/config/pack.txt b/Documentation/config/pack.adoc similarity index 100% rename from Documentation/config/pack.txt rename to Documentation/config/pack.adoc diff --git a/Documentation/config/pager.txt b/Documentation/config/pager.adoc similarity index 100% rename from Documentation/config/pager.txt rename to Documentation/config/pager.adoc diff --git a/Documentation/config/pretty.txt b/Documentation/config/pretty.adoc similarity index 100% rename from Documentation/config/pretty.txt rename to Documentation/config/pretty.adoc diff --git a/Documentation/config/promisor.adoc b/Documentation/config/promisor.adoc new file mode 100644 index 00000000000000..9192acfd243097 --- /dev/null +++ b/Documentation/config/promisor.adoc @@ -0,0 +1,30 @@ +promisor.quiet:: + If set to "true" assume `--quiet` when fetching additional + objects for a partial clone. + +promisor.advertise:: + If set to "true", a server will use the "promisor-remote" + capability, see linkgit:gitprotocol-v2[5], to advertise the + promisor remotes it is using, if it uses some. Default is + "false", which means the "promisor-remote" capability is not + advertised. + +promisor.acceptFromServer:: + If set to "all", a client will accept all the promisor remotes + a server might advertise using the "promisor-remote" + capability. If set to "knownName" the client will accept + promisor remotes which are already configured on the client + and have the same name as those advertised by the client. This + is not very secure, but could be used in a corporate setup + where servers and clients are trusted to not switch name and + URLs. If set to "knownUrl", the client will accept promisor + remotes which have both the same name and the same URL + configured on the client as the name and URL advertised by the + server. This is more secure than "all" or "knownName", so it + should be used if possible instead of those options. Default + is "none", which means no promisor remote advertised by a + server will be accepted. By accepting a promisor remote, the + client agrees that the server might omit objects that are + lazily fetchable from this promisor remote from its responses + to "fetch" and "clone" requests from the client. See + linkgit:gitprotocol-v2[5]. diff --git a/Documentation/config/promisor.txt b/Documentation/config/promisor.txt deleted file mode 100644 index 98c5cb2ec20d34..00000000000000 --- a/Documentation/config/promisor.txt +++ /dev/null @@ -1,3 +0,0 @@ -promisor.quiet:: - If set to "true" assume `--quiet` when fetching additional - objects for a partial clone. diff --git a/Documentation/config/protocol.txt b/Documentation/config/protocol.adoc similarity index 100% rename from Documentation/config/protocol.txt rename to Documentation/config/protocol.adoc diff --git a/Documentation/config/pull.txt b/Documentation/config/pull.adoc similarity index 100% rename from Documentation/config/pull.txt rename to Documentation/config/pull.adoc diff --git a/Documentation/config/push.txt b/Documentation/config/push.adoc similarity index 100% rename from Documentation/config/push.txt rename to Documentation/config/push.adoc diff --git a/Documentation/config/rebase.txt b/Documentation/config/rebase.adoc similarity index 100% rename from Documentation/config/rebase.txt rename to Documentation/config/rebase.adoc diff --git a/Documentation/config/receive.txt b/Documentation/config/receive.adoc similarity index 100% rename from Documentation/config/receive.txt rename to Documentation/config/receive.adoc diff --git a/Documentation/config/reftable.txt b/Documentation/config/reftable.adoc similarity index 100% rename from Documentation/config/reftable.txt rename to Documentation/config/reftable.adoc diff --git a/Documentation/config/remote.txt b/Documentation/config/remote.adoc similarity index 76% rename from Documentation/config/remote.txt rename to Documentation/config/remote.adoc index 36e771556c67aa..25fe219d103cc4 100644 --- a/Documentation/config/remote.txt +++ b/Documentation/config/remote.adoc @@ -50,7 +50,7 @@ remote.<name>.skipFetchAll:: If true, this remote will be skipped when updating using linkgit:git-fetch[1], the `update` subcommand of linkgit:git-remote[1], and ignored by the prefetch task - of `git maitenance`. + of `git maintenance`. remote.<name>.receivepack:: The default program to execute on the remote side when pushing. See @@ -96,3 +96,26 @@ remote.<name>.partialclonefilter:: Changing or clearing this value will only affect fetches for new commits. To fetch associated objects for commits already present in the local object database, use the `--refetch` option of linkgit:git-fetch[1]. + +remote.<name>.serverOption:: + The default set of server options used when fetching from this remote. + These server options can be overridden by the `--server-option=` command + line arguments. ++ +This is a multi-valued variable, and an empty value can be used in a higher +priority configuration file (e.g. `.git/config` in a repository) to clear +the values inherited from a lower priority configuration files (e.g. +`$HOME/.gitconfig`). + +remote.<name>.followRemoteHEAD:: + How linkgit:git-fetch[1] should handle updates to `remotes/<name>/HEAD`. + The default value is "create", which will create `remotes/<name>/HEAD` + if it exists on the remote, but not locally; this will not touch an + already existing local reference. Setting it to "warn" will print + a message if the remote has a different value than the local one; + in case there is no local reference, it behaves like "create". + A variant on "warn" is "warn-if-not-$branch", which behaves like + "warn", but if `HEAD` on the remote is `$branch` it will be silent. + Setting it to "always" will silently update `remotes/<name>/HEAD` to + the value on the remote. Finally, setting it to "never" will never + change or create the local reference. diff --git a/Documentation/config/remotes.txt b/Documentation/config/remotes.adoc similarity index 100% rename from Documentation/config/remotes.txt rename to Documentation/config/remotes.adoc diff --git a/Documentation/config/repack.txt b/Documentation/config/repack.adoc similarity index 100% rename from Documentation/config/repack.txt rename to Documentation/config/repack.adoc diff --git a/Documentation/config/rerere.txt b/Documentation/config/rerere.adoc similarity index 100% rename from Documentation/config/rerere.txt rename to Documentation/config/rerere.adoc diff --git a/Documentation/config/revert.txt b/Documentation/config/revert.adoc similarity index 100% rename from Documentation/config/revert.txt rename to Documentation/config/revert.adoc diff --git a/Documentation/config/safe.txt b/Documentation/config/safe.adoc similarity index 100% rename from Documentation/config/safe.txt rename to Documentation/config/safe.adoc diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.adoc similarity index 100% rename from Documentation/config/sendemail.txt rename to Documentation/config/sendemail.adoc diff --git a/Documentation/config/sequencer.txt b/Documentation/config/sequencer.adoc similarity index 100% rename from Documentation/config/sequencer.txt rename to Documentation/config/sequencer.adoc diff --git a/Documentation/config/showbranch.txt b/Documentation/config/showbranch.adoc similarity index 100% rename from Documentation/config/showbranch.txt rename to Documentation/config/showbranch.adoc diff --git a/Documentation/config/sparse.txt b/Documentation/config/sparse.adoc similarity index 100% rename from Documentation/config/sparse.txt rename to Documentation/config/sparse.adoc diff --git a/Documentation/config/splitindex.txt b/Documentation/config/splitindex.adoc similarity index 100% rename from Documentation/config/splitindex.txt rename to Documentation/config/splitindex.adoc diff --git a/Documentation/config/ssh.txt b/Documentation/config/ssh.adoc similarity index 100% rename from Documentation/config/ssh.txt rename to Documentation/config/ssh.adoc diff --git a/Documentation/config/stash.txt b/Documentation/config/stash.adoc similarity index 100% rename from Documentation/config/stash.txt rename to Documentation/config/stash.adoc diff --git a/Documentation/config/status.txt b/Documentation/config/status.adoc similarity index 100% rename from Documentation/config/status.txt rename to Documentation/config/status.adoc diff --git a/Documentation/config/submodule.txt b/Documentation/config/submodule.adoc similarity index 100% rename from Documentation/config/submodule.txt rename to Documentation/config/submodule.adoc diff --git a/Documentation/config/survey.adoc b/Documentation/config/survey.adoc new file mode 100644 index 00000000000000..ab2217c7d54eb8 --- /dev/null +++ b/Documentation/config/survey.adoc @@ -0,0 +1,14 @@ +survey.*:: + These variables adjust the default behavior of the `git survey` + command. The intention is that this command could be run in the + background with these options. ++ +---- + verbose:: + This boolean value implies the `--[no-]verbose` option. + progress:: + This boolean value implies the `--[no-]progress` option. + top:: + This integer value implies `--top=<N>`, specifying the + number of entries in the detail tables. +---- diff --git a/Documentation/config/tag.txt b/Documentation/config/tag.adoc similarity index 100% rename from Documentation/config/tag.txt rename to Documentation/config/tag.adoc diff --git a/Documentation/config/tar.txt b/Documentation/config/tar.adoc similarity index 100% rename from Documentation/config/tar.txt rename to Documentation/config/tar.adoc diff --git a/Documentation/config/trace2.txt b/Documentation/config/trace2.adoc similarity index 98% rename from Documentation/config/trace2.txt rename to Documentation/config/trace2.adoc index 3b6bca2b7ae44c..05639ce33f908a 100644 --- a/Documentation/config/trace2.txt +++ b/Documentation/config/trace2.adoc @@ -17,7 +17,7 @@ trace2.eventTarget:: It may be overridden by the `GIT_TRACE2_EVENT` environment variable. The following table shows possible values. + -include::../trace2-target-values.txt[] +include::../trace2-target-values.adoc[] trace2.normalBrief:: Boolean. When true `time`, `filename`, and `line` fields are diff --git a/Documentation/config/trailer.adoc b/Documentation/config/trailer.adoc new file mode 100644 index 00000000000000..60bc221c88b801 --- /dev/null +++ b/Documentation/config/trailer.adoc @@ -0,0 +1,136 @@ +trailer.separators:: + This option tells which characters are recognized as trailer + separators. By default only ':' is recognized as a trailer + separator, except that '=' is always accepted on the command + line for compatibility with other git commands. ++ +The first character given by this option will be the default character +used when another separator is not specified in the config for this +trailer. ++ +For example, if the value for this option is "%=$", then only lines +using the format '<key><sep><value>' with <sep> containing '%', '=' +or '$' and then spaces will be considered trailers. And '%' will be +the default separator used, so by default trailers will appear like: +'<key>% <value>' (one percent sign and one space will appear between +the key and the value). + +trailer.where:: + This option tells where a new trailer will be added. ++ +This can be `end`, which is the default, `start`, `after` or `before`. ++ +If it is `end`, then each new trailer will appear at the end of the +existing trailers. ++ +If it is `start`, then each new trailer will appear at the start, +instead of the end, of the existing trailers. ++ +If it is `after`, then each new trailer will appear just after the +last trailer with the same <key>. ++ +If it is `before`, then each new trailer will appear just before the +first trailer with the same <key>. + +trailer.ifexists:: + This option makes it possible to choose what action will be + performed when there is already at least one trailer with the + same <key> in the input. ++ +The valid values for this option are: `addIfDifferentNeighbor` (this +is the default), `addIfDifferent`, `add`, `replace` or `doNothing`. ++ +With `addIfDifferentNeighbor`, a new trailer will be added only if no +trailer with the same (<key>, <value>) pair is above or below the line +where the new trailer will be added. ++ +With `addIfDifferent`, a new trailer will be added only if no trailer +with the same (<key>, <value>) pair is already in the input. ++ +With `add`, a new trailer will be added, even if some trailers with +the same (<key>, <value>) pair are already in the input. ++ +With `replace`, an existing trailer with the same <key> will be +deleted and the new trailer will be added. The deleted trailer will be +the closest one (with the same <key>) to the place where the new one +will be added. ++ +With `doNothing`, nothing will be done; that is no new trailer will be +added if there is already one with the same <key> in the input. + +trailer.ifmissing:: + This option makes it possible to choose what action will be + performed when there is not yet any trailer with the same + <key> in the input. ++ +The valid values for this option are: `add` (this is the default) and +`doNothing`. ++ +With `add`, a new trailer will be added. ++ +With `doNothing`, nothing will be done. + +trailer.<keyAlias>.key:: + Defines a <keyAlias> for the <key>. The <keyAlias> must be a + prefix (case does not matter) of the <key>. For example, in `git + config trailer.ack.key "Acked-by"` the "Acked-by" is the <key> and + the "ack" is the <keyAlias>. This configuration allows the shorter + `--trailer "ack:..."` invocation on the command line using the "ack" + <keyAlias> instead of the longer `--trailer "Acked-by:..."`. ++ +At the end of the <key>, a separator can appear and then some +space characters. By default the only valid separator is ':', +but this can be changed using the `trailer.separators` config +variable. ++ +If there is a separator in the key, then it overrides the default +separator when adding the trailer. + +trailer.<keyAlias>.where:: + This option takes the same values as the 'trailer.where' + configuration variable and it overrides what is specified by + that option for trailers with the specified <keyAlias>. + +trailer.<keyAlias>.ifexists:: + This option takes the same values as the 'trailer.ifexists' + configuration variable and it overrides what is specified by + that option for trailers with the specified <keyAlias>. + +trailer.<keyAlias>.ifmissing:: + This option takes the same values as the 'trailer.ifmissing' + configuration variable and it overrides what is specified by + that option for trailers with the specified <keyAlias>. + +trailer.<keyAlias>.command:: + Deprecated in favor of 'trailer.<keyAlias>.cmd'. + This option behaves in the same way as 'trailer.<keyAlias>.cmd', except + that it doesn't pass anything as argument to the specified command. + Instead the first occurrence of substring $ARG is replaced by the + <value> that would be passed as argument. ++ +Note that $ARG in the user's command is +only replaced once and that the original way of replacing $ARG is not safe. ++ +When both 'trailer.<keyAlias>.cmd' and 'trailer.<keyAlias>.command' are given +for the same <keyAlias>, 'trailer.<keyAlias>.cmd' is used and +'trailer.<keyAlias>.command' is ignored. + +trailer.<keyAlias>.cmd:: + This option can be used to specify a shell command that will be called + once to automatically add a trailer with the specified <keyAlias>, and then + called each time a '--trailer <keyAlias>=<value>' argument is specified to + modify the <value> of the trailer that this option would produce. ++ +When the specified command is first called to add a trailer +with the specified <keyAlias>, the behavior is as if a special +'--trailer <keyAlias>=<value>' argument was added at the beginning +of the "git interpret-trailers" command, where <value> +is taken to be the standard output of the command with any +leading and trailing whitespace trimmed off. ++ +If some '--trailer <keyAlias>=<value>' arguments are also passed +on the command line, the command is called again once for each +of these arguments with the same <keyAlias>. And the <value> part +of these arguments, if any, will be passed to the command as its +first argument. This way the command can produce a <value> computed +from the <value> passed in the '--trailer <keyAlias>=<value>' argument. diff --git a/Documentation/config/transfer.txt b/Documentation/config/transfer.adoc similarity index 100% rename from Documentation/config/transfer.txt rename to Documentation/config/transfer.adoc diff --git a/Documentation/config/uploadarchive.txt b/Documentation/config/uploadarchive.adoc similarity index 100% rename from Documentation/config/uploadarchive.txt rename to Documentation/config/uploadarchive.adoc diff --git a/Documentation/config/uploadpack.txt b/Documentation/config/uploadpack.adoc similarity index 95% rename from Documentation/config/uploadpack.txt rename to Documentation/config/uploadpack.adoc index 16264d82a722ec..0e1dda944a5490 100644 --- a/Documentation/config/uploadpack.txt +++ b/Documentation/config/uploadpack.adoc @@ -25,7 +25,11 @@ uploadpack.allowReachableSHA1InWant:: uploadpack.allowAnySHA1InWant:: Allow `upload-pack` to accept a fetch request that asks for any object at all. - Defaults to `false`. + It implies `uploadpack.allowTipSHA1InWant` and + `uploadpack.allowReachableSHA1InWant`. If set to `true` it will + enable both of them, it set to `false` it will disable both of + them. + By default not set. uploadpack.keepAlive:: When `upload-pack` has started `pack-objects`, there may be a diff --git a/Documentation/config/url.txt b/Documentation/config/url.adoc similarity index 100% rename from Documentation/config/url.txt rename to Documentation/config/url.adoc diff --git a/Documentation/config/user.txt b/Documentation/config/user.adoc similarity index 100% rename from Documentation/config/user.txt rename to Documentation/config/user.adoc diff --git a/Documentation/config/versionsort.txt b/Documentation/config/versionsort.adoc similarity index 100% rename from Documentation/config/versionsort.txt rename to Documentation/config/versionsort.adoc diff --git a/Documentation/config/web.txt b/Documentation/config/web.adoc similarity index 100% rename from Documentation/config/web.txt rename to Documentation/config/web.adoc diff --git a/Documentation/config/worktree.txt b/Documentation/config/worktree.adoc similarity index 51% rename from Documentation/config/worktree.txt rename to Documentation/config/worktree.adoc index 048e349482df6c..5e35c7d018aecd 100644 --- a/Documentation/config/worktree.txt +++ b/Documentation/config/worktree.adoc @@ -7,3 +7,13 @@ worktree.guessRemote:: such a branch exists, it is checked out and set as "upstream" for the new branch. If no such match can be found, it falls back to creating a new branch from the current HEAD. + +worktree.useRelativePaths:: + Link worktrees using relative paths (when "true") or absolute + paths (when "false"). This is particularly useful for setups + where the repository and worktrees may be moved between + different locations or environments. Defaults to "false". ++ +Note that setting `worktree.useRelativePaths` to "true" implies enabling the +`extension.relativeWorktrees` config (see linkgit:git-config[1]), +thus making it incompatible with older versions of Git. diff --git a/Documentation/date-formats.txt b/Documentation/date-formats.adoc similarity index 100% rename from Documentation/date-formats.txt rename to Documentation/date-formats.adoc diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.adoc similarity index 82% rename from Documentation/diff-format.txt rename to Documentation/diff-format.adoc index a3ae8747a226fc..80e36e153dac88 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.adoc @@ -1,25 +1,25 @@ Raw output format ----------------- -The raw output format from "git-diff-index", "git-diff-tree", -"git-diff-files" and "git diff --raw" are very similar. +The raw output format from `git-diff-index`, `git-diff-tree`, +`git-diff-files` and `git diff --raw` are very similar. These commands all compare two sets of things; what is compared differs: -git-diff-index <tree-ish>:: - compares the <tree-ish> and the files on the filesystem. +`git-diff-index <tree-ish>`:: + compares the _<tree-ish>_ and the files on the filesystem. -git-diff-index --cached <tree-ish>:: - compares the <tree-ish> and the index. +`git-diff-index --cached <tree-ish>`:: + compares the _<tree-ish>_ and the index. -git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]:: +`git-diff-tree [-r] <tree-ish-1> <tree-ish-2> [<pattern>...]`:: compares the trees named by the two arguments. -git-diff-files [<pattern>...]:: +`git-diff-files [<pattern>...]`:: compares the index and the files on the filesystem. -The "git-diff-tree" command begins its output by printing the hash of +The `git-diff-tree` command begins its output by printing the hash of what is being compared. After that, all the commands print one output line per changed file. @@ -54,19 +54,19 @@ That is, from the left to the right: Possible status letters are: -- A: addition of a file -- C: copy of a file into a new one -- D: deletion of a file -- M: modification of the contents or mode of a file -- R: renaming of a file -- T: change in the type of the file (regular file, symbolic link or submodule) -- U: file is unmerged (you must complete the merge before it can +- `A`: addition of a file +- `C`: copy of a file into a new one +- `D`: deletion of a file +- `M`: modification of the contents or mode of a file +- `R`: renaming of a file +- `T`: change in the type of the file (regular file, symbolic link or submodule) +- `U`: file is unmerged (you must complete the merge before it can be committed) -- X: "unknown" change type (most probably a bug, please report it) +- `X`: "unknown" change type (most probably a bug, please report it) -Status letters C and R are always followed by a score (denoting the +Status letters `C` and `R` are always followed by a score (denoting the percentage of similarity between the source and target of the move or -copy). Status letter M may be followed by a score (denoting the +copy). Status letter `M` may be followed by a score (denoting the percentage of dissimilarity) for file rewrites. The sha1 for "dst" is shown as all 0's if a file on the filesystem @@ -86,7 +86,7 @@ verbatim and the line is terminated by a NUL byte. diff format for merges ---------------------- -"git-diff-tree", "git-diff-files" and "git-diff --raw" +`git-diff-tree`, `git-diff-files` and `git-diff --raw` can take `-c` or `--cc` option to generate diff output also for merge commits. The output differs from the format described above in the following way: @@ -121,14 +121,14 @@ Note that 'combined diff' lists only files which were modified from all parents. -include::diff-generate-patch.txt[] +include::diff-generate-patch.adoc[] other diff formats ------------------ The `--summary` option describes newly added, deleted, renamed and -copied files. The `--stat` option adds diffstat(1) graph to the +copied files. The `--stat` option adds `diffstat`(1) graph to the output. These options can be combined with other options, such as `-p`, and are meant for human consumption. diff --git a/Documentation/diff-generate-patch.txt b/Documentation/diff-generate-patch.adoc similarity index 90% rename from Documentation/diff-generate-patch.txt rename to Documentation/diff-generate-patch.adoc index 4b5aa5c2e045f5..e5c813c96f3ac4 100644 --- a/Documentation/diff-generate-patch.txt +++ b/Documentation/diff-generate-patch.adoc @@ -14,7 +14,7 @@ You can customize the creation of patch text via the `GIT_EXTERNAL_DIFF` and the `GIT_DIFF_OPTS` environment variables (see linkgit:git[1]), and the `diff` attribute (see linkgit:gitattributes[5]). -What the -p option produces is slightly different from the traditional +What the `-p` option produces is slightly different from the traditional diff format: 1. It is preceded by a "git diff" header that looks like this: @@ -30,20 +30,21 @@ name of the source file of the rename/copy and the name of the file that the rename/copy produces, respectively. 2. It is followed by one or more extended header lines: - - old mode <mode> - new mode <mode> - deleted file mode <mode> - new file mode <mode> - copy from <path> - copy to <path> - rename from <path> - rename to <path> - similarity index <number> - dissimilarity index <number> - index <hash>..<hash> <mode> + -File modes are printed as 6-digit octal numbers including the file type +[synopsis] +old mode <mode> +new mode <mode> +deleted file mode <mode> +new file mode <mode> +copy from <path> +copy to <path> +rename from <path> +rename to <path> +similarity index <number> +dissimilarity index <number> +index <hash>..<hash> <mode> ++ +File modes _<mode>_ are printed as 6-digit octal numbers including the file type and file permission bits. + Path names in extended headers do not include the `a/` and `b/` prefixes. @@ -56,7 +57,7 @@ files, while 100% dissimilarity means that no line from the old file made it into the new one. + The index line includes the blob object names before and after the change. -The <mode> is included if the file mode does not change; otherwise, +The _<mode>_ is included if the file mode does not change; otherwise, separate lines indicate the old and the new mode. 3. Pathnames with "unusual" characters are quoted as explained for @@ -134,17 +135,18 @@ or like this (when the `--cc` option is used): 2. It is followed by one or more extended header lines (this example shows a merge with two parents): - - index <hash>,<hash>..<hash> - mode <mode>,<mode>..<mode> - new file mode <mode> - deleted file mode <mode>,<mode> ++ +[synopsis] +index <hash>,<hash>..<hash> +mode <mode>,<mode>`..`<mode> +new file mode <mode> +deleted file mode <mode>,<mode> + The `mode <mode>,<mode>..<mode>` line appears only if at least one of the <mode> is different from the rest. Extended headers with information about detected content movement (renames and copying detection) are designed to work with the diff of two -<tree-ish> and are not used by combined diff format. +_<tree-ish>_ and are not used by combined diff format. 3. It is followed by a two-line from-file/to-file header: diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.adoc similarity index 78% rename from Documentation/diff-options.txt rename to Documentation/diff-options.adoc index cd0b81adbb69d1..640eb6e7db58a5 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.adoc @@ -19,16 +19,16 @@ ifdef::git-format-patch[] endif::git-format-patch[] ifndef::git-format-patch[] --p:: --u:: ---patch:: +`-p`:: +`-u`:: +`--patch`:: Generate patch (see <<generate_patch_text_with_p>>). ifdef::git-diff[] This is the default. endif::git-diff[] --s:: ---no-patch:: +`-s`:: +`--no-patch`:: Suppress all output from the diff machinery. Useful for commands like `git show` that show the patch by default to squelch their output, or to cancel the effect of options like @@ -39,28 +39,28 @@ endif::git-format-patch[] ifdef::git-log[] -m:: Show diffs for merge commits in the default format. This is - similar to '--diff-merges=on', except `-m` will + similar to `--diff-merges=on`, except `-m` will produce no output unless `-p` is given as well. -c:: Produce combined diff output for merge commits. - Shortcut for '--diff-merges=combined -p'. + Shortcut for `--diff-merges=combined -p`. --cc:: Produce dense combined diff output for merge commits. - Shortcut for '--diff-merges=dense-combined -p'. + Shortcut for `--diff-merges=dense-combined -p`. --dd:: Produce diff with respect to first parent for both merge and regular commits. - Shortcut for '--diff-merges=first-parent -p'. + Shortcut for `--diff-merges=first-parent -p`. --remerge-diff:: Produce remerge-diff output for merge commits. - Shortcut for '--diff-merges=remerge -p'. + Shortcut for `--diff-merges=remerge -p`. --no-diff-merges:: - Synonym for '--diff-merges=off'. + Synonym for `--diff-merges=off`. --diff-merges=<format>:: Specify diff format to be used for merge commits. Default is @@ -73,33 +73,33 @@ The following formats are supported: off, none:: Disable output of diffs for merge commits. Useful to override implied value. -+ + on, m:: Make diff output for merge commits to be shown in the default format. The default format can be changed using `log.diffMerges` configuration variable, whose default value is `separate`. -+ + first-parent, 1:: Show full diff with respect to first parent. This is the same format as `--patch` produces for non-merge commits. -+ + separate:: Show full diff with respect to each of parents. Separate log entry and diff is generated for each parent. -+ + combined, c:: Show differences from each of the parents to the merge result simultaneously instead of showing pairwise diff between a parent and the result one at a time. Furthermore, it lists only files which were modified from all parents. -+ + dense-combined, cc:: Further compress output produced by `--diff-merges=combined` by omitting uninteresting hunks whose contents in the parents have only two variants and the merge result picks one of them without modification. -+ + remerge, r:: Remerge two-parent merge commits to create a temporary tree object--potentially containing files with conflict markers @@ -112,33 +112,33 @@ documented). -- --combined-all-paths:: - This flag causes combined diffs (used for merge commits) to + Cause combined diffs (used for merge commits) to list the name of the file from all parents. It thus only has effect when `--diff-merges=[dense-]combined` is in use, and is likely only useful if filename changes are detected (i.e. when either rename or copy detection have been requested). endif::git-log[] --U<n>:: ---unified=<n>:: - Generate diffs with <n> lines of context instead of +`-U<n>`:: +`--unified=<n>`:: + Generate diffs with _<n>_ lines of context instead of the usual three. ifndef::git-format-patch[] Implies `--patch`. endif::git-format-patch[] ---output=<file>:: +`--output=<file>`:: Output to a specific file instead of stdout. ---output-indicator-new=<char>:: ---output-indicator-old=<char>:: ---output-indicator-context=<char>:: +`--output-indicator-new=<char>`:: +`--output-indicator-old=<char>`:: +`--output-indicator-context=<char>`:: Specify the character used to indicate new, old or context - lines in the generated patch. Normally they are '+', '-' and + lines in the generated patch. Normally they are `+`, `-` and ' ' respectively. ifndef::git-format-patch[] ---raw:: +`--raw`:: ifndef::git-log[] Generate the diff in raw format. ifdef::git-diff-core[] @@ -155,54 +155,55 @@ endif::git-log[] endif::git-format-patch[] ifndef::git-format-patch[] ---patch-with-raw:: +`--patch-with-raw`:: Synonym for `-p --raw`. endif::git-format-patch[] ifdef::git-log[] --t:: +`-t`:: Show the tree objects in the diff output. endif::git-log[] ---indent-heuristic:: +`--indent-heuristic`:: Enable the heuristic that shifts diff hunk boundaries to make patches easier to read. This is the default. ---no-indent-heuristic:: +`--no-indent-heuristic`:: Disable the indent heuristic. ---minimal:: +`--minimal`:: Spend extra time to make sure the smallest possible diff is produced. ---patience:: +`--patience`:: Generate a diff using the "patience diff" algorithm. ---histogram:: +`--histogram`:: Generate a diff using the "histogram diff" algorithm. ---anchored=<text>:: +`--anchored=<text>`:: Generate a diff using the "anchored diff" algorithm. + This option may be specified more than once. + If a line exists in both the source and destination, exists only once, -and starts with this text, this algorithm attempts to prevent it from +and starts with _<text>_, this algorithm attempts to prevent it from appearing as a deletion or addition in the output. It uses the "patience diff" algorithm internally. ---diff-algorithm={patience|minimal|histogram|myers}:: +`--diff-algorithm=(patience|minimal|histogram|myers)`:: Choose a diff algorithm. The variants are as follows: + -- -`default`, `myers`;; + `default`;; + `myers`;; The basic greedy diff algorithm. Currently, this is the default. -`minimal`;; + `minimal`;; Spend extra time to make sure the smallest possible diff is produced. -`patience`;; + `patience`;; Use "patience diff" algorithm when generating patches. -`histogram`;; + `histogram`;; This algorithm extends the patience algorithm to "support low-occurrence common elements". -- @@ -211,47 +212,47 @@ For instance, if you configured the `diff.algorithm` variable to a non-default value and want to use the default one, then you have to use `--diff-algorithm=default` option. ---stat[=<width>[,<name-width>[,<count>]]]:: +`--stat[=<width>[,<name-width>[,<count>]]]`:: Generate a diffstat. By default, as much space as necessary will be used for the filename part, and the rest for the graph part. Maximum width defaults to terminal width, or 80 columns if not connected to a terminal, and can be overridden by - `<width>`. The width of the filename part can be limited by - giving another width `<name-width>` after a comma or by setting - `diff.statNameWidth=<width>`. The width of the graph part can be - limited by using `--stat-graph-width=<width>` or by setting - `diff.statGraphWidth=<width>`. Using `--stat` or + _<width>_. The width of the filename part can be limited by + giving another width _<name-width>_ after a comma or by setting + `diff.statNameWidth=<name-width>`. The width of the graph part can be + limited by using `--stat-graph-width=<graph-width>` or by setting + `diff.statGraphWidth=<graph-width>`. Using `--stat` or `--stat-graph-width` affects all commands generating a stat graph, while setting `diff.statNameWidth` or `diff.statGraphWidth` does not affect `git format-patch`. - By giving a third parameter `<count>`, you can limit the output to - the first `<count>` lines, followed by `...` if there are more. + By giving a third parameter _<count>_, you can limit the output to + the first _<count>_ lines, followed by `...` if there are more. + These parameters can also be set individually with `--stat-width=<width>`, `--stat-name-width=<name-width>` and `--stat-count=<count>`. ---compact-summary:: +`--compact-summary`:: Output a condensed summary of extended header information such - as file creations or deletions ("new" or "gone", optionally "+l" - if it's a symlink) and mode changes ("+x" or "-x" for adding + as file creations or deletions ("new" or "gone", optionally `+l` + if it's a symlink) and mode changes (`+x` or `-x` for adding or removing executable bit respectively) in diffstat. The information is put between the filename part and the graph part. Implies `--stat`. ---numstat:: +`--numstat`:: Similar to `--stat`, but shows number of added and deleted lines in decimal notation and pathname without abbreviation, to make it more machine friendly. For binary files, outputs two `-` instead of saying `0 0`. ---shortstat:: +`--shortstat`:: Output only the last line of the `--stat` format containing total number of modified files, as well as number of added and deleted lines. --X[<param1,param2,...>]:: ---dirstat[=<param1,param2,...>]:: +`-X [<param>,...]`:: +`--dirstat[=<param>,...]`:: Output the distribution of relative amount of changes for each sub-directory. The behavior of `--dirstat` can be customized by passing it a comma separated list of parameters. @@ -284,7 +285,7 @@ These parameters can also be set individually with `--stat-width=<width>`, Note that when using `cumulative`, the sum of the percentages reported may exceed 100%. The default (non-cumulative) behavior can be specified with the `noncumulative` parameter. -<limit>;; +_<limit>_;; An integer parameter specifies a cut-off percent (3% by default). Directories contributing less than this percentage of the changes are not shown in the output. @@ -295,29 +296,29 @@ directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: `--dirstat=files,10,cumulative`. ---cumulative:: - Synonym for --dirstat=cumulative +`--cumulative`:: + Synonym for `--dirstat=cumulative`. ---dirstat-by-file[=<param1,param2>...]:: - Synonym for --dirstat=files,<param1>,<param2>... +`--dirstat-by-file[=<param>,...]`:: + Synonym for `--dirstat=files,<param>,...`. ---summary:: +`--summary`:: Output a condensed summary of extended header information such as creations, renames and mode changes. ifndef::git-format-patch[] ---patch-with-stat:: +`--patch-with-stat`:: Synonym for `-p --stat`. endif::git-format-patch[] ifndef::git-format-patch[] --z:: +`-z`:: ifdef::git-log[] - Separate the commits with NULs instead of newlines. + Separate the commits with __NUL__s instead of newlines. + Also, when `--raw` or `--numstat` has been given, do not munge -pathnames and use NULs as output field terminators. +pathnames and use __NUL__s as output field terminators. endif::git-log[] ifndef::git-log[] When `--raw`, `--numstat`, `--name-only` or `--name-status` has been @@ -328,89 +329,89 @@ Without this option, pathnames with "unusual" characters are quoted as explained for the configuration variable `core.quotePath` (see linkgit:git-config[1]). ---name-only:: +`--name-only`:: Show only the name of each changed file in the post-image tree. The file names are often encoded in UTF-8. For more information see the discussion about encoding in the linkgit:git-log[1] manual page. ---name-status:: +`--name-status`:: Show only the name(s) and status of each changed file. See the description of the `--diff-filter` option on what the status letters mean. Just like `--name-only` the file names are often encoded in UTF-8. ---submodule[=<format>]:: +`--submodule[=<format>]`:: Specify how differences in submodules are shown. When specifying - `--submodule=short` the 'short' format is used. This format just + `--submodule=short` the `short` format is used. This format just shows the names of the commits at the beginning and end of the range. - When `--submodule` or `--submodule=log` is specified, the 'log' + When `--submodule` or `--submodule=log` is specified, the `log` format is used. This format lists the commits in the range like linkgit:git-submodule[1] `summary` does. When `--submodule=diff` - is specified, the 'diff' format is used. This format shows an + is specified, the `diff` format is used. This format shows an inline diff of the changes in the submodule contents between the - commit range. Defaults to `diff.submodule` or the 'short' format + commit range. Defaults to `diff.submodule` or the `short` format if the config option is unset. ---color[=<when>]:: +`--color[=<when>]`:: Show colored diff. - `--color` (i.e. without '=<when>') is the same as `--color=always`. - '<when>' can be one of `always`, `never`, or `auto`. + `--color` (i.e. without `=<when>`) is the same as `--color=always`. + _<when>_ can be one of `always`, `never`, or `auto`. ifdef::git-diff[] It can be changed by the `color.ui` and `color.diff` configuration settings. endif::git-diff[] ---no-color:: +`--no-color`:: Turn off colored diff. ifdef::git-diff[] This can be used to override configuration settings. endif::git-diff[] It is the same as `--color=never`. ---color-moved[=<mode>]:: +`--color-moved[=<mode>]`:: Moved lines of code are colored differently. ifdef::git-diff[] It can be changed by the `diff.colorMoved` configuration setting. endif::git-diff[] - The <mode> defaults to 'no' if the option is not given - and to 'zebra' if the option with no mode is given. + The _<mode>_ defaults to `no` if the option is not given + and to `zebra` if the option with no mode is given. The mode must be one of: + -- -no:: +`no`:: Moved lines are not highlighted. -default:: +`default`:: Is a synonym for `zebra`. This may change to a more sensible mode in the future. -plain:: +`plain`:: Any line that is added in one location and was removed - in another location will be colored with 'color.diff.newMoved'. - Similarly 'color.diff.oldMoved' will be used for removed lines + in another location will be colored with `color.diff.newMoved`. + Similarly `color.diff.oldMoved` will be used for removed lines that are added somewhere else in the diff. This mode picks up any moved line, but it is not very useful in a review to determine if a block of code was moved without permutation. -blocks:: +`blocks`:: Blocks of moved text of at least 20 alphanumeric characters are detected greedily. The detected blocks are - painted using either the 'color.diff.{old,new}Moved' color. + painted using either the `color.diff.(old|new)Moved` color. Adjacent blocks cannot be told apart. -zebra:: - Blocks of moved text are detected as in 'blocks' mode. The blocks - are painted using either the 'color.diff.{old,new}Moved' color or - 'color.diff.{old,new}MovedAlternative'. The change between +`zebra`:: + Blocks of moved text are detected as in `blocks` mode. The blocks + are painted using either the `color.diff.(old|new)Moved` color or + `color.diff.(old|new)MovedAlternative`. The change between the two colors indicates that a new block was detected. -dimmed-zebra:: - Similar to 'zebra', but additional dimming of uninteresting parts +`dimmed-zebra`:: + Similar to `zebra`, but additional dimming of uninteresting parts of moved code is performed. The bordering lines of two adjacent blocks are considered interesting, the rest is uninteresting. `dimmed_zebra` is a deprecated synonym. -- ---no-color-moved:: +`--no-color-moved`:: Turn off move detection. This can be used to override configuration settings. It is the same as `--color-moved=no`. ---color-moved-ws=<modes>:: +`--color-moved-ws=<mode>,...`:: This configures how whitespace is ignored when performing the move detection for `--color-moved`. ifdef::git-diff[] @@ -419,63 +420,62 @@ endif::git-diff[] These modes can be given as a comma separated list: + -- -no:: +`no`:: Do not ignore whitespace when performing move detection. -ignore-space-at-eol:: +`ignore-space-at-eol`:: Ignore changes in whitespace at EOL. -ignore-space-change:: +`ignore-space-change`:: Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent. -ignore-all-space:: +`ignore-all-space`:: Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none. -allow-indentation-change:: +`allow-indentation-change`:: Initially ignore any whitespace in the move detection, then group the moved code blocks only into a block if the change in whitespace is the same per line. This is incompatible with the other modes. -- ---no-color-moved-ws:: +`--no-color-moved-ws`:: Do not ignore whitespace when performing move detection. This can be used to override configuration settings. It is the same as `--color-moved-ws=no`. ---word-diff[=<mode>]:: - Show a word diff, using the <mode> to delimit changed words. +`--word-diff[=<mode>]`:: By default, words are delimited by whitespace; see - `--word-diff-regex` below. The <mode> defaults to 'plain', and + `--word-diff-regex` below. The _<mode>_ defaults to `plain`, and must be one of: + -- -color:: +`color`:: Highlight changed words using only colors. Implies `--color`. -plain:: - Show words as `[-removed-]` and `{+added+}`. Makes no +`plain`:: + Show words as ++[-removed-]++ and ++{+added+}++. Makes no attempts to escape the delimiters if they appear in the input, so the output may be ambiguous. -porcelain:: +`porcelain`:: Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff format, starting with a `+`/`-`/` ` character at the beginning of the line and extending to the end of the line. Newlines in the input are represented by a tilde `~` on a line of its own. -none:: +`none`:: Disable word diff again. -- + Note that despite the name of the first mode, color is used to highlight the changed parts in all modes if enabled. ---word-diff-regex=<regex>:: - Use <regex> to decide what a word is, instead of considering +`--word-diff-regex=<regex>`:: + Use _<regex>_ to decide what a word is, instead of considering runs of non-whitespace to be a word. Also implies `--word-diff` unless it was already enabled. + Every non-overlapping match of the -<regex> is considered a word. Anything between these matches is +_<regex>_ is considered a word. Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences. You may want to append `|[^[:space:]]` to your regular expression to make sure that it matches all non-whitespace characters. @@ -490,20 +490,20 @@ linkgit:gitattributes[5] or linkgit:git-config[1]. Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings. ---color-words[=<regex>]:: +`--color-words[=<regex>]`:: Equivalent to `--word-diff=color` plus (if a regex was specified) `--word-diff-regex=<regex>`. endif::git-format-patch[] ---no-renames:: +`--no-renames`:: Turn off rename detection, even when the configuration file gives the default to do so. ---[no-]rename-empty:: +`--[no-]rename-empty`:: Whether to use empty blobs as rename source. ifndef::git-format-patch[] ---check:: +`--check`:: Warn if changes introduce conflict markers or whitespace errors. What are considered whitespace errors is controlled by `core.whitespace` configuration. By default, trailing whitespaces (including @@ -511,9 +511,9 @@ ifndef::git-format-patch[] that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors. Exits with non-zero status if problems are found. Not compatible - with --exit-code. + with `--exit-code`. ---ws-error-highlight=<kind>:: +`--ws-error-highlight=<kind>`:: Highlight whitespace errors in the `context`, `old` or `new` lines of the diff. Multiple values are separated by comma, `none` resets previous values, `default` reset the list to @@ -525,30 +525,30 @@ ifndef::git-format-patch[] endif::git-format-patch[] ---full-index:: +`--full-index`:: Instead of the first handful of characters, show the full pre- and post-image blob object names on the "index" line when generating patch format output. ---binary:: +`--binary`:: In addition to `--full-index`, output a binary diff that can be applied with `git-apply`. ifndef::git-format-patch[] Implies `--patch`. endif::git-format-patch[] ---abbrev[=<n>]:: +`--abbrev[=<n>]`:: Instead of showing the full 40-byte hexadecimal object name in diff-raw format output and diff-tree header - lines, show the shortest prefix that is at least '<n>' + lines, show the shortest prefix that is at least _<n>_ hexdigits long that uniquely refers the object. In diff-patch output format, `--full-index` takes higher precedence, i.e. if `--full-index` is specified, full blob names will be shown regardless of `--abbrev`. Non default number of digits can be specified with `--abbrev=<n>`. --B[<n>][/<m>]:: ---break-rewrites[=[<n>][/<m>]]:: +`-B[<n>][/<m>]`:: +`--break-rewrites[=[<n>][/<m>]]`:: Break complete rewrite changes into pairs of delete and create. This serves two purposes: + @@ -556,22 +556,22 @@ It affects the way a change that amounts to a total rewrite of a file not as a series of deletion and insertion mixed together with a very few lines that happen to match textually as the context, but as a single deletion of everything old followed by a single insertion of -everything new, and the number `m` controls this aspect of the -B +everything new, and the number _<m>_ controls this aspect of the `-B` option (defaults to 60%). `-B/70%` specifies that less than 30% of the original should remain in the result for Git to consider it a total rewrite (i.e. otherwise the resulting patch will be a series of deletion and insertion mixed together with context lines). + -When used with -M, a totally-rewritten file is also considered as the -source of a rename (usually -M only considers a file that disappeared -as the source of a rename), and the number `n` controls this aspect of -the -B option (defaults to 50%). `-B20%` specifies that a change with +When used with `-M`, a totally-rewritten file is also considered as the +source of a rename (usually `-M` only considers a file that disappeared +as the source of a rename), and the number _<n>_ controls this aspect of +the `-B` option (defaults to 50%). `-B20%` specifies that a change with addition and deletion compared to 20% or more of the file's size are eligible for being picked up as a possible source of a rename to another file. --M[<n>]:: ---find-renames[=<n>]:: +`-M[<n>]`:: +`--find-renames[=<n>]`:: ifndef::git-log[] Detect renames. endif::git-log[] @@ -580,7 +580,7 @@ ifdef::git-log[] For following files across renames while traversing history, see `--follow`. endif::git-log[] - If `n` is specified, it is a threshold on the similarity + If _<n>_ is specified, it is a threshold on the similarity index (i.e. amount of addition/deletions compared to the file's size). For example, `-M90%` means Git should consider a delete/add pair to be a rename if more than 90% of the file @@ -590,12 +590,12 @@ endif::git-log[] the same as `-M5%`. To limit detection to exact renames, use `-M100%`. The default similarity index is 50%. --C[<n>]:: ---find-copies[=<n>]:: +`-C[<n>]`:: +`--find-copies[=<n>]`:: Detect copies as well as renames. See also `--find-copies-harder`. - If `n` is specified, it has the same meaning as for `-M<n>`. + If _<n>_ is specified, it has the same meaning as for `-M<n>`. ---find-copies-harder:: +`--find-copies-harder`:: For performance reasons, by default, `-C` option finds copies only if the original file of the copy was modified in the same changeset. This flag makes the command @@ -604,8 +604,8 @@ endif::git-log[] projects, so use it with caution. Giving more than one `-C` option has the same effect. --D:: ---irreversible-delete:: +`-D`:: +`--irreversible-delete`:: Omit the preimage for deletes, i.e. print only the header but not the diff between the preimage and `/dev/null`. The resulting patch is not meant to be applied with `patch` or `git apply`; this is @@ -617,7 +617,7 @@ endif::git-log[] When used together with `-B`, omit also the preimage in the deletion part of a delete/create pair. --l<num>:: +`-l<num>`:: The `-M` and `-C` options involve some preliminary steps that can detect subsets of renames/copies cheaply, followed by an exhaustive fallback portion that compares all remaining @@ -627,11 +627,11 @@ of a delete/create pair. destinations, this exhaustive check is O(N^2). This option prevents the exhaustive portion of rename/copy detection from running if the number of source/destination files involved - exceeds the specified number. Defaults to diff.renameLimit. + exceeds the specified number. Defaults to `diff.renameLimit`. Note that a value of 0 is treated as unlimited. ifndef::git-format-patch[] ---diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]:: +`--diff-filter=[(A|C|D|M|R|T|U|X|B)...[*]]`:: Select only files that are Added (`A`), Copied (`C`), Deleted (`D`), Modified (`M`), Renamed (`R`), have their type (i.e. regular file, symlink, submodule, ...) changed (`T`), @@ -649,9 +649,9 @@ Also, these upper-case letters can be downcased to exclude. E.g. Note that not all diffs can feature all types. For instance, copied and renamed entries cannot appear if detection for those types is disabled. --S<string>:: +`-S<string>`:: Look for differences that change the number of occurrences of - the specified string (i.e. addition/deletion) in a file. + the specified _<string>_ (i.e. addition/deletion) in a file. Intended for the scripter's use. + It is useful when you're looking for an exact block of code (like a @@ -662,11 +662,11 @@ very first version of the block. + Binary files are searched as well. --G<regex>:: +`-G<regex>`:: Look for differences whose patch text contains added/removed - lines that match <regex>. + lines that match _<regex>_. + -To illustrate the difference between `-S<regex> --pickaxe-regex` and +To illustrate the difference between `-S<regex>` `--pickaxe-regex` and `-G<regex>`, consider a commit with the following diff in the same file: + @@ -686,7 +686,7 @@ filter will be ignored. See the 'pickaxe' entry in linkgit:gitdiffcore[7] for more information. ---find-object=<object-id>:: +`--find-object=<object-id>`:: Look for differences that change the number of occurrences of the specified object. Similar to `-S`, just the argument is different in that it doesn't search for a specific string but for a specific @@ -695,25 +695,25 @@ information. The object can be a blob or a submodule commit. It implies the `-t` option in `git-log` to also find trees. ---pickaxe-all:: +`--pickaxe-all`:: When `-S` or `-G` finds a change, show all the changes in that changeset, not just the files that contain the change - in <string>. + in _<string>_. ---pickaxe-regex:: - Treat the <string> given to `-S` as an extended POSIX regular +`--pickaxe-regex`:: + Treat the _<string>_ given to `-S` as an extended POSIX regular expression to match. endif::git-format-patch[] --O<orderfile>:: +`-O<orderfile>`:: Control the order in which files appear in the output. This overrides the `diff.orderFile` configuration variable (see linkgit:git-config[1]). To cancel `diff.orderFile`, use `-O/dev/null`. + The output order is determined by the order of glob patterns in -<orderfile>. +_<orderfile>_. All files with pathnames that match the first pattern are output first, all files with pathnames that match the second pattern (but not the first) are output next, and so on. @@ -724,7 +724,7 @@ If multiple pathnames have the same rank (they match the same pattern but no earlier patterns), their output order relative to each other is the normal order. + -<orderfile> is parsed as follows: +_<orderfile>_ is parsed as follows: + -- - Blank lines are ignored, so they can be used as separators for @@ -738,106 +738,107 @@ the normal order. -- + Patterns have the same syntax and semantics as patterns used for -fnmatch(3) without the FNM_PATHNAME flag, except a pathname also +`fnmatch`(3) without the `FNM_PATHNAME` flag, except a pathname also matches a pattern if removing any number of the final pathname components matches the pattern. For example, the pattern "`foo*bar`" matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`". ---skip-to=<file>:: ---rotate-to=<file>:: - Discard the files before the named <file> from the output +`--skip-to=<file>`:: +`--rotate-to=<file>`:: + Discard the files before the named _<file>_ from the output (i.e. 'skip to'), or move them to the end of the output (i.e. 'rotate to'). These options were invented primarily for the use of the `git difftool` command, and may not be very useful otherwise. ifndef::git-format-patch[] --R:: +`-R`:: Swap two inputs; that is, show differences from index or on-disk file to tree contents. endif::git-format-patch[] ---relative[=<path>]:: ---no-relative:: +`--relative[=<path>]`:: +`--no-relative`:: When run from a subdirectory of the project, it can be told to exclude changes outside the directory and show pathnames relative to it with this option. When you are not in a subdirectory (e.g. in a bare repository), you can name which subdirectory to make the output relative - to by giving a <path> as an argument. + to by giving a _<path>_ as an argument. `--no-relative` can be used to countermand both `diff.relative` config option and previous `--relative`. --a:: ---text:: +`-a`:: +`--text`:: Treat all files as text. ---ignore-cr-at-eol:: +`--ignore-cr-at-eol`:: Ignore carriage-return at the end of line when doing a comparison. ---ignore-space-at-eol:: +`--ignore-space-at-eol`:: Ignore changes in whitespace at EOL. --b:: ---ignore-space-change:: +`-b`:: +`--ignore-space-change`:: Ignore changes in amount of whitespace. This ignores whitespace at line end, and considers all other sequences of one or more whitespace characters to be equivalent. --w:: ---ignore-all-space:: +`-w`:: +`--ignore-all-space`:: Ignore whitespace when comparing lines. This ignores differences even if one line has whitespace where the other line has none. ---ignore-blank-lines:: +`--ignore-blank-lines`:: Ignore changes whose lines are all blank. --I<regex>:: ---ignore-matching-lines=<regex>:: - Ignore changes whose all lines match <regex>. This option may + +`-I<regex>`:: +`--ignore-matching-lines=<regex>`:: + Ignore changes whose all lines match _<regex>_. This option may be specified more than once. ---inter-hunk-context=<lines>:: - Show the context between diff hunks, up to the specified number +`--inter-hunk-context=<number>`:: + Show the context between diff hunks, up to the specified _<number>_ of lines, thereby fusing hunks that are close to each other. Defaults to `diff.interHunkContext` or 0 if the config option is unset. --W:: ---function-context:: +`-W`:: +`--function-context`:: Show whole function as context lines for each change. The function names are determined in the same way as - `git diff` works out patch hunk headers (see 'Defining a - custom hunk-header' in linkgit:gitattributes[5]). + `git diff` works out patch hunk headers (see "Defining a + custom hunk-header" in linkgit:gitattributes[5]). ifndef::git-format-patch[] ifndef::git-log[] ---exit-code:: - Make the program exit with codes similar to diff(1). +`--exit-code`:: + Make the program exit with codes similar to `diff`(1). That is, it exits with 1 if there were differences and 0 means no differences. ---quiet:: +`--quiet`:: Disable all output of the program. Implies `--exit-code`. Disables execution of external diff helpers whose exit code is not trusted, i.e. their respective configuration option - `diff.trustExitCode` or `diff.<driver>.trustExitCode` or + `diff.trustExitCode` or ++diff.++__<driver>__++.trustExitCode++ or environment variable `GIT_EXTERNAL_DIFF_TRUST_EXIT_CODE` is false. endif::git-log[] endif::git-format-patch[] ---ext-diff:: +`--ext-diff`:: Allow an external diff helper to be executed. If you set an external diff driver with linkgit:gitattributes[5], you need to use this option with linkgit:git-log[1] and friends. ---no-ext-diff:: +`--no-ext-diff`:: Disallow external diff drivers. ---textconv:: ---no-textconv:: +`--textconv`:: +`--no-textconv`:: Allow (or disallow) external text conversion filters to be run when comparing binary files. See linkgit:gitattributes[5] for details. Because textconv filters are typically a one-way @@ -847,42 +848,42 @@ endif::git-format-patch[] linkgit:git-log[1], but not for linkgit:git-format-patch[1] or diff plumbing commands. ---ignore-submodules[=<when>]:: - Ignore changes to submodules in the diff generation. <when> can be - either "none", "untracked", "dirty" or "all", which is the default. - Using "none" will consider the submodule modified when it either contains - untracked or modified files or its HEAD differs from the commit recorded + +`--ignore-submodules[=(none|untracked|dirty|all)]`:: + Ignore changes to submodules in the diff generation. `all` is the default. + Using `none` will consider the submodule modified when it either contains + untracked or modified files or its `HEAD` differs from the commit recorded in the superproject and can be used to override any settings of the - 'ignore' option in linkgit:git-config[1] or linkgit:gitmodules[5]. When - "untracked" is used submodules are not considered dirty when they only + `ignore` option in linkgit:git-config[1] or linkgit:gitmodules[5]. When + `untracked` is used submodules are not considered dirty when they only contain untracked content (but they are still scanned for modified - content). Using "dirty" ignores all changes to the work tree of submodules, + content). Using `dirty` ignores all changes to the work tree of submodules, only changes to the commits stored in the superproject are shown (this was - the behavior until 1.7.0). Using "all" hides all changes to submodules. + the behavior until 1.7.0). Using `all` hides all changes to submodules. ---src-prefix=<prefix>:: - Show the given source prefix instead of "a/". +`--src-prefix=<prefix>`:: + Show the given source _<prefix>_ instead of "a/". ---dst-prefix=<prefix>:: - Show the given destination prefix instead of "b/". +`--dst-prefix=<prefix>`:: + Show the given destination _<prefix>_ instead of "b/". ---no-prefix:: +`--no-prefix`:: Do not show any source or destination prefix. ---default-prefix:: +`--default-prefix`:: Use the default source and destination prefixes ("a/" and "b/"). This overrides configuration variables such as `diff.noprefix`, `diff.srcPrefix`, `diff.dstPrefix`, and `diff.mnemonicPrefix` - (see `git-config`(1)). + (see linkgit:git-config[1]). ---line-prefix=<prefix>:: - Prepend an additional prefix to every line of output. +`--line-prefix=<prefix>`:: + Prepend an additional _<prefix>_ to every line of output. ---ita-invisible-in-index:: - By default entries added by "git add -N" appear as an existing - empty file in "git diff" and a new file in "git diff --cached". - This option makes the entry appear as a new file in "git diff" - and non-existent in "git diff --cached". This option could be +`--ita-invisible-in-index`:: + By default entries added by `git add -N` appear as an existing + empty file in `git diff` and a new file in `git diff --cached`. + This option makes the entry appear as a new file in `git diff` + and non-existent in `git diff --cached`. This option could be reverted with `--ita-visible-in-index`. Both options are experimental and could be removed in future. diff --git a/Documentation/everyday.txto b/Documentation/everyday.adoco similarity index 100% rename from Documentation/everyday.txto rename to Documentation/everyday.adoco diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.adoc similarity index 98% rename from Documentation/fetch-options.txt rename to Documentation/fetch-options.adoc index 80838fe37ef30e..b01372e4b3c659 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.adoc @@ -29,7 +29,7 @@ Deepen or shorten the history of a shallow repository to include all reachable commits after <date>. ---shallow-exclude=<revision>:: +--shallow-exclude=<ref>:: Deepen or shorten the history of a shallow repository to exclude commits reachable from a specified remote branch or tag. This option can be specified multiple times. @@ -305,6 +305,9 @@ endif::git-pull[] unknown ones, is server-specific. When multiple `--server-option=<option>` are given, they are all sent to the other side in the order listed on the command line. + When no `--server-option=<option>` is given from the command line, + the values of configuration variable `remote.<name>.serverOption` + are used instead. --show-forced-updates:: By default, git checks if a branch is force-updated during diff --git a/Documentation/fsck-msgids.txt b/Documentation/fsck-msgids.adoc similarity index 75% rename from Documentation/fsck-msgids.txt rename to Documentation/fsck-msgids.adoc index 68a2801f1529df..b14bc44ca4791f 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.adoc @@ -19,12 +19,18 @@ `badParentSha1`:: (ERROR) A commit object has a bad parent sha1. +`badRefContent`:: + (ERROR) A ref has bad content. + `badRefFiletype`:: (ERROR) A ref has a bad file type. `badRefName`:: (ERROR) A ref has an invalid format. +`badReferentName`:: + (ERROR) The referent name of a symref is invalid. + `badTagName`:: (INFO) A tag has an invalid format. @@ -170,6 +176,35 @@ `nullSha1`:: (WARN) Tree contains entries pointing to a null sha1. +`refMissingNewline`:: + (INFO) A loose ref that does not end with newline(LF). As + valid implementations of Git never created such a loose ref + file, it may become an error in the future. Report to the + git@vger.kernel.org mailing list if you see this error, as + we need to know what tools created such a file. + +`symlinkRef`:: + (INFO) A symbolic link is used as a symref. Report to the + git@vger.kernel.org mailing list if you see this error, as we + are assessing the feasibility of dropping the support to drop + creating symbolic links as symrefs. + +`symrefTargetIsNotARef`:: + (INFO) The target of a symbolic reference points neither to + a root reference nor to a reference starting with "refs/". + Although we allow create a symref pointing to the referent which + is outside the "ref" by using `git symbolic-ref`, we may tighten + the rule in the future. Report to the git@vger.kernel.org + mailing list if you see this error, as we need to know what tools + created such a file. + +`trailingRefContent`:: + (INFO) A loose ref has trailing content. As valid implementations + of Git never created such a loose ref file, it may become an + error in the future. Report to the git@vger.kernel.org mailing + list if you see this error, as we need to know what tools + created such a file. + `treeNotSorted`:: (ERROR) A tree is not properly sorted. diff --git a/Documentation/generate-mergetool-list.sh b/Documentation/generate-mergetool-list.sh new file mode 100755 index 00000000000000..6700498b93be53 --- /dev/null +++ b/Documentation/generate-mergetool-list.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +if test "$#" -ne 3 +then + echo >&2 "USAGE: $0 <SOURCE_DIR> <MODE> <OUTPUT>" + exit 1 +fi + +SOURCE_DIR="$1" +TOOL_MODE="$2" +OUTPUT="$3" +MERGE_TOOLS_DIR="$SOURCE_DIR/mergetools" + +( + . "$SOURCE_DIR"/git-mergetool--lib.sh && + show_tool_names can_$TOOL_MODE +) | sed -e "s/\([a-z0-9]*\)/\`\1\`;;/" >"$OUTPUT" diff --git a/Documentation/git-add.txt b/Documentation/git-add.adoc similarity index 88% rename from Documentation/git-add.txt rename to Documentation/git-add.adoc index aceaa025e3020a..eba0b419ce508f 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.adoc @@ -7,12 +7,12 @@ git-add - Add file contents to the index SYNOPSIS -------- -[verse] -'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] - [--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>...] +[synopsis] +git add [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p] + [--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>...] DESCRIPTION ----------- @@ -41,7 +41,7 @@ The `git add` command will not add ignored files by default. If any ignored files were explicitly specified on the command line, `git add` will fail with a list of ignored files. Ignored files reached by directory recursion or filename globbing performed by Git (quote your -globs before the shell) will be silently ignored. The 'git add' command can +globs before the shell) will be silently ignored. The `git add` command can be used to add ignored files with the `-f` (force) option. Please see linkgit:git-commit[1] for alternative ways to add content to a @@ -50,7 +50,7 @@ commit. OPTIONS ------- -<pathspec>...:: +`<pathspec>...`:: Files to add content from. Fileglobs (e.g. `*.c`) can be given to add all matching files. Also a leading directory name (e.g. `dir` to add `dir/file1` @@ -66,35 +66,35 @@ OPTIONS For more details about the _<pathspec>_ syntax, see the 'pathspec' entry in linkgit:gitglossary[7]. --n:: ---dry-run:: +`-n`:: +`--dry-run`:: Don't actually add the file(s), just show if they exist and/or will be ignored. --v:: ---verbose:: +`-v`:: +`--verbose`:: Be verbose. --f:: ---force:: +`-f`:: +`--force`:: Allow adding otherwise ignored files. ---sparse:: +`--sparse`:: Allow updating index entries outside of the sparse-checkout cone. Normally, `git add` refuses to update index entries whose paths do not fit within the sparse-checkout cone, since those files might be removed from the working tree without warning. See linkgit:git-sparse-checkout[1] for more details. --i:: ---interactive:: +`-i`:: +`--interactive`:: Add modified contents in the working tree interactively to the index. Optional path arguments may be supplied to limit operation to a subset of the working tree. See ``Interactive mode'' for details. --p:: ---patch:: +`-p`:: +`--patch`:: Interactively choose hunks of patch between the index and the work tree and add them to the index. This gives the user a chance to review the difference before adding modified contents to the @@ -104,8 +104,8 @@ This effectively runs `add --interactive`, but bypasses the initial command menu and directly jumps to the `patch` subcommand. See ``Interactive mode'' for details. --e:: ---edit:: +`-e`:: +`--edit`:: Open the diff vs. the index in an editor and let the user edit it. After the editor was closed, adjust the hunk headers and apply the patch to the index. @@ -116,8 +116,8 @@ quicker and more flexible than using the interactive hunk selector. However, it is easy to confuse oneself and create a patch that does not apply to the index. See EDITING PATCHES below. --u:: ---update:: +`-u`:: +`--update`:: Update the index just where it already has an entry matching _<pathspec>_. This removes as well as modifies index entries to match the working tree, but adds no new files. @@ -127,9 +127,9 @@ 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). --A:: ---all:: ---no-ignore-removal:: +`-A`:: +`--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 entry. This adds, modifies, and removes index entries to @@ -140,77 +140,77 @@ files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories). ---no-all:: ---ignore-removal:: +`--no-all`:: +`--ignore-removal`:: 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. + 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:: +`-N`:: +`--intent-to-add`:: Record only the fact that the path will be added later. An entry for the path is placed in the index with no content. This is useful for, among other things, showing the unstaged content of such files with `git diff` and committing them with `git commit -a`. ---refresh:: +`--refresh`:: Don't add the file(s), but only refresh their stat() information in the index. ---ignore-errors:: +`--ignore-errors`:: If some files could not be added because of errors indexing them, do not abort the operation, but continue adding the others. The command shall still exit with non-zero status. The configuration variable `add.ignoreErrors` can be set to true to make this the default behaviour. ---ignore-missing:: - This option can only be used together with --dry-run. By using +`--ignore-missing`:: + This option can only be used together with `--dry-run`. By using this option the user can check if any of the given files would be ignored, no matter if they are already present in the work tree or not. ---no-warn-embedded-repo:: +`--no-warn-embedded-repo`:: By default, `git add` will warn when adding an embedded repository to the index without using `git submodule add` to create an entry in `.gitmodules`. This option will suppress the warning (e.g., if you are manually performing operations on submodules). ---renormalize:: +`--renormalize`:: Apply the "clean" process freshly to all tracked files to forcibly add them again to the index. This is useful after changing `core.autocrlf` configuration or the `text` attribute - in order to correct files added with wrong CRLF/LF line endings. + in order to correct files added with wrong _CRLF/LF_ line endings. This option implies `-u`. Lone CR characters are untouched, thus - while a CRLF cleans to LF, a CRCRLF sequence is only partially - cleaned to CRLF. + while a _CRLF_ cleans to _LF_, a _CRCRLF_ sequence is only partially + cleaned to _CRLF_. ---chmod=(+|-)x:: +`--chmod=(+|-)x`:: Override the executable bit of the added files. The executable bit is only changed in the index, the files on disk are left unchanged. ---pathspec-from-file=<file>:: +`--pathspec-from-file=<file>`:: 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 + 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 global `--literal-pathspecs`. ---pathspec-file-nul:: +`--pathspec-file-nul`:: Only meaningful with `--pathspec-from-file`. Pathspec elements are - separated with NUL character and all other characters are taken + separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). -\--:: +`--`:: This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken for command-line options). @@ -219,18 +219,18 @@ for "git add --no-all _<pathspec>_...", i.e. ignored removed files. EXAMPLES -------- -* Adds content from all `*.txt` files under `Documentation` directory +* Adds content from all ++*.txt++ files under `Documentation` directory and its subdirectories: + ------------ $ git add Documentation/\*.txt ------------ + -Note that the asterisk `*` is quoted from the shell in this +Note that the asterisk ++*++ is quoted from the shell in this example; this lets the command include the files from subdirectories of `Documentation/` directory. -* Considers adding content from all git-*.sh scripts: +* Considers adding content from all ++git-*.sh++ scripts: + ------------ $ git add git-*.sh @@ -265,7 +265,7 @@ The main command loop has 6 subcommands (plus help and quit). status:: - This shows the change between HEAD and index (i.e. what will be + This shows the change between `HEAD` and index (i.e. what will be committed if you say `git commit`), and between index and working tree files (i.e. what you could stage further before `git commit` using `git add`) for each path. A sample output @@ -277,12 +277,12 @@ status:: 2: +403/-35 +1/-1 add-interactive.c ------------ + -It shows that foo.png has differences from HEAD (but that is +It shows that `foo.png` has differences from `HEAD` (but that is binary so line count cannot be shown) and there is no difference between indexed copy and the working tree version (if the working tree version were also different, 'binary' would have been shown in place of 'nothing'). The -other file, add-interactive.c, has 403 lines added +other file, `add-interactive.c`, has 403 lines added and 35 lines deleted if you commit what is in the index, but working tree file has further modifications (one addition and one deletion). @@ -360,7 +360,7 @@ variable `interactive.singleKey` to `true`. diff:: This lets you review what will be committed (i.e. between - HEAD and index). + `HEAD` and index). EDITING PATCHES @@ -399,7 +399,7 @@ There are also more complex operations that can be performed. But beware that because the patch is applied only to the index and not the working tree, the working tree will appear to "undo" the change in the index. For example, introducing a new line into the index that is in neither -the HEAD nor the working tree will stage the new line for commit, but +the `HEAD` nor the working tree will stage the new line for commit, but the line will appear to be reverted in the working tree. Avoid using these constructs, or do so with extreme caution. @@ -437,9 +437,10 @@ they will make the patch impossible to apply: CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/add.txt[] +:git-add: 1 +include::config/add.adoc[] SEE ALSO -------- diff --git a/Documentation/git-am.txt b/Documentation/git-am.adoc similarity index 98% rename from Documentation/git-am.txt rename to Documentation/git-am.adoc index 69d5cc9f210825..221070de481227 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.adoc @@ -120,7 +120,7 @@ default. You can use `--no-utf8` to override this. am.threeWay configuration variable. For more information, see am.threeWay in linkgit:git-config[1]. -include::rerere-options.txt[] +include::rerere-options.adoc[] --ignore-space-change:: --ignore-whitespace:: @@ -284,9 +284,9 @@ information. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/am.txt[] +include::config/am.adoc[] SEE ALSO -------- diff --git a/Documentation/git-annotate.txt b/Documentation/git-annotate.adoc similarity index 96% rename from Documentation/git-annotate.txt rename to Documentation/git-annotate.adoc index 5ae8aabe0f88c6..965bc676afe591 100644 --- a/Documentation/git-annotate.txt +++ b/Documentation/git-annotate.adoc @@ -22,7 +22,7 @@ familiar command name for people coming from other SCM systems. OPTIONS ------- -include::blame-options.txt[] +include::blame-options.adoc[] SEE ALSO -------- diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.adoc similarity index 99% rename from Documentation/git-apply.txt rename to Documentation/git-apply.adoc index dd4a61ef289339..952518b8af6fc0 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.adoc @@ -270,9 +270,9 @@ has no effect when `--index` or `--cached` is in use. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/apply.txt[] +include::config/apply.adoc[] SUBMODULES ---------- diff --git a/Documentation/git-archimport.txt b/Documentation/git-archimport.adoc similarity index 100% rename from Documentation/git-archimport.txt rename to Documentation/git-archimport.adoc diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.adoc similarity index 100% rename from Documentation/git-archive.txt rename to Documentation/git-archive.adoc diff --git a/Documentation/git-backfill.adoc b/Documentation/git-backfill.adoc new file mode 100644 index 00000000000000..95623051f789b2 --- /dev/null +++ b/Documentation/git-backfill.adoc @@ -0,0 +1,71 @@ +git-backfill(1) +=============== + +NAME +---- +git-backfill - Download missing objects in a partial clone + + +SYNOPSIS +-------- +[synopsis] +git backfill [--min-batch-size=<n>] [--[no-]sparse] + +DESCRIPTION +----------- + +Blobless partial clones are created using `git clone --filter=blob:none` +and then configure the local repository such that the Git client avoids +downloading blob objects unless they are required for a local operation. +This initially means that the clone and later fetches download reachable +commits and trees but no blobs. Later operations that change the `HEAD` +pointer, such as `git checkout` or `git merge`, may need to download +missing blobs in order to complete their operation. + +In the worst cases, commands that compute blob diffs, such as `git blame`, +become very slow as they download the missing blobs in single-blob +requests to satisfy the missing object as the Git command needs it. This +leads to multiple download requests and no ability for the Git server to +provide delta compression across those objects. + +The `git backfill` command provides a way for the user to request that +Git downloads the missing blobs (with optional filters) such that the +missing blobs representing historical versions of files can be downloaded +in batches. The `backfill` command attempts to optimize the request by +grouping blobs that appear at the same path, hopefully leading to good +delta compression in the packfile sent by the server. + +In this way, `git backfill` provides a mechanism to break a large clone +into smaller chunks. Starting with a blobless partial clone with `git +clone --filter=blob:none` and then running `git backfill` in the local +repository provides a way to download all reachable objects in several +smaller network calls than downloading the entire repository at clone +time. + +By default, `git backfill` downloads all blobs reachable from the `HEAD` +commit. This set can be restricted or expanded using various options. + +THIS COMMAND IS EXPERIMENTAL. ITS BEHAVIOR MAY CHANGE IN THE FUTURE. + + +OPTIONS +------- + +`--min-batch-size=<n>`:: + Specify a minimum size for a batch of missing objects to request + from the server. This size may be exceeded by the last set of + blobs seen at a given path. The default minimum batch size is + 50,000. + +`--[no-]sparse`:: + Only download objects if they appear at a path that matches the + current sparse-checkout. If the sparse-checkout feature is enabled, + then `--sparse` is assumed and can be disabled with `--no-sparse`. + +SEE ALSO +-------- +linkgit:git-clone[1]. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-bisect-lk2009.txt b/Documentation/git-bisect-lk2009.adoc similarity index 100% rename from Documentation/git-bisect-lk2009.txt rename to Documentation/git-bisect-lk2009.adoc diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.adoc similarity index 100% rename from Documentation/git-bisect.txt rename to Documentation/git-bisect.adoc diff --git a/Documentation/git-blame.txt b/Documentation/git-blame.adoc similarity index 98% rename from Documentation/git-blame.txt rename to Documentation/git-blame.adoc index b1d7fb539d0216..f75ed4479021cb 100644 --- a/Documentation/git-blame.txt +++ b/Documentation/git-blame.adoc @@ -48,7 +48,7 @@ ea4c7f9bf69e781dd0cd88d2bccb2bf5cc15c9a7 git-blame: Make the output OPTIONS ------- -include::blame-options.txt[] +include::blame-options.adoc[] -c:: Use the same output mode as linkgit:git-annotate[1] (Default: off). @@ -244,9 +244,9 @@ See linkgit:gitmailmap[5]. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/blame.txt[] +include::config/blame.adoc[] SEE ALSO -------- diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.adoc similarity index 99% rename from Documentation/git-branch.txt rename to Documentation/git-branch.adoc index 0b08442932354f..7a073a36d6dbf0 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.adoc @@ -345,9 +345,9 @@ CONFIGURATION `--list` is used or implied. The default is to use a pager. See linkgit:git-config[1]. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/branch.txt[] +include::config/branch.adoc[] EXAMPLES -------- @@ -415,7 +415,7 @@ serve four related but different purposes: - `--no-merged` is used to find branches which are candidates for merging into HEAD, since those branches are not fully contained by HEAD. -include::ref-reachability-filters.txt[] +include::ref-reachability-filters.adoc[] SEE ALSO -------- diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.adoc similarity index 100% rename from Documentation/git-bugreport.txt rename to Documentation/git-bugreport.adoc diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.adoc similarity index 84% rename from Documentation/git-bundle.txt rename to Documentation/git-bundle.adoc index 3ab42a19cae4ac..03cd36fe8d2f7a 100644 --- a/Documentation/git-bundle.txt +++ b/Documentation/git-bundle.adoc @@ -23,19 +23,18 @@ the "offline" transfer of Git objects without an active "server" sitting on the other side of the network connection. They can be used to create both incremental and full backups of a -repository, and to relay the state of the references in one repository -to another. +repository (see the "full backup" example in "EXAMPLES"), and to relay +the state of the references in one repository to another (see the second +example). Git commands that fetch or otherwise "read" via protocols such as `ssh://` and `https://` can also operate on bundle files. It is possible linkgit:git-clone[1] a new repository from a bundle, to use linkgit:git-fetch[1] to fetch from one, and to list the references contained within it with linkgit:git-ls-remote[1]. There's no -corresponding "write" support, i.e.a 'git push' into a bundle is not +corresponding "write" support, i.e. a 'git push' into a bundle is not supported. -See the "EXAMPLES" section below for examples of how to use bundles. - BUNDLE FORMAT ------------- @@ -132,7 +131,7 @@ SPECIFYING REFERENCES --------------------- Revisions must be accompanied by reference names to be packaged in a -bundle. +bundle. Alternatively `--all` can be used to package all refs. More than one reference may be packaged, and more than one set of prerequisite objects can be specified. The objects packaged are those not contained in the @@ -203,8 +202,6 @@ It is okay to err on the side of caution, causing the bundle file to contain objects already in the destination, as these are ignored when unpacking at the destination. -If you want to match `git clone --mirror`, which would include your -refs such as `refs/remotes/*`, use `--all`. If you want to provide the same set of refs that a clone directly from the source repository would get, use `--branches --tags` for the `<git-rev-list-args>`. @@ -216,8 +213,34 @@ bundle. EXAMPLES -------- -Assume you want to transfer the history from a repository R1 on machine A -to another repository R2 on machine B. +We'll discuss two cases: + +1. Taking a full backup of a repository +2. Transferring the history of a repository to another machine when the + two machines have no direct connection + +First let's consider a full backup of the repository. The following +command will take a full backup of the repository in the sense that all +refs are included in the bundle: + +---------------- +$ git bundle create backup.bundle --all +---------------- + +But note again that this is only for the refs, i.e. you will only +include refs and commits reachable from those refs. You will not +include other local state, such as the contents of the index, working +tree, the stash, per-repository configuration, hooks, etc. + +You can later recover that repository by using for example +linkgit:git-clone[1]: + +---------------- +$ git clone backup.bundle <new directory> +---------------- + +For the next example, assume you want to transfer the history from a +repository R1 on machine A to another repository R2 on machine B. For whatever reason, direct connection between A and B is not allowed, but we can move data from A to B via some mechanism (CD, email, etc.). We want to update R2 with development made on the branch master in R1. @@ -321,6 +344,24 @@ You can also see what references it offers: $ git ls-remote mybundle ---------------- +DISCUSSION +---------- + +A naive way to make a full backup of a repository is to use something to +the effect of `cp -r <repo> <destination>`. This is discouraged since +the repository could be written to during the copy operation. In turn +some files at `<destination>` could be corrupted. + +This is why it is recommended to use Git tooling for making repository +backups, either with this command or with e.g. linkgit:git-clone[1]. +But keep in mind that these tools will not help you backup state other +than refs and commits. In other words they will not help you backup +contents of the index, working tree, the stash, per-repository +configuration, hooks, etc. + +See also linkgit:gitfaq[7], section "TRANSFERS" for a discussion of the +problems associated with file syncing across systems. + FILE FORMAT ----------- diff --git a/Documentation/git-cat-file.txt b/Documentation/git-cat-file.adoc similarity index 100% rename from Documentation/git-cat-file.txt rename to Documentation/git-cat-file.adoc diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.adoc similarity index 100% rename from Documentation/git-check-attr.txt rename to Documentation/git-check-attr.adoc diff --git a/Documentation/git-check-ignore.txt b/Documentation/git-check-ignore.adoc similarity index 100% rename from Documentation/git-check-ignore.txt rename to Documentation/git-check-ignore.adoc diff --git a/Documentation/git-check-mailmap.txt b/Documentation/git-check-mailmap.adoc similarity index 100% rename from Documentation/git-check-mailmap.txt rename to Documentation/git-check-mailmap.adoc diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.adoc similarity index 100% rename from Documentation/git-check-ref-format.txt rename to Documentation/git-check-ref-format.adoc diff --git a/Documentation/git-checkout-index.txt b/Documentation/git-checkout-index.adoc similarity index 100% rename from Documentation/git-checkout-index.txt rename to Documentation/git-checkout-index.adoc diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.adoc similarity index 98% rename from Documentation/git-checkout.txt rename to Documentation/git-checkout.adoc index 8bdfa54ab09b4c..a66c53a5cd1e0a 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.adoc @@ -290,10 +290,10 @@ Note that this option uses the no overlay mode by default (see also `--overlay`), and currently doesn't support overlay mode. --ignore-other-worktrees:: - `git checkout` refuses when the wanted ref is already checked - out by another worktree. This option makes it check the ref - out anyway. In other words, the ref can be held by more than one - worktree. + `git checkout` refuses when the wanted branch is already checked + out or otherwise in use by another worktree. This option makes + it check the branch out anyway. In other words, the branch can + be in use by more than one worktree. --overwrite-ignore:: --no-overwrite-ignore:: @@ -612,9 +612,9 @@ $ git add frotz CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/checkout.txt[] +include::config/checkout.adoc[] SEE ALSO -------- diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.adoc similarity index 99% rename from Documentation/git-cherry-pick.txt rename to Documentation/git-cherry-pick.adoc index 81ace900fc5965..42b41923d5f0bc 100644 --- a/Documentation/git-cherry-pick.txt +++ b/Documentation/git-cherry-pick.adoc @@ -172,11 +172,11 @@ fail unless one of `--empty=keep` or `--allow-empty` are specified. Pass the merge strategy-specific option through to the merge strategy. See linkgit:git-merge[1] for details. -include::rerere-options.txt[] +include::rerere-options.adoc[] SEQUENCER SUBCOMMANDS --------------------- -include::sequencer.txt[] +include::sequencer.adoc[] EXAMPLES -------- diff --git a/Documentation/git-cherry.txt b/Documentation/git-cherry.adoc similarity index 100% rename from Documentation/git-cherry.txt rename to Documentation/git-cherry.adoc diff --git a/Documentation/git-citool.txt b/Documentation/git-citool.adoc similarity index 100% rename from Documentation/git-citool.txt rename to Documentation/git-citool.adoc diff --git a/Documentation/git-clean.txt b/Documentation/git-clean.adoc similarity index 98% rename from Documentation/git-clean.txt rename to Documentation/git-clean.adoc index fd171654163c1f..bed52c203b49b3 100644 --- a/Documentation/git-clean.txt +++ b/Documentation/git-clean.adoc @@ -140,9 +140,9 @@ help:: CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/clean.txt[] +include::config/clean.adoc[] SEE ALSO -------- diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.adoc similarity index 79% rename from Documentation/git-clone.txt rename to Documentation/git-clone.adoc index 8e925db7e9c662..222d558290ed6b 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.adoc @@ -8,16 +8,16 @@ git-clone - Clone a repository into a new directory SYNOPSIS -------- -[verse] -`git clone` [++--template=++__<template-directory>__] - [`-l`] [`-s`] [`--no-hardlinks`] [`-q`] [`-n`] [`--bare`] [`--mirror`] - [`-o` _<name>_] [`-b` _<name>_] [`-u` _<upload-pack>_] [`--reference` _<repository>_] - [`--dissociate`] [`--separate-git-dir` _<git-dir>_] - [`--depth` _<depth>_] [`--`[`no-`]{empty}`single-branch`] [`--no-tags`] - [++--recurse-submodules++[++=++__<pathspec>__]] [++--++[++no-++]{empty}++shallow-submodules++] - [`--`[`no-`]{empty}`remote-submodules`] [`--jobs` _<n>_] [`--sparse`] [`--`[`no-`]{empty}`reject-shallow`] - [++--filter=++__<filter-spec>__] [`--also-filter-submodules`]] [`--`] _<repository>_ - [_<directory>_] +[synopsis] +git clone [--template=<template-directory>] + [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror] + [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] + [--dissociate] [--separate-git-dir <git-dir>] + [--depth <depth>] [--[no-]single-branch] [--[no-]tags] + [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules] + [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--[no-]reject-shallow] + [--filter=<filter-spec>] [--also-filter-submodules]] [--] <repository> + [<directory>] DESCRIPTION ----------- @@ -52,7 +52,7 @@ OPTIONS to save space when possible. + If the repository is specified as a local path (e.g., `/path/to/repo`), -this is the default, and --local is essentially a no-op. If the +this is the default, and `--local` is essentially a no-op. If the repository is specified as a URL, then this flag is ignored (and we never use the local optimizations). Specifying `--no-local` will override the default when `/path/to/repo` is given, using the regular @@ -63,9 +63,12 @@ symbolic link, the clone will fail. This is a security measure to prevent the unintentional copying of files by dereferencing the symbolic links. + +This option does not work with repositories owned by other users for security +reasons, and `--no-local` must be specified for the clone to succeed. ++ *NOTE*: this operation can race with concurrent modification to the -source repository, similar to running `cp -r src dst` while modifying -`src`. +source repository, similar to running `cp -r <src> <dst>` while modifying +_<src>_. `--no-hardlinks`:: Force the cloning process from a repository on a local @@ -101,7 +104,7 @@ If you want to break the dependency of a repository cloned with `--shared` on its source repository, you can simply run `git repack -a` to copy all objects from the source repository into a pack in the cloned repository. -`--reference`[`-if-able`] _<repository>_:: +`--reference[-if-able] <repository>`:: If the reference _<repository>_ is on the local machine, automatically setup `.git/objects/info/alternates` to obtain objects from the reference _<repository>_. Using @@ -142,17 +145,20 @@ objects from the source repository into a pack in the cloned repository. is specified. This flag forces progress status even if the standard error stream is not directed to a terminal. -++--server-option=++__<option>__:: +`--server-option=<option>`:: Transmit the given string to the server when communicating using protocol version 2. The given string must not contain a NUL or LF character. The server's handling of server options, including unknown ones, is server-specific. - When multiple ++--server-option=++__<option>__ are given, they are all + When multiple `--server-option=<option>` are given, they are all sent to the other side in the order listed on the command line. + When no ++--server-option=++__<option>__ is given from the command + line, the values of configuration variable `remote.<name>.serverOption` + are used instead. `-n`:: `--no-checkout`:: - No checkout of HEAD is performed after the clone is complete. + No checkout of `HEAD` is performed after the clone is complete. `--`[`no-`]`reject-shallow`:: Fail if the source repository is a shallow repository. @@ -162,7 +168,7 @@ objects from the source repository into a pack in the cloned repository. `--bare`:: Make a 'bare' Git repository. That is, instead of creating _<directory>_ and placing the administrative - files in _<directory>_`/.git`, make the _<directory>_ + files in `<directory>/.git`, make the _<directory>_ itself the `$GIT_DIR`. This obviously implies the `--no-checkout` because there is nowhere to check out the working tree. Also the branch heads at the remote are copied directly @@ -177,13 +183,13 @@ objects from the source repository into a pack in the cloned repository. linkgit:git-sparse-checkout[1] command can be used to grow the working directory as needed. -++--filter=++__<filter-spec>__:: +`--filter=<filter-spec>`:: Use the partial clone feature and request that the server sends a subset of reachable objects according to a given object filter. When using `--filter`, the supplied _<filter-spec>_ is used for the partial clone filter. For example, `--filter=blob:none` will filter out all blobs (file contents) until needed by Git. Also, - ++--filter=blob:limit=++__<size>__ will filter out all blobs of size + `--filter=blob:limit=<size>` will filter out all blobs of size at least _<size>_. For more details on filter specifications, see the `--filter` option in linkgit:git-rev-list[1]. @@ -208,25 +214,34 @@ objects from the source repository into a pack in the cloned repository. `-b` _<name>_:: `--branch` _<name>_:: - Instead of pointing the newly created HEAD to the branch pointed - to by the cloned repository's HEAD, point to _<name>_ branch + Instead of pointing the newly created `HEAD` to the branch pointed + to by the cloned repository's `HEAD`, point to _<name>_ branch instead. In a non-bare repository, this is the branch that will be checked out. - `--branch` can also take tags and detaches the HEAD at that commit + `--branch` can also take tags and detaches the `HEAD` at that commit in the resulting repository. +`--revision=<rev>`:: + Create a new repository, and fetch the history leading to the given + revision _<rev>_ (and nothing else), without making any remote-tracking + branch, and without making any local branch, and detach `HEAD` to + _<rev>_. The argument can be a ref name (e.g. `refs/heads/main` or + `refs/tags/v1.0`) that peels down to a commit, or a hexadecimal object + name. + This option is incompatible with `--branch` and `--mirror`. + `-u` _<upload-pack>_:: `--upload-pack` _<upload-pack>_:: When given, and the repository to clone from is accessed via ssh, this specifies a non-default path for the command run on the other end. -++--template=++__<template-directory>__:: +`--template=<template-directory>`:: Specify the directory from which templates will be used; (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].) -`-c` __<key>__++=++__<value>__:: -`--config` __<key>__++=++__<value>__:: +`-c` `<key>=<value>`:: +`--config` `<key>=<value>`:: Set a configuration variable in the newly-created repository; this takes effect immediately after the repository is initialized, but before the remote history is fetched or any @@ -239,25 +254,25 @@ objects from the source repository into a pack in the cloned repository. Due to limitations of the current implementation, some configuration variables do not take effect until after the initial fetch and checkout. Configuration variables known to not take effect are: -++remote.++__<name>__++.mirror++ and ++remote.++__<name>__++.tagOpt++. Use the +`remote.<name>.mirror` and `remote.<name>.tagOpt`. Use the corresponding `--mirror` and `--no-tags` options instead. -`--depth` _<depth>_:: +`--depth <depth>`:: Create a 'shallow' clone with a history truncated to the specified number of commits. Implies `--single-branch` unless `--no-single-branch` is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass `--shallow-submodules`. -++--shallow-since=++__<date>__:: +`--shallow-since=<date>`:: Create a shallow clone with a history after the specified time. -++--shallow-exclude=++__<revision>__:: +`--shallow-exclude=<ref>`:: Create a shallow clone with a history, excluding commits reachable from a specified remote branch or tag. This option can be specified multiple times. -`--`[`no-`]`single-branch`:: +`--[no-]single-branch`:: Clone only the history leading to the tip of a single branch, either specified by the `--branch` option or the primary branch remote's `HEAD` points at. @@ -267,25 +282,28 @@ corresponding `--mirror` and `--no-tags` options instead. branch when `--single-branch` clone was made, no remote-tracking branch is created. -`--no-tags`:: - Don't clone any tags, and set - `remote.<remote>.tagOpt=--no-tags` in the config, ensuring - that future `git pull` and `git fetch` operations won't follow - any tags. Subsequent explicit tag fetches will still work, - (see linkgit:git-fetch[1]). +`--[no-]tags`:: + Control whether or not tags will be cloned. When `--no-tags` is + given, the option will be become permanent by setting the + `remote.<remote>.tagOpt=--no-tags` configuration. This ensures that + future `git pull` and `git fetch` won't follow any tags. Subsequent + explicit tag fetches will still work (see linkgit:git-fetch[1]). ++ +By default, tags are cloned and passing `--tags` is thus typically a +no-op, unless it cancels out a previous `--no-tags`. + Can be used in conjunction with `--single-branch` to clone and maintain a branch with no references other than a single cloned branch. This is useful e.g. to maintain minimal clones of the default branch of some repository for search indexing. -`--recurse-submodules`[`=`{empty}__<pathspec>__]:: +`--recurse-submodules[=<pathspec>]`:: After the clone is created, initialize and clone submodules - within based on the provided _<pathspec>_. If no _=<pathspec>_ is + within based on the provided _<pathspec>_. If no `=<pathspec>` is provided, all submodules are initialized and cloned. This option can be given multiple times for pathspecs consisting of multiple entries. The resulting clone has `submodule.active` set to - the provided pathspec, or "." (meaning all submodules) if no + the provided pathspec, or "`.`" (meaning all submodules) if no pathspec is provided. + Submodules are initialized and cloned using their default settings. This is @@ -295,27 +313,27 @@ the clone is finished. This option is ignored if the cloned repository does not have a worktree/checkout (i.e. if any of `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) -`--`[`no-`]`shallow-submodules`:: +`--[no-]shallow-submodules`:: All submodules which are cloned will be shallow with a depth of 1. -`--`[`no-`]`remote-submodules`:: +`--[no-]remote-submodules`:: All submodules which are cloned will use the status of the submodule's remote-tracking branch to update the submodule, rather than the superproject's recorded SHA-1. Equivalent to passing `--remote` to `git submodule update`. -`--separate-git-dir=`{empty}__<git-dir>__:: +`--separate-git-dir=<git-dir>`:: Instead of placing the cloned repository where it is supposed to be, place the cloned repository at the specified directory, then make a filesystem-agnostic Git symbolic link to there. The result is Git repository can be separated from working tree. -`--ref-format=`{empty}__<ref-format>__:: +`--ref-format=<ref-format>`:: Specify the given ref storage format for the repository. The valid values are: + -include::ref-storage-format.txt[] +include::ref-storage-format.adoc[] `-j` _<n>_:: `--jobs` _<n>_:: @@ -334,7 +352,7 @@ _<directory>_:: for `host.xz:foo/.git`). Cloning into an existing directory is only allowed if the directory is empty. -`--bundle-uri=`{empty}__<uri>__:: +`--bundle-uri=<uri>`:: Before fetching from the remote, fetch a bundle from the given _<uri>_ and unbundle the data into the local repository. The refs in the bundle will be stored under the hidden `refs/bundle/*` @@ -342,7 +360,7 @@ _<directory>_:: `--shallow-since`, and `--shallow-exclude`. :git-clone: 1 -include::urls.txt[] +include::urls.adoc[] EXAMPLES -------- @@ -381,14 +399,20 @@ $ cd my-linux $ git clone --bare -l /home/proj/.git /pub/scm/proj.git ------------ +* Clone a local repository from a different user: ++ +------------ +$ git clone --no-local /home/otheruser/proj.git /pub/scm/proj.git +------------ + CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/init.txt[] +include::config/init.adoc[] -include::config/clone.txt[] +include::config/clone.adoc[] GIT diff --git a/Documentation/git-column.txt b/Documentation/git-column.adoc similarity index 96% rename from Documentation/git-column.txt rename to Documentation/git-column.adoc index 18431647a2da9f..85fb87c94a4445 100644 --- a/Documentation/git-column.txt +++ b/Documentation/git-column.adoc @@ -77,9 +77,9 @@ v2.4.8 v2.4.9 CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/column.txt[] +include::config/column.adoc[] GIT --- diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.adoc similarity index 98% rename from Documentation/git-commit-graph.txt rename to Documentation/git-commit-graph.adoc index 903b16830ea225..50b50168045cc6 100644 --- a/Documentation/git-commit-graph.txt +++ b/Documentation/git-commit-graph.adoc @@ -148,9 +148,9 @@ $ git rev-parse HEAD | git commit-graph write --stdin-commits --append CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/commitgraph.txt[] +include::config/commitgraph.adoc[] FILE FORMAT diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.adoc similarity index 98% rename from Documentation/git-commit-tree.txt rename to Documentation/git-commit-tree.adoc index 2e2c5810983a89..6472921e14b562 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.adoc @@ -80,12 +80,12 @@ A commit comment is read from stdin. If a changelog entry is not provided via "<" redirection, 'git commit-tree' will just wait for one to be entered and terminated with ^D. -include::date-formats.txt[] +include::date-formats.adoc[] Discussion ---------- -include::i18n.txt[] +include::i18n.adoc[] FILES ----- diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.adoc similarity index 73% rename from Documentation/git-commit.txt rename to Documentation/git-commit.adoc index c822113c111ded..dc219025f1eb0b 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.adoc @@ -7,8 +7,8 @@ git-commit - Record changes to the repository SYNOPSIS -------- -[verse] -'git commit' [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] +[synopsis] +git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend] [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] @@ -23,31 +23,31 @@ Create a new commit containing the current contents of the index and the given log message describing the changes. The new commit is a direct child of HEAD, usually the tip of the current branch, and the branch is updated to point to it (unless no branch is associated with -the working tree, in which case HEAD is "detached" as described in +the working tree, in which case `HEAD` is "detached" as described in linkgit:git-checkout[1]). The content to be committed can be specified in several ways: 1. by using linkgit:git-add[1] to incrementally "add" changes to the - index before using the 'commit' command (Note: even modified files + index before using the `commit` command (Note: even modified files must be "added"); 2. by using linkgit:git-rm[1] to remove files from the working tree - and the index, again before using the 'commit' command; + and the index, again before using the `commit` command; -3. by listing files as arguments to the 'commit' command - (without --interactive or --patch switch), in which +3. by listing files as arguments to the `commit` command + (without `--interactive` or `--patch` switch), in which case the commit will ignore changes staged in the index, and instead record the current content of the listed files (which must already be known to Git); -4. by using the -a switch with the 'commit' command to automatically +4. by using the `-a` switch with the `commit` command to automatically "add" changes from all known files (i.e. all files that are already listed in the index) and to automatically "rm" files in the index that have been removed from the working tree, and then perform the actual commit; -5. by using the --interactive or --patch switches with the 'commit' command +5. by using the `--interactive` or `--patch` switches with the `commit` command to decide one by one which files or hunks should be part of the commit in addition to contents in the index, before finalizing the operation. See the ``Interactive Mode'' section of @@ -58,139 +58,139 @@ summary of what is included by any of the above for the next commit by giving the same set of parameters (options and paths). If you make a commit and then find a mistake immediately after -that, you can recover from it with 'git reset'. +that, you can recover from it with `git reset`. :git-commit: 1 OPTIONS ------- --a:: ---all:: - Tell the command to automatically stage files that have +`-a`:: +`--all`:: + Automatically stage files that have been modified and deleted, but new files you have not told Git about are not affected. --p:: ---patch:: +`-p`:: +`--patch`:: Use the interactive patch selection interface to choose which changes to commit. See linkgit:git-add[1] for details. --C <commit>:: ---reuse-message=<commit>:: - Take an existing commit object, and reuse the log message +`-C <commit>`:: +`--reuse-message=<commit>`:: + Take an existing _<commit>_ object, and reuse the log message and the authorship information (including the timestamp) when creating the commit. --c <commit>:: ---reedit-message=<commit>:: - Like '-C', but with `-c` the editor is invoked, so that +`-c <commit>`:: +`--reedit-message=<commit>`:: + Like `-C`, but with `-c` the editor is invoked, so that the user can further edit the commit message. ---fixup=[(amend|reword):]<commit>:: - Create a new commit which "fixes up" `<commit>` when applied with +`--fixup=[(amend|reword):]<commit>`:: + Create a new commit which "fixes up" _<commit>_ when applied with `git rebase --autosquash`. Plain `--fixup=<commit>` creates a - "fixup!" commit which changes the content of `<commit>` but leaves + "fixup!" commit which changes the content of _<commit>_ but leaves its log message untouched. `--fixup=amend:<commit>` is similar but creates an "amend!" commit which also replaces the log message of - `<commit>` with the log message of the "amend!" commit. + _<commit>_ with the log message of the "amend!" commit. `--fixup=reword:<commit>` creates an "amend!" commit which - replaces the log message of `<commit>` with its own log message - but makes no changes to the content of `<commit>`. + replaces the log message of _<commit>_ with its own log message + but makes no changes to the content of _<commit>_. + -The commit created by plain `--fixup=<commit>` has a subject -composed of "fixup!" followed by the subject line from <commit>, +The commit created by plain `--fixup=<commit>` has a title +composed of "fixup!" followed by the title of _<commit>_, and is recognized specially by `git rebase --autosquash`. The `-m` option may be used to supplement the log message of the created commit, but the additional commentary will be thrown away once the -"fixup!" commit is squashed into `<commit>` by +"fixup!" commit is squashed into _<commit>_ by `git rebase --autosquash`. + The commit created by `--fixup=amend:<commit>` is similar but its -subject is instead prefixed with "amend!". The log message of -<commit> is copied into the log message of the "amend!" commit and +title is instead prefixed with "amend!". The log message of +_<commit>_ is copied into the log message of the "amend!" commit and opened in an editor so it can be refined. When `git rebase ---autosquash` squashes the "amend!" commit into `<commit>`, the -log message of `<commit>` is replaced by the refined log message +--autosquash` squashes the "amend!" commit into _<commit>_, the +log message of _<commit>_ is replaced by the refined log message from the "amend!" commit. It is an error for the "amend!" commit's log message to be empty unless `--allow-empty-message` is specified. + `--fixup=reword:<commit>` is shorthand for `--fixup=amend:<commit> ---only`. It creates an "amend!" commit with only a log message + --only`. It creates an "amend!" commit with only a log message (ignoring any changes staged in the index). When squashed by `git -rebase --autosquash`, it replaces the log message of `<commit>` +rebase --autosquash`, it replaces the log message of _<commit>_ without making any other changes. + Neither "fixup!" nor "amend!" commits change authorship of -`<commit>` when applied by `git rebase --autosquash`. +_<commit>_ when applied by `git rebase --autosquash`. See linkgit:git-rebase[1] for details. ---squash=<commit>:: - Construct a commit message for use with `rebase --autosquash`. - The commit message subject line is taken from the specified +`--squash=<commit>`:: + Construct a commit message for use with `git rebase --autosquash`. + The commit message title is taken from the specified commit with a prefix of "squash! ". Can be used with additional commit message options (`-m`/`-c`/`-C`/`-F`). See linkgit:git-rebase[1] for details. ---reset-author:: - When used with -C/-c/--amend options, or when committing after a +`--reset-author`:: + When used with `-C`/`-c`/`--amend` options, or when committing after a conflicting cherry-pick, declare that the authorship of the resulting commit now belongs to the committer. This also renews the author timestamp. ---short:: +`--short`:: When doing a dry-run, give the output in the short-format. See linkgit:git-status[1] for details. Implies `--dry-run`. ---branch:: +`--branch`:: Show the branch and tracking info even in short-format. ---porcelain:: +`--porcelain`:: When doing a dry-run, give the output in a porcelain-ready format. See linkgit:git-status[1] for details. Implies `--dry-run`. ---long:: +`--long`:: When doing a dry-run, give the output in the long-format. Implies `--dry-run`. --z:: ---null:: +`-z`:: +`--null`:: When showing `short` or `porcelain` status output, print the - filename verbatim and terminate the entries with NUL, instead of LF. + filename verbatim and terminate the entries with _NUL_, instead of _LF_. If no format is given, implies the `--porcelain` output format. Without the `-z` option, filenames with "unusual" characters are quoted as explained for the configuration variable `core.quotePath` (see linkgit:git-config[1]). --F <file>:: ---file=<file>:: - Take the commit message from the given file. Use '-' to +`-F <file>`:: +`--file=<file>`:: + Take the commit message from _<file>_. Use '-' to read the message from the standard input. ---author=<author>:: +`--author=<author>`:: Override the commit author. Specify an explicit author using the - standard `A U Thor <author@example.com>` format. Otherwise <author> + standard `A U Thor <author@example.com>` format. Otherwise _<author>_ is assumed to be a pattern and is used to search for an existing - commit by that author (i.e. rev-list --all -i --author=<author>); + commit by that author (i.e. `git rev-list --all -i --author=<author>`); the commit author is then copied from the first such commit found. ---date=<date>:: +`--date=<date>`:: Override the author date used in the commit. --m <msg>:: ---message=<msg>:: - Use the given <msg> as the commit message. +`-m <msg>`:: +`--message=<msg>`:: + Use _<msg>_ as the commit message. If multiple `-m` options are given, their values are concatenated as separate paragraphs. + The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. --t <file>:: ---template=<file>:: +`-t <file>`:: +`--template=<file>`:: When editing the commit message, start the editor with the - contents in the given file. The `commit.template` configuration + contents in _<file>_. The `commit.template` configuration variable is often used to give this option implicitly to the command. This mechanism can be used by projects that want to guide participants with some hints on what to write in the message @@ -198,58 +198,56 @@ The `-m` option is mutually exclusive with `-c`, `-C`, and `-F`. message, the commit is aborted. This has no effect when a message is given by other means, e.g. with the `-m` or `-F` options. -include::signoff-option.txt[] +include::signoff-option.adoc[] ---trailer <token>[(=|:)<value>]:: - Specify a (<token>, <value>) pair that should be applied as a +`--trailer <token>[(=|:)<value>]`:: + Specify a (_<token>_, _<value>_) pair that should be applied as a trailer. (e.g. `git commit --trailer "Signed-off-by:C O Mitter \ <committer@example.com>" --trailer "Helped-by:C O Mitter \ - <committer@example.com>"` will add the "Signed-off-by" trailer - and the "Helped-by" trailer to the commit message.) + <committer@example.com>"` will add the `Signed-off-by` trailer + and the `Helped-by` trailer to the commit message.) The `trailer.*` configuration variables (linkgit:git-interpret-trailers[1]) can be used to define if a duplicated trailer is omitted, where in the run of trailers each trailer would appear, and other details. --n:: ---[no-]verify:: - By default, the pre-commit and commit-msg hooks are run. - When any of `--no-verify` or `-n` is given, these are bypassed. +`-n`:: +`--[no-]verify`:: + Bypass the `pre-commit` and `commit-msg` hooks. See also linkgit:githooks[5]. ---allow-empty:: +`--allow-empty`:: Usually recording a commit that has the exact same tree as its sole parent commit is a mistake, and the command prevents you from making such a commit. This option bypasses the safety, and is primarily for use by foreign SCM interface scripts. ---allow-empty-message:: - Like --allow-empty this command is primarily for use by foreign - SCM interface scripts. It allows you to create a commit with an - empty commit message without using plumbing commands like - linkgit:git-commit-tree[1]. +`--allow-empty-message`:: + Create a commit with an empty commit message without using plumbing + commands like linkgit:git-commit-tree[1]. Like `--allow-empty`, this + command is primarily for use by foreign SCM interface scripts. ---cleanup=<mode>:: - This option determines how the supplied commit message should be +`--cleanup=<mode>`:: + Determine how the supplied commit message should be cleaned up before committing. The '<mode>' can be `strip`, `whitespace`, `verbatim`, `scissors` or `default`. + -- -strip:: +`strip`:: Strip leading and trailing empty lines, trailing whitespace, commentary and collapse consecutive empty lines. -whitespace:: +`whitespace`:: Same as `strip` except #commentary is not removed. -verbatim:: +`verbatim`:: Do not change the message at all. -scissors:: +`scissors`:: Same as `whitespace` except that everything from (and including) the line found below is truncated, if the message is to be edited. - "`#`" can be customized with core.commentChar. + "`#`" can be customized with `core.commentChar`. # ------------------------ >8 ------------------------ -default:: +`default`:: Same as `strip` if the message is to be edited. Otherwise `whitespace`. -- @@ -257,19 +255,18 @@ default:: The default can be changed by the `commit.cleanup` configuration variable (see linkgit:git-config[1]). --e:: ---edit:: - The message taken from file with `-F`, command line with - `-m`, and from commit object with `-C` are usually used as - the commit log message unmodified. This option lets you - further edit the message taken from these sources. +`-e`:: +`--edit`:: + Let the user further edit the message taken from _<file>_ + with `-F <file>`, command line with `-m <message>`, and + from _<commit>_ with `-C <commit>`. ---no-edit:: +`--no-edit`:: Use the selected commit message without launching an editor. For example, `git commit --amend --no-edit` amends a commit without changing its commit message. ---amend:: +`--amend`:: Replace the tip of the current branch by creating a new commit. The recorded tree is prepared as usual (including the effect of the `-i` and `-o` options and explicit @@ -295,23 +292,23 @@ You should understand the implications of rewriting history if you amend a commit that has already been published. (See the "RECOVERING FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].) ---no-post-rewrite:: - Bypass the post-rewrite hook. +`--no-post-rewrite`:: + Bypass the `post-rewrite` hook. --i:: ---include:: +`-i`:: +`--include`:: Before making a commit out of staged contents so far, stage the contents of paths given on the command line as well. This is usually not what you want unless you are concluding a conflicted merge. --o:: ---only:: +`-o`:: +`--only`:: Make a commit by taking the updated working tree contents of the paths specified on the command line, disregarding any contents that have been staged for other paths. This is the default mode of operation of - 'git commit' if any paths are given on the command line, + `git commit` if any paths are given on the command line, in which case this option can be omitted. If this option is specified together with `--amend`, then no paths need to be specified, which can be used to amend @@ -319,48 +316,48 @@ FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].) already been staged. If used together with `--allow-empty` paths are also not required, and an empty commit will be created. ---pathspec-from-file=<file>:: - 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 +`--pathspec-from-file=<file>`:: + Pass pathspec 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 global `--literal-pathspecs`. ---pathspec-file-nul:: +`--pathspec-file-nul`:: Only meaningful with `--pathspec-from-file`. Pathspec elements are - separated with NUL character and all other characters are taken + separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). --u[<mode>]:: ---untracked-files[=<mode>]:: +`-u[<mode>]`:: +`--untracked-files[=<mode>]`:: Show untracked files. + -- -The mode parameter is optional (defaults to 'all'), and is used to -specify the handling of untracked files; when -u is not used, the -default is 'normal', i.e. show untracked files and directories. +The _<mode>_ parameter is optional (defaults to `all`), and is used to +specify the handling of untracked files; when `-u` is not used, the +default is `normal`, i.e. show untracked files and directories. The possible options are: - - 'no' - Show no untracked files - - 'normal' - Shows untracked files and directories - - 'all' - Also shows individual files in untracked directories. +`no`:: Show no untracked files +`normal`:: Shows untracked files and directories +`all`:: Also shows individual files in untracked directories. All usual spellings for Boolean value `true` are taken as `normal` and `false` as `no`. -The default can be changed using the status.showUntrackedFiles +The default can be changed using the `status.showUntrackedFiles` configuration variable documented in linkgit:git-config[1]. -- --v:: ---verbose:: - Show unified diff between the HEAD commit and what +`-v`:: +`--verbose`:: + Show unified diff between the `HEAD` commit and what would be committed at the bottom of the commit message template to help the user describe the commit by reminding what changes the commit has. Note that this diff output doesn't have its - lines prefixed with '#'. This diff will not be a part + lines prefixed with `#`. This diff will not be a part of the commit message. See the `commit.verbose` configuration variable in linkgit:git-config[1]. + @@ -368,40 +365,40 @@ If specified twice, show in addition the unified diff between what would be committed and the worktree files, i.e. the unstaged changes to tracked files. --q:: ---quiet:: +`-q`:: +`--quiet`:: Suppress commit summary message. ---dry-run:: +`--dry-run`:: Do not create a commit, but show a list of paths that are to be committed, paths with local changes that will be left uncommitted and paths that are untracked. ---status:: +`--status`:: Include the output of linkgit:git-status[1] in the commit message template when using an editor to prepare the commit message. Defaults to on, but can be used to override - configuration variable commit.status. + configuration variable `commit.status`. ---no-status:: +`--no-status`:: Do not include the output of linkgit:git-status[1] in the commit message template when using an editor to prepare the default commit message. --S[<keyid>]:: ---gpg-sign[=<keyid>]:: ---no-gpg-sign:: - GPG-sign commits. The `keyid` argument is optional and +`-S[<key-id>]`:: +`--gpg-sign[=<key-id>]`:: +`--no-gpg-sign`:: + GPG-sign commits. The _<key-id>_ is optional and defaults to the committer identity; if specified, it must be stuck to the option without a space. `--no-gpg-sign` is useful to countermand both `commit.gpgSign` configuration variable, and earlier `--gpg-sign`. -\--:: +`--`:: Do not interpret any more arguments as options. -<pathspec>...:: - When pathspec is given on the command line, commit the contents of +`<pathspec>...`:: + When _<pathspec>_ is given on the command line, commit the contents of the files that match the pathspec without recording the changes already added to the index. The contents of these files are also staged for the next commit on top of what have been staged before. @@ -412,10 +409,10 @@ EXAMPLES -------- When recording your own work, the contents of modified files in your working tree are temporarily stored to a staging area -called the "index" with 'git add'. A file can be +called the "index" with `git add`. A file can be reverted back, only in the index but not in the working tree, to that of the last commit with `git restore --staged <file>`, -which effectively reverts 'git add' and prevents the changes to +which effectively reverts `git add` and prevents the changes to this file from participating in the next commit. After building the state to be committed incrementally with these commands, `git commit` (without any pathname parameter) is used to record what @@ -443,7 +440,7 @@ $ git commit -a ------------ The command `git commit -a` first looks at your working tree, -notices that you have modified hello.c and removed goodbye.c, +notices that you have modified `hello.c` and removed `goodbye.c`, and performs necessary `git add` and `git rm` for you. After staging changes to many files, you can alter the order the @@ -471,13 +468,13 @@ $ git commit this second commit would record the changes to `hello.c` and `hello.h` as expected. -After a merge (initiated by 'git merge' or 'git pull') stops +After a merge (initiated by `git merge` or `git pull`) stops because of conflicts, cleanly merged paths are already staged to be committed for you, and paths that conflicted are left in unmerged state. You would have to first -check which paths are conflicting with 'git status' +check which paths are conflicting with `git status` and after fixing them manually in your working tree, you would -stage the result as usual with 'git add': +stage the result as usual with `git add`: ------------ $ git status | grep unmerged @@ -507,12 +504,12 @@ COMMIT INFORMATION Author and committer information is taken from the following environment variables, if set: - GIT_AUTHOR_NAME - GIT_AUTHOR_EMAIL - GIT_AUTHOR_DATE - GIT_COMMITTER_NAME - GIT_COMMITTER_EMAIL - GIT_COMMITTER_DATE + * `GIT_AUTHOR_NAME` + * `GIT_AUTHOR_EMAIL` + * `GIT_AUTHOR_DATE` + * `GIT_COMMITTER_NAME` + * `GIT_COMMITTER_EMAIL` + * `GIT_COMMITTER_DATE` (nb "<", ">" and "\n"s are stripped) @@ -524,7 +521,7 @@ that, see the `credential.username` variable in linkgit:git-config[1]. In case (some of) these environment variables are not set, the information is taken from the configuration items `user.name` and `user.email`, or, if not -present, the environment variable EMAIL, or, if that is not set, +present, the environment variable `EMAIL`, or, if that is not set, system user name and the hostname used for outgoing mail (taken from `/etc/mailname` and falling back to the fully qualified hostname when that file does not exist). @@ -537,7 +534,7 @@ The typical usage is to set just the `user.name` and `user.email` variables; the other options are provided for more complex use cases. :git-commit: 1 -include::date-formats.txt[] +include::date-formats.adoc[] DISCUSSION ---------- @@ -550,18 +547,18 @@ as the commit title, and that title is used throughout Git. For example, linkgit:git-format-patch[1] turns a commit into email, and it uses the title on the Subject line and the rest of the commit in the body. -include::i18n.txt[] +include::i18n.adoc[] ENVIRONMENT AND CONFIGURATION VARIABLES --------------------------------------- The editor used to edit the commit log message will be chosen from the -`GIT_EDITOR` environment variable, the core.editor configuration variable, the +`GIT_EDITOR` environment variable, the `core.editor` configuration variable, the `VISUAL` environment variable, or the `EDITOR` environment variable (in that order). See linkgit:git-var[1] for details. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/commit.txt[] +include::config/commit.adoc[] HOOKS ----- diff --git a/Documentation/git-config.txt b/Documentation/git-config.adoc similarity index 99% rename from Documentation/git-config.txt rename to Documentation/git-config.adoc index 7f81fbbea83a6e..936e0c5130fe7d 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.adoc @@ -12,7 +12,7 @@ SYNOPSIS 'git config list' [<file-option>] [<display-option>] [--includes] 'git config get' [<file-option>] [<display-option>] [--includes] [--all] [--regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name> 'git config set' [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value> -'git config unset' [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value> +'git config unset' [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> 'git config rename-section' [<file-option>] <old-name> <new-name> 'git config remove-section' [<file-option>] <name> 'git config edit' [<file-option>] @@ -213,7 +213,9 @@ See also <<FILES>>. + Valid `<type>`'s include: + -- 'bool': canonicalize values as either "true" or "false". +- 'bool': canonicalize values `true`, `yes`,`on`, and positive + numbers as "true", and values `false`, `no`, `off` and `0` as + "false". - 'int': canonicalize values as simple decimal numbers. An optional suffix of 'k', 'm', or 'g' will cause the value to be multiplied by 1024, 1048576, or 1073741824 upon input. @@ -610,7 +612,7 @@ http.cookieFile /tmp/cookie.txt http.sslverify false ------------ -include::config.txt[] +include::config.adoc[] BUGS ---- diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.adoc similarity index 100% rename from Documentation/git-count-objects.txt rename to Documentation/git-count-objects.adoc diff --git a/Documentation/git-credential-cache--daemon.txt b/Documentation/git-credential-cache--daemon.adoc similarity index 100% rename from Documentation/git-credential-cache--daemon.txt rename to Documentation/git-credential-cache--daemon.adoc diff --git a/Documentation/git-credential-cache.txt b/Documentation/git-credential-cache.adoc similarity index 77% rename from Documentation/git-credential-cache.txt rename to Documentation/git-credential-cache.adoc index 487cc557a87fea..54fa7a27e199f0 100644 --- a/Documentation/git-credential-cache.txt +++ b/Documentation/git-credential-cache.adoc @@ -78,6 +78,23 @@ variable (this example increases the cache time to 1 hour): $ git config credential.helper 'cache --timeout=3600' ------------------------------------------------------- +PERSONAL ACCESS TOKENS +---------------------- + +Some remotes accept personal access tokens, which are randomly +generated and hard to memorise. They typically have a lifetime of weeks +or months. + +git-credential-cache is inherently unsuitable for persistent storage of +personal access tokens. The credential will be forgotten after the cache +timeout. Even if you configure a long timeout, credentials will be +forgotten if the daemon dies. + +To avoid frequently regenerating personal access tokens, configure a +credential helper with persistent storage. Alternatively, configure an +OAuth credential helper to generate credentials automatically. See +linkgit:gitcredentials[7], sections "Available helpers" and "OAuth". + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-credential-store.txt b/Documentation/git-credential-store.adoc similarity index 100% rename from Documentation/git-credential-store.txt rename to Documentation/git-credential-store.adoc diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.adoc similarity index 100% rename from Documentation/git-credential.txt rename to Documentation/git-credential.adoc diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.adoc similarity index 100% rename from Documentation/git-cvsexportcommit.txt rename to Documentation/git-cvsexportcommit.adoc diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.adoc similarity index 100% rename from Documentation/git-cvsimport.txt rename to Documentation/git-cvsimport.adoc diff --git a/Documentation/git-cvsserver.txt b/Documentation/git-cvsserver.adoc similarity index 100% rename from Documentation/git-cvsserver.txt rename to Documentation/git-cvsserver.adoc diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.adoc similarity index 100% rename from Documentation/git-daemon.txt rename to Documentation/git-daemon.adoc diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.adoc similarity index 100% rename from Documentation/git-describe.txt rename to Documentation/git-describe.adoc diff --git a/Documentation/git-diagnose.txt b/Documentation/git-diagnose.adoc similarity index 100% rename from Documentation/git-diagnose.txt rename to Documentation/git-diagnose.adoc diff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.adoc similarity index 95% rename from Documentation/git-diff-files.txt rename to Documentation/git-diff-files.adoc index bf78e314313813..2b2358ca1ca719 100644 --- a/Documentation/git-diff-files.txt +++ b/Documentation/git-diff-files.adoc @@ -20,7 +20,7 @@ same as for 'git diff-index' and 'git diff-tree'. OPTIONS ------- -include::diff-options.txt[] +include::diff-options.adoc[] -1 --base:: -2 --ours:: @@ -45,7 +45,7 @@ omit diff output for unmerged entries and just show "Unmerged". Remain silent even for nonexistent files -include::diff-format.txt[] +include::diff-format.adoc[] GIT --- diff --git a/Documentation/git-diff-index.txt b/Documentation/git-diff-index.adoc similarity index 98% rename from Documentation/git-diff-index.txt rename to Documentation/git-diff-index.adoc index 4de1d4c8f11e60..911446a2964eb8 100644 --- a/Documentation/git-diff-index.txt +++ b/Documentation/git-diff-index.adoc @@ -21,7 +21,7 @@ files are compared. OPTIONS ------- -include::diff-options.txt[] +include::diff-options.adoc[] <tree-ish>:: The id of a tree object to diff against. @@ -40,7 +40,7 @@ include::diff-options.txt[] 'git diff-index' say that all non-checked-out files are up to date. -include::diff-format.txt[] +include::diff-format.adoc[] OPERATING MODES --------------- diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.adoc similarity index 97% rename from Documentation/git-diff-tree.txt rename to Documentation/git-diff-tree.adoc index 09286a85eb2cce..f1e3134bdefb9a 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.adoc @@ -24,7 +24,7 @@ Note that 'git diff-tree' can use the tree encapsulated in a commit object. OPTIONS ------- -include::diff-options.txt[] +include::diff-options.adoc[] <tree-ish>:: The id of a tree object. @@ -84,7 +84,7 @@ commits (but not trees). This flag causes 'git diff-tree --stdin' to also show the commit message before the differences. -include::pretty-options.txt[] +include::pretty-options.adoc[] --no-commit-id:: 'git diff-tree' outputs a line with the commit ID when @@ -122,9 +122,9 @@ include::pretty-options.txt[] if the diff itself is empty. -include::pretty-formats.txt[] +include::pretty-formats.adoc[] -include::diff-format.txt[] +include::diff-format.adoc[] GIT --- diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.adoc similarity index 60% rename from Documentation/git-diff.txt rename to Documentation/git-diff.adoc index c065f023eca3fb..dec173a345179e 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.adoc @@ -8,13 +8,13 @@ git-diff - Show changes between commits, commit and working tree, etc SYNOPSIS -------- -[verse] -'git diff' [<options>] [<commit>] [--] [<path>...] -'git diff' [<options>] --cached [--merge-base] [<commit>] [--] [<path>...] -'git diff' [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...] -'git diff' [<options>] <commit>...<commit> [--] [<path>...] -'git diff' [<options>] <blob> <blob> -'git diff' [<options>] --no-index [--] <path> <path> +[synopsis] +git diff [<options>] [<commit>] [--] [<path>...] +git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...] +git diff [<options>] [--merge-base] <commit> [<commit>...] <commit> [--] [<path>...] +git diff [<options>] <commit>...<commit> [--] [<path>...] +git diff [<options>] <blob> <blob> +git diff [<options>] --no-index [--] <path> <path> DESCRIPTION ----------- @@ -23,7 +23,7 @@ between the index and a tree, changes between two trees, changes resulting from a merge, changes between two blob objects, or changes between two files on disk. -'git diff' [<options>] [--] [<path>...]:: +`git diff [<options>] [--] [<path>...]`:: This form is to view the changes you made relative to the index (staging area for the next commit). In other @@ -31,7 +31,7 @@ files on disk. further add to the index but you still haven't. You can stage these changes by using linkgit:git-add[1]. -'git diff' [<options>] --no-index [--] <path> <path>:: +`git diff [<options>] --no-index [--] <path> <path>`:: This form is to compare the given two paths on the filesystem. You can omit the `--no-index` option when @@ -40,82 +40,82 @@ files on disk. or when running the command outside a working tree controlled by Git. This form implies `--exit-code`. -'git diff' [<options>] --cached [--merge-base] [<commit>] [--] [<path>...]:: +`git diff [<options>] --cached [--merge-base] [<commit>] [--] [<path>...]`:: This form is to view the changes you staged for the next - commit relative to the named <commit>. Typically you + commit relative to the named _<commit>_. Typically you would want comparison with the latest commit, so if you - do not give <commit>, it defaults to HEAD. - If HEAD does not exist (e.g. unborn branches) and - <commit> is not given, it shows all staged changes. - --staged is a synonym of --cached. + do not give _<commit>_, it defaults to `HEAD`. + If `HEAD` does not exist (e.g. unborn branches) and + _<commit>_ is not given, it shows all staged changes. + `--staged` is a synonym of `--cached`. + -If --merge-base is given, instead of using <commit>, use the merge base -of <commit> and HEAD. `git diff --cached --merge-base A` is equivalent to +If `--merge-base` is given, instead of using _<commit>_, use the merge base +of _<commit>_ and `HEAD`. `git diff --cached --merge-base A` is equivalent to `git diff --cached $(git merge-base A HEAD)`. -'git diff' [<options>] [--merge-base] <commit> [--] [<path>...]:: +`git diff [<options>] [--merge-base] <commit> [--] [<path>...]`:: This form is to view the changes you have in your - working tree relative to the named <commit>. You can - use HEAD to compare it with the latest commit, or a + working tree relative to the named _<commit>_. You can + use `HEAD` to compare it with the latest commit, or a branch name to compare with the tip of a different branch. + -If --merge-base is given, instead of using <commit>, use the merge base -of <commit> and HEAD. `git diff --merge-base A` is equivalent to +If `--merge-base` is given, instead of using _<commit>_, use the merge base +of _<commit>_ and `HEAD`. `git diff --merge-base A` is equivalent to `git diff $(git merge-base A HEAD)`. -'git diff' [<options>] [--merge-base] <commit> <commit> [--] [<path>...]:: +`git diff [<options>] [--merge-base] <commit> <commit> [--] [<path>...]`:: This is to view the changes between two arbitrary - <commit>. + _<commit>_. + -If --merge-base is given, use the merge base of the two commits for the +If `--merge-base` is given, use the merge base of the two commits for the "before" side. `git diff --merge-base A B` is equivalent to `git diff $(git merge-base A B) B`. -'git diff' [<options>] <commit> <commit>... <commit> [--] [<path>...]:: +`git diff [<options>] <commit> <commit>...<commit> [--] [<path>...]`:: This form is to view the results of a merge commit. The first - listed <commit> must be the merge itself; the remaining two or + listed _<commit>_ must be the merge itself; the remaining two or more commits should be its parents. Convenient ways to produce - the desired set of revisions are to use the suffixes `^@` and - `^!`. If A is a merge commit, then `git diff A A^@`, + the desired set of revisions are to use the suffixes `@` and + `^!`. If `A` is a merge commit, then `git diff A A^@`, `git diff A^!` and `git show A` all give the same combined diff. -'git diff' [<options>] <commit>..<commit> [--] [<path>...]:: +`git diff [<options>] <commit>..<commit> [--] [<path>...]`:: This is synonymous to the earlier form (without the `..`) for - viewing the changes between two arbitrary <commit>. If <commit> on + viewing the changes between two arbitrary _<commit>_. If _<commit>_ on one side is omitted, it will have the same effect as - using HEAD instead. + using `HEAD` instead. -'git diff' [<options>] <commit>\...<commit> [--] [<path>...]:: +`git diff [<options>] <commit>...<commit> [--] [<path>...]`:: This form is to view the changes on the branch containing - and up to the second <commit>, starting at a common ancestor - of both <commit>. `git diff A...B` is equivalent to + and up to the second _<commit>_, starting at a common ancestor + of both _<commit>_. `git diff A...B` is equivalent to `git diff $(git merge-base A B) B`. You can omit any one - of <commit>, which has the same effect as using HEAD instead. + of _<commit>_, which has the same effect as using `HEAD` instead. Just in case you are doing something exotic, it should be -noted that all of the <commit> in the above description, except +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 ref named `AUTO_MERGE`, which is written by the 'ort' merge +notations, can be any _<tree>_. A tree of interest is the one pointed to +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). -For a more complete list of ways to spell <commit>, see +For a more complete list of ways to spell _<commit>_, see "SPECIFYING REVISIONS" section in linkgit:gitrevisions[7]. -However, "diff" is about comparing two _endpoints_, not ranges, -and the range notations (`<commit>..<commit>` and -`<commit>...<commit>`) do not mean a range as defined in the +However, `diff` is about comparing two _endpoints_, not ranges, +and the range notations (`<commit>..<commit>` and `<commit>...<commit>`) +do not mean a range as defined in the "SPECIFYING RANGES" section in linkgit:gitrevisions[7]. -'git diff' [<options>] <blob> <blob>:: +`git diff [<options>] <blob> <blob>`:: This form is to view the differences between the raw contents of two blob objects. @@ -123,29 +123,38 @@ and the range notations (`<commit>..<commit>` and OPTIONS ------- :git-diff: 1 -include::diff-options.txt[] - --1 --base:: --2 --ours:: --3 --theirs:: - Compare the working tree with the "base" version (stage #1), - "our branch" (stage #2) or "their branch" (stage #3). The - index contains these stages only for unmerged entries i.e. - while resolving conflicts. See linkgit:git-read-tree[1] - section "3-Way Merge" for detailed information. - --0:: +include::diff-options.adoc[] + +`-1`:: +`--base`:: +`-2`:: +`--ours`:: +`-3`:: +`--theirs`:: + Compare the working tree with ++ +-- + * the "base" version (stage #1) when using `-1` or `--base`, + * "our branch" (stage #2) when using `-2` or `--ours`, or + * "their branch" (stage #3) when using `-3` or `--theirs`. +-- ++ +The index contains these stages only for unmerged entries i.e. +while resolving conflicts. See linkgit:git-read-tree[1] +section "3-Way Merge" for detailed information. + +`-0`:: Omit diff output for unmerged entries and just show "Unmerged". Can be used only when comparing the working tree with the index. -<path>...:: - The <paths> parameters, when given, are used to limit +`<path>...`:: + The _<path>_ parameters, when given, are used to limit the diff to the named paths (you can give directory names and get diff for all files under them). -include::diff-format.txt[] +include::diff-format.adoc[] EXAMPLES -------- @@ -223,13 +232,14 @@ $ git diff -R <2> CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/diff.txt[] +:git-diff: 1 +include::config/diff.adoc[] SEE ALSO -------- -diff(1), +`diff`(1), linkgit:git-difftool[1], linkgit:git-log[1], linkgit:gitdiffcore[7], diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.adoc similarity index 98% rename from Documentation/git-difftool.txt rename to Documentation/git-difftool.adoc index a616f8b2e6f349..d596205eaf3bfd 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.adoc @@ -119,9 +119,9 @@ CONFIGURATION 'git difftool' falls back to 'git mergetool' config variables when the difftool equivalents have not been defined. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/difftool.txt[] +include::config/difftool.adoc[] SEE ALSO -------- diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.adoc similarity index 100% rename from Documentation/git-fast-export.txt rename to Documentation/git-fast-export.adoc diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.adoc similarity index 99% rename from Documentation/git-fast-import.txt rename to Documentation/git-fast-import.adoc index 3d435157a66146..58a2eaa51a8034 100644 --- a/Documentation/git-fast-import.txt +++ b/Documentation/git-fast-import.adoc @@ -1578,9 +1578,9 @@ compression. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/fastimport.txt[] +include::config/fastimport.adoc[] SEE ALSO -------- diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.adoc similarity index 99% rename from Documentation/git-fetch-pack.txt rename to Documentation/git-fetch-pack.adoc index b3467664d30bde..b5223576a75088 100644 --- a/Documentation/git-fetch-pack.txt +++ b/Documentation/git-fetch-pack.adoc @@ -91,7 +91,7 @@ be in a separate packet, and the list must end with a flush packet. Deepen or shorten the history of a shallow repository to include all reachable commits after <date>. ---shallow-exclude=<revision>:: +--shallow-exclude=<ref>:: Deepen or shorten the history of a shallow repository to exclude commits reachable from a specified remote branch or tag. This option can be specified multiple times. diff --git a/Documentation/git-fetch.txt b/Documentation/git-fetch.adoc similarity index 98% rename from Documentation/git-fetch.txt rename to Documentation/git-fetch.adoc index 50900a50dabce9..16f5d9d69af78e 100644 --- a/Documentation/git-fetch.txt +++ b/Documentation/git-fetch.adoc @@ -44,15 +44,15 @@ may be used by scripts or other git commands, such as linkgit:git-pull[1]. OPTIONS ------- -include::fetch-options.txt[] +include::fetch-options.adoc[] -include::pull-fetch-param.txt[] +include::pull-fetch-param.adoc[] --stdin:: Read refspecs, one per line, from stdin in addition to those provided as arguments. The "tag <name>" format is not supported. -include::urls-remotes.txt[] +include::urls-remotes.adoc[] CONFIGURED REMOTE-TRACKING BRANCHES[[CRTB]] @@ -292,14 +292,14 @@ The first command fetches the `maint` branch from the repository at objects will eventually be removed by git's built-in housekeeping (see linkgit:git-gc[1]). -include::transfer-data-leaks.txt[] +include::transfer-data-leaks.adoc[] CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/fetch.txt[] +include::config/fetch.adoc[] BUGS ---- diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.adoc similarity index 100% rename from Documentation/git-filter-branch.txt rename to Documentation/git-filter-branch.adoc diff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.adoc similarity index 98% rename from Documentation/git-fmt-merge-msg.txt rename to Documentation/git-fmt-merge-msg.adoc index 6f28812f38defe..0f3328956dfda2 100644 --- a/Documentation/git-fmt-merge-msg.txt +++ b/Documentation/git-fmt-merge-msg.adoc @@ -55,7 +55,7 @@ OPTIONS CONFIGURATION ------------- -include::config/fmt-merge-msg.txt[] +include::config/fmt-merge-msg.adoc[] merge.summary:: Synonym to `merge.log`; this is deprecated and will be removed in diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.adoc similarity index 99% rename from Documentation/git-for-each-ref.txt rename to Documentation/git-for-each-ref.adoc index d3764401a2334b..ffb97e62c2d94e 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.adoc @@ -538,7 +538,7 @@ will be reported. NOTES ----- -include::ref-reachability-filters.txt[] +include::ref-reachability-filters.adoc[] SEE ALSO -------- diff --git a/Documentation/git-for-each-repo.txt b/Documentation/git-for-each-repo.adoc similarity index 100% rename from Documentation/git-for-each-repo.txt rename to Documentation/git-for-each-repo.adoc diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.adoc similarity index 99% rename from Documentation/git-format-patch.txt rename to Documentation/git-format-patch.adoc index 8708b3159309d5..a8b53db9a6635b 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.adoc @@ -105,7 +105,7 @@ reference. OPTIONS ------- :git-format-patch: 1 -include::diff-options.txt[] +include::diff-options.adoc[] -<n>:: Prepare patches from the topmost <n> commits. @@ -250,7 +250,7 @@ is not complete yet ("WIP" stands for "Work In Progress"). + If the convention of the receiving community for a particular extra string is to have it _after_ the subject prefix, the string _<rfc>_ -can be prefixed with a dash ("`-`") to signal that the the rest of +can be prefixed with a dash ("`-`") to signal that the rest of the _<rfc>_ string should be appended to the subject prefix instead, e.g., `--rfc='-(WIP)'` results in "PATCH (WIP)". diff --git a/Documentation/git-fsck-objects.txt b/Documentation/git-fsck-objects.adoc similarity index 100% rename from Documentation/git-fsck-objects.txt rename to Documentation/git-fsck-objects.adoc diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.adoc similarity index 98% rename from Documentation/git-fsck.txt rename to Documentation/git-fsck.adoc index 5b82e4605c2e91..8f32800a835fe8 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.adoc @@ -107,9 +107,9 @@ care about this output and want to speed it up further. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/fsck.txt[] +include::config/fsck.adoc[] DISCUSSION ---------- @@ -161,7 +161,7 @@ each error means, with their default severity. The severity of the error, other than those that are marked as "(FATAL)", can be tweaked by setting the corresponding `fsck.<msg-id>` configuration variable. -include::fsck-msgids.txt[] +include::fsck-msgids.adoc[] Environment Variables diff --git a/Documentation/git-fsmonitor--daemon.txt b/Documentation/git-fsmonitor--daemon.adoc similarity index 97% rename from Documentation/git-fsmonitor--daemon.txt rename to Documentation/git-fsmonitor--daemon.adoc index 8585d19f4d8987..8fe5241b08b007 100644 --- a/Documentation/git-fsmonitor--daemon.txt +++ b/Documentation/git-fsmonitor--daemon.adoc @@ -97,9 +97,9 @@ error that will cause the daemon and the currently running command to exit. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/fsmonitor--daemon.txt[] +include::config/fsmonitor--daemon.adoc[] GIT --- diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.adoc similarity index 94% rename from Documentation/git-gc.txt rename to Documentation/git-gc.adoc index 370e22faaeb55e..526ce01463d7ff 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.adoc @@ -69,6 +69,13 @@ be performed as well. the `--max-cruft-size` option of linkgit:git-repack[1] for more. +--expire-to=<dir>:: + When packing unreachable objects into a cruft pack, write a cruft + pack containing pruned objects (if any) to the directory `<dir>`. + This option only has an effect when used together with `--cruft`. + See the `--expire-to` option of linkgit:git-repack[1] for + more information. + --prune=<date>:: Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable `gc.pruneExpire`). @@ -122,9 +129,9 @@ users and their repositories. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/gc.txt[] +include::config/gc.adoc[] NOTES ----- diff --git a/Documentation/git-get-tar-commit-id.txt b/Documentation/git-get-tar-commit-id.adoc similarity index 100% rename from Documentation/git-get-tar-commit-id.txt rename to Documentation/git-get-tar-commit-id.adoc diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.adoc similarity index 99% rename from Documentation/git-grep.txt rename to Documentation/git-grep.adoc index 1e6d7b65c84e0f..a548585d4cbad5 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.adoc @@ -351,9 +351,9 @@ experienced in this case, it might be desirable to use `--threads=1`. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/grep.txt[] +include::config/grep.adoc[] GIT --- diff --git a/Documentation/git-gui.txt b/Documentation/git-gui.adoc similarity index 100% rename from Documentation/git-gui.txt rename to Documentation/git-gui.adoc diff --git a/Documentation/git-hash-object.txt b/Documentation/git-hash-object.adoc similarity index 100% rename from Documentation/git-hash-object.txt rename to Documentation/git-hash-object.adoc diff --git a/Documentation/git-help.txt b/Documentation/git-help.adoc similarity index 100% rename from Documentation/git-help.txt rename to Documentation/git-help.adoc diff --git a/Documentation/git-hook.txt b/Documentation/git-hook.adoc similarity index 100% rename from Documentation/git-hook.txt rename to Documentation/git-hook.adoc diff --git a/Documentation/git-http-backend.txt b/Documentation/git-http-backend.adoc similarity index 98% rename from Documentation/git-http-backend.txt rename to Documentation/git-http-backend.adoc index f37ddaded82b42..1dea4268520af4 100644 --- a/Documentation/git-http-backend.txt +++ b/Documentation/git-http-backend.adoc @@ -56,6 +56,10 @@ http.receivepack:: disabled by setting this item to `false`, or enabled for all users, including anonymous users, by setting it to `true`. +http.uploadarchive:: + This serves 'git archive' clients for remote archive over HTTP/HTTPS + protocols. It is disabled by default. It only works in protocol v2. + URL TRANSLATION --------------- To determine the location of the repository on disk, 'git http-backend' diff --git a/Documentation/git-http-fetch.txt b/Documentation/git-http-fetch.adoc similarity index 100% rename from Documentation/git-http-fetch.txt rename to Documentation/git-http-fetch.adoc diff --git a/Documentation/git-http-push.txt b/Documentation/git-http-push.adoc similarity index 100% rename from Documentation/git-http-push.txt rename to Documentation/git-http-push.adoc diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.adoc similarity index 97% rename from Documentation/git-imap-send.txt rename to Documentation/git-imap-send.adoc index c8a89d7243bfbd..26ccf4e433b44f 100644 --- a/Documentation/git-imap-send.txt +++ b/Documentation/git-imap-send.adoc @@ -54,9 +54,9 @@ CONFIGURATION To use the tool, `imap.folder` and either `imap.tunnel` or `imap.host` must be set to appropriate values. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/imap.txt[] +include::config/imap.adoc[] EXAMPLES -------- diff --git a/Documentation/git-index-pack.txt b/Documentation/git-index-pack.adoc similarity index 94% rename from Documentation/git-index-pack.txt rename to Documentation/git-index-pack.adoc index 5a20deefd5f5da..270056cf6352bd 100644 --- a/Documentation/git-index-pack.txt +++ b/Documentation/git-index-pack.adoc @@ -130,7 +130,7 @@ information on the possible values of `<msg-id>` and `<severity>`. + This option cannot be used with --stdin. + -include::object-format-disclaimer.txt[] +include::object-format-disclaimer.adoc[] --promisor[=<message>]:: Before committing the pack-index, create a .promisor file for this @@ -139,6 +139,13 @@ include::object-format-disclaimer.txt[] written. If a `<message>` is provided, then that content will be written to the .promisor file for future reference. See link:technical/partial-clone.html[partial clone] for more information. ++ +Also, if there are objects in the given pack that references non-promisor +objects (in the repo), repacks those non-promisor objects into a promisor +pack. This avoids a situation in which a repo has non-promisor objects that are +accessible through promisor objects. ++ +Requires <pack-file> to not be specified. NOTES ----- diff --git a/Documentation/git-init-db.txt b/Documentation/git-init-db.adoc similarity index 100% rename from Documentation/git-init-db.txt rename to Documentation/git-init-db.adoc diff --git a/Documentation/git-init.txt b/Documentation/git-init.adoc similarity index 85% rename from Documentation/git-init.txt rename to Documentation/git-init.adoc index daff93bd164b7c..a0dffba665fed6 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.adoc @@ -8,12 +8,12 @@ git-init - Create an empty Git repository or reinitialize an existing one 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>_] +[synopsis] +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>] DESCRIPTION @@ -25,11 +25,11 @@ directory with subdirectories for `objects`, `refs/heads`, commits will be created (see the `--initial-branch` option below for its name). -If the `$GIT_DIR` environment variable is set then it specifies a path +If the `GIT_DIR` environment variable is set then it specifies a path to use instead of `./.git` for the base of the repository. If the object storage directory is specified via the -`$GIT_OBJECT_DIRECTORY` environment variable then the sha1 directories +`GIT_OBJECT_DIRECTORY` environment variable then the sha1 directories are created underneath; otherwise, the default `$GIT_DIR/objects` directory is used. @@ -51,26 +51,22 @@ Only print error and warning messages; all other output will be suppressed. Create a bare repository. If `GIT_DIR` environment is not set, it is set to the current working directory. -++--object-format=++__<format>__:: - +`--object-format=<format>`:: Specify the given object _<format>_ (hash algorithm) for the repository. The valid values are `sha1` and (if enabled) `sha256`. `sha1` is the default. + -include::object-format-disclaimer.txt[] - -++--ref-format=++__<format>__:: +include::object-format-disclaimer.adoc[] +`--ref-format=<format>`:: Specify the given ref storage _<format>_ for the repository. The valid values are: + -include::ref-storage-format.txt[] - -++--template=++__<template-directory>__:: +include::ref-storage-format.adoc[] +`--template=<template-directory>`:: Specify the directory from which templates will be used. (See the "TEMPLATE DIRECTORY" section below.) -++--separate-git-dir=++__<git-dir>__:: - +`--separate-git-dir=<git-dir>`:: Instead of initializing the repository as a directory to either `$GIT_DIR` or `./.git/`, create a text file there containing the path to the actual repository. This file acts as a filesystem-agnostic Git symbolic link to the @@ -78,15 +74,14 @@ repository. + If this is a reinitialization, the repository will be moved to the specified path. -`-b` _<branch-name>_:: -++--initial-branch=++__<branch-name>__:: - +`-b <branch-name>`:: +`--initial-branch=<branch-name>`:: Use _<branch-name>_ for the initial branch in the newly created repository. If not specified, fall back to the default name (currently `master`, but this is subject to change in the future; the name can be customized via the `init.defaultBranch` configuration variable). -++--shared++[++=++(`false`|`true`|`umask`|`group`|`all`|`world`|`everybody`|_<perm>_)]:: +`--shared[=(false|true|umask|group|all|world|everybody|<perm>)]`:: Specify that the Git repository is to be shared amongst several users. This allows users belonging to the same group to push into that @@ -183,11 +178,11 @@ $ git commit <3> CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] :git-init: -include::config/init.txt[] +include::config/init.adoc[] GIT --- diff --git a/Documentation/git-instaweb.txt b/Documentation/git-instaweb.adoc similarity index 100% rename from Documentation/git-instaweb.txt rename to Documentation/git-instaweb.adoc diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.adoc similarity index 68% rename from Documentation/git-interpret-trailers.txt rename to Documentation/git-interpret-trailers.adoc index d9dfb75fef525f..82c8780d932f33 100644 --- a/Documentation/git-interpret-trailers.txt +++ b/Documentation/git-interpret-trailers.adoc @@ -186,142 +186,9 @@ OPTIONS CONFIGURATION VARIABLES ----------------------- -trailer.separators:: - This option tells which characters are recognized as trailer - separators. By default only ':' is recognized as a trailer - separator, except that '=' is always accepted on the command - line for compatibility with other git commands. -+ -The first character given by this option will be the default character -used when another separator is not specified in the config for this -trailer. -+ -For example, if the value for this option is "%=$", then only lines -using the format '<key><sep><value>' with <sep> containing '%', '=' -or '$' and then spaces will be considered trailers. And '%' will be -the default separator used, so by default trailers will appear like: -'<key>% <value>' (one percent sign and one space will appear between -the key and the value). - -trailer.where:: - This option tells where a new trailer will be added. -+ -This can be `end`, which is the default, `start`, `after` or `before`. -+ -If it is `end`, then each new trailer will appear at the end of the -existing trailers. -+ -If it is `start`, then each new trailer will appear at the start, -instead of the end, of the existing trailers. -+ -If it is `after`, then each new trailer will appear just after the -last trailer with the same <key>. -+ -If it is `before`, then each new trailer will appear just before the -first trailer with the same <key>. +include::includes/cmd-config-section-all.adoc[] -trailer.ifexists:: - This option makes it possible to choose what action will be - performed when there is already at least one trailer with the - same <key> in the input. -+ -The valid values for this option are: `addIfDifferentNeighbor` (this -is the default), `addIfDifferent`, `add`, `replace` or `doNothing`. -+ -With `addIfDifferentNeighbor`, a new trailer will be added only if no -trailer with the same (<key>, <value>) pair is above or below the line -where the new trailer will be added. -+ -With `addIfDifferent`, a new trailer will be added only if no trailer -with the same (<key>, <value>) pair is already in the input. -+ -With `add`, a new trailer will be added, even if some trailers with -the same (<key>, <value>) pair are already in the input. -+ -With `replace`, an existing trailer with the same <key> will be -deleted and the new trailer will be added. The deleted trailer will be -the closest one (with the same <key>) to the place where the new one -will be added. -+ -With `doNothing`, nothing will be done; that is no new trailer will be -added if there is already one with the same <key> in the input. - -trailer.ifmissing:: - This option makes it possible to choose what action will be - performed when there is not yet any trailer with the same - <key> in the input. -+ -The valid values for this option are: `add` (this is the default) and -`doNothing`. -+ -With `add`, a new trailer will be added. -+ -With `doNothing`, nothing will be done. - -trailer.<keyAlias>.key:: - Defines a <keyAlias> for the <key>. The <keyAlias> must be a - prefix (case does not matter) of the <key>. For example, in `git - config trailer.ack.key "Acked-by"` the "Acked-by" is the <key> and - the "ack" is the <keyAlias>. This configuration allows the shorter - `--trailer "ack:..."` invocation on the command line using the "ack" - <keyAlias> instead of the longer `--trailer "Acked-by:..."`. -+ -At the end of the <key>, a separator can appear and then some -space characters. By default the only valid separator is ':', -but this can be changed using the `trailer.separators` config -variable. -+ -If there is a separator in the key, then it overrides the default -separator when adding the trailer. - -trailer.<keyAlias>.where:: - This option takes the same values as the 'trailer.where' - configuration variable and it overrides what is specified by - that option for trailers with the specified <keyAlias>. - -trailer.<keyAlias>.ifexists:: - This option takes the same values as the 'trailer.ifexists' - configuration variable and it overrides what is specified by - that option for trailers with the specified <keyAlias>. - -trailer.<keyAlias>.ifmissing:: - This option takes the same values as the 'trailer.ifmissing' - configuration variable and it overrides what is specified by - that option for trailers with the specified <keyAlias>. - -trailer.<keyAlias>.command:: - Deprecated in favor of 'trailer.<keyAlias>.cmd'. - This option behaves in the same way as 'trailer.<keyAlias>.cmd', except - that it doesn't pass anything as argument to the specified command. - Instead the first occurrence of substring $ARG is replaced by the - <value> that would be passed as argument. -+ -Note that $ARG in the user's command is -only replaced once and that the original way of replacing $ARG is not safe. -+ -When both 'trailer.<keyAlias>.cmd' and 'trailer.<keyAlias>.command' are given -for the same <keyAlias>, 'trailer.<keyAlias>.cmd' is used and -'trailer.<keyAlias>.command' is ignored. - -trailer.<keyAlias>.cmd:: - This option can be used to specify a shell command that will be called - once to automatically add a trailer with the specified <keyAlias>, and then - called each time a '--trailer <keyAlias>=<value>' argument is specified to - modify the <value> of the trailer that this option would produce. -+ -When the specified command is first called to add a trailer -with the specified <keyAlias>, the behavior is as if a special -'--trailer <keyAlias>=<value>' argument was added at the beginning -of the "git interpret-trailers" command, where <value> -is taken to be the standard output of the command with any -leading and trailing whitespace trimmed off. -+ -If some '--trailer <keyAlias>=<value>' arguments are also passed -on the command line, the command is called again once for each -of these arguments with the same <keyAlias>. And the <value> part -of these arguments, if any, will be passed to the command as its -first argument. This way the command can produce a <value> computed -from the <value> passed in the '--trailer <keyAlias>=<value>' argument. +include::config/trailer.adoc[] EXAMPLES -------- diff --git a/Documentation/git-log.txt b/Documentation/git-log.adoc similarity index 95% rename from Documentation/git-log.txt rename to Documentation/git-log.adoc index 579682172fe458..ae8a7e2d638949 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.adoc @@ -16,7 +16,7 @@ DESCRIPTION Shows the commit logs. :git-log: 1 -include::rev-list-description.txt[] +include::rev-list-description.adoc[] The command takes options applicable to the linkgit:git-rev-list[1] command to control what is shown and how, and options applicable to @@ -89,7 +89,7 @@ produced by `--stat`, etc. Intended to speed up tools that read log messages from `git log` output by allowing them to allocate space in advance. -include::line-range-options.txt[] +include::line-range-options.adoc[] <revision-range>:: Show only commits in the specified revision range. When no @@ -109,9 +109,9 @@ include::line-range-options.txt[] Paths may need to be prefixed with `--` to separate them from options or the revision range, when confusion arises. -include::rev-list-options.txt[] +include::rev-list-options.adoc[] -include::pretty-formats.txt[] +include::pretty-formats.adoc[] DIFF FORMATTING --------------- @@ -128,9 +128,9 @@ the default format for merge commits. :git-log: 1 :diff-merges-default: `off` -include::diff-options.txt[] +include::diff-options.adoc[] -include::diff-generate-patch.txt[] +include::diff-generate-patch.adoc[] EXAMPLES -------- @@ -192,7 +192,7 @@ EXAMPLES DISCUSSION ---------- -include::i18n.txt[] +include::i18n.adoc[] CONFIGURATION ------------- @@ -209,11 +209,11 @@ i18n.logOutputEncoding:: Defaults to the value of `i18n.commitEncoding` if set, and UTF-8 otherwise. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/log.txt[] +include::config/log.adoc[] -include::config/notes.txt[] +include::config/notes.adoc[] GIT --- diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.adoc similarity index 100% rename from Documentation/git-ls-files.txt rename to Documentation/git-ls-files.adoc diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.adoc similarity index 96% rename from Documentation/git-ls-remote.txt rename to Documentation/git-ls-remote.adoc index 76c86c3ce4fee0..d71c4ab3e290c5 100644 --- a/Documentation/git-ls-remote.txt +++ b/Documentation/git-ls-remote.adoc @@ -81,6 +81,9 @@ OPTIONS character. When multiple `--server-option=<option>` are given, they are all sent to the other side in the order listed on the command line. + When no `--server-option=<option>` is given from the command line, + the values of configuration variable `remote.<name>.serverOption` + are used instead. <repository>:: The "remote" repository to query. This parameter can be diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.adoc similarity index 100% rename from Documentation/git-ls-tree.txt rename to Documentation/git-ls-tree.adoc diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.adoc similarity index 97% rename from Documentation/git-mailinfo.txt rename to Documentation/git-mailinfo.adoc index 28060283c703a9..3b24c9abd98636 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.adoc @@ -118,9 +118,9 @@ If no such configuration option has been set, `warn` will be used. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/mailinfo.txt[] +include::config/mailinfo.adoc[] GIT --- diff --git a/Documentation/git-mailsplit.txt b/Documentation/git-mailsplit.adoc similarity index 100% rename from Documentation/git-mailsplit.txt rename to Documentation/git-mailsplit.adoc diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.adoc similarity index 98% rename from Documentation/git-maintenance.txt rename to Documentation/git-maintenance.adoc index 9d968191331080..0450d74aff1ea2 100644 --- a/Documentation/git-maintenance.txt +++ b/Documentation/git-maintenance.adoc @@ -220,7 +220,9 @@ on an hourly basis. Each run executes the "hourly" tasks. At midnight, that process also executes the "daily" tasks. At midnight on the first day of the week, that process also executes the "weekly" tasks. A single process iterates over each registered repository, performing the scheduled -tasks for that frequency. Depending on the number of registered +tasks for that frequency. The processes are scheduled to a random minute of +the hour per client to spread out the load that multiple clients might +generate (e.g. from prefetching). Depending on the number of registered repositories and their sizes, this process may take longer than an hour. In this case, multiple `git maintenance run` commands may run on the same repository at the same time, colliding on the object database lock. This @@ -407,9 +409,9 @@ custom tasks. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/maintenance.txt[] +include::config/maintenance.adoc[] GIT diff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.adoc similarity index 100% rename from Documentation/git-merge-base.txt rename to Documentation/git-merge-base.adoc diff --git a/Documentation/git-merge-file.txt b/Documentation/git-merge-file.adoc similarity index 100% rename from Documentation/git-merge-file.txt rename to Documentation/git-merge-file.adoc diff --git a/Documentation/git-merge-index.txt b/Documentation/git-merge-index.adoc similarity index 100% rename from Documentation/git-merge-index.txt rename to Documentation/git-merge-index.adoc diff --git a/Documentation/git-merge-one-file.txt b/Documentation/git-merge-one-file.adoc similarity index 100% rename from Documentation/git-merge-one-file.txt rename to Documentation/git-merge-one-file.adoc diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.adoc similarity index 95% rename from Documentation/git-merge-tree.txt rename to Documentation/git-merge-tree.adoc index 84cb2edf6d0922..cf0578f9b5e86d 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.adoc @@ -40,11 +40,17 @@ After the merge completes, a new toplevel tree object is created. See OPTIONS ------- +--stdin:: + Read the commits to merge from the standard input rather than + the command-line. See <<INPUT,INPUT FORMAT>> below for more + information. Implies `-z`. + -z:: Do not quote filenames in the <Conflicted file info> section, and end each filename with a NUL character rather than newline. Also begin the messages section with a NUL character - instead of a newline. See <<OUTPUT>> below for more information. + instead of a newline. See <<OUTPUT,OUTPUT>> below for more + information. --name-only:: In the Conflicted file info section, instead of writing a list @@ -116,8 +122,6 @@ This is an integer status followed by a NUL character. The integer status is: 0: merge had conflicts 1: merge was clean - <0: something prevented the merge from running (e.g. access to repository - objects denied by filesystem) [[OIDTLT]] OID of toplevel tree @@ -211,9 +215,15 @@ linkgit:git-commit-tree[1], linkgit:git-write-tree[1], linkgit:git-update-ref[1], and linkgit:git-mktag[1]. Thus, it can be used as a part of a series of steps such as: - NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) - test $? -eq 0 || die "There were conflicts..." - NEWCOMMIT=$(git commit-tree $NEWTREE -p $BRANCH1 -p $BRANCH2) + vi message.txt + BRANCH1=refs/heads/test + BRANCH2=main + NEWTREE=$(git merge-tree --write-tree $BRANCH1 $BRANCH2) || { + echo "There were conflicts..." 1>&2 + exit 1 + } + NEWCOMMIT=$(git commit-tree $NEWTREE -F message.txt \ + -p $BRANCH1 -p $BRANCH2) git update-ref $BRANCH1 $NEWCOMMIT Note that when the exit status is non-zero, `NEWTREE` in this sequence @@ -229,6 +239,7 @@ with linkgit:git-merge[1]: * any messages that would have been printed to stdout (the <<IM,Informational messages>>) +[[INPUT]] INPUT FORMAT ------------ 'git merge-tree --stdin' input format is fully text based. Each line diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.adoc similarity index 98% rename from Documentation/git-merge.txt rename to Documentation/git-merge.adoc index 1ab69f61f5749a..64281d6d44ddf7 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.adoc @@ -65,7 +65,7 @@ OPTIONS ------- :git-merge: 1 -include::merge-options.txt[] +include::merge-options.adoc[] -m <msg>:: Set the commit message to be used for the merge commit (in @@ -91,7 +91,7 @@ invocations. The automated message can include the branch description. If `--log` is specified, a shortlog of the commits being merged will be appended to the specified message. -include::rerere-options.txt[] +include::rerere-options.adoc[] --overwrite-ignore:: --no-overwrite-ignore:: @@ -385,7 +385,7 @@ changes into a merge commit. Small fixups like bumping release/version name would be acceptable. -include::merge-strategies.txt[] +include::merge-strategies.adoc[] CONFIGURATION ------------- @@ -395,9 +395,9 @@ branch.<name>.mergeOptions:: supported options are the same as those of `git merge`, but option values containing whitespace characters are currently not supported. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/merge.txt[] +include::config/merge.adoc[] SEE ALSO -------- diff --git a/Documentation/git-mergetool--lib.txt b/Documentation/git-mergetool--lib.adoc similarity index 100% rename from Documentation/git-mergetool--lib.txt rename to Documentation/git-mergetool--lib.adoc diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.adoc similarity index 97% rename from Documentation/git-mergetool.txt rename to Documentation/git-mergetool.adoc index b9e20c5dcd8c52..046c3258f0508d 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.adoc @@ -104,9 +104,9 @@ CONFIGURATION ------------- :git-mergetool: 1 -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/mergetool.txt[] +include::config/mergetool.adoc[] TEMPORARY FILES --------------- @@ -123,7 +123,7 @@ BACKEND SPECIFIC HINTS vimdiff ~~~~~~~ -include::mergetools/vimdiff.txt[] +include::mergetools/vimdiff.adoc[] GIT --- diff --git a/Documentation/git-mktag.txt b/Documentation/git-mktag.adoc similarity index 100% rename from Documentation/git-mktag.txt rename to Documentation/git-mktag.adoc diff --git a/Documentation/git-mktree.txt b/Documentation/git-mktree.adoc similarity index 100% rename from Documentation/git-mktree.txt rename to Documentation/git-mktree.adoc diff --git a/Documentation/git-multi-pack-index.txt b/Documentation/git-multi-pack-index.adoc similarity index 100% rename from Documentation/git-multi-pack-index.txt rename to Documentation/git-multi-pack-index.adoc diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.adoc similarity index 100% rename from Documentation/git-mv.txt rename to Documentation/git-mv.adoc diff --git a/Documentation/git-name-rev.txt b/Documentation/git-name-rev.adoc similarity index 100% rename from Documentation/git-name-rev.txt rename to Documentation/git-name-rev.adoc diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.adoc similarity index 70% rename from Documentation/git-notes.txt rename to Documentation/git-notes.adoc index c9221a68ccedc8..bcfe3dacd3f0de 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.adoc @@ -7,19 +7,19 @@ git-notes - Add or inspect object notes SYNOPSIS -------- -[verse] -'git notes' [list [<object>]] -'git notes' add [-f] [--allow-empty] [--[no-]separator | --separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>] -'git notes' copy [-f] ( --stdin | <from-object> [<to-object>] ) -'git notes' append [--allow-empty] [--[no-]separator | --separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [<object>] -'git notes' edit [--allow-empty] [<object>] [--[no-]stripspace] -'git notes' show [<object>] -'git notes' merge [-v | -q] [-s <strategy> ] <notes-ref> -'git notes' merge --commit [-v | -q] -'git notes' merge --abort [-v | -q] -'git notes' remove [--ignore-missing] [--stdin] [<object>...] -'git notes' prune [-n] [-v] -'git notes' get-ref +[synopsis] +git notes [list [<object>]] +git notes add [-f] [--allow-empty] [--[no-]separator | --separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [-e] [<object>] +git notes copy [-f] ( --stdin | <from-object> [<to-object>] ) +git notes append [--allow-empty] [--[no-]separator | --separator=<paragraph-break>] [--[no-]stripspace] [-F <file> | -m <msg> | (-c | -C) <object>] [-e] [<object>] +git notes edit [--allow-empty] [<object>] [--[no-]stripspace] +git notes show [<object>] +git notes merge [-v | -q] [-s <strategy> ] <notes-ref> +git notes merge --commit [-v | -q] +git notes merge --abort [-v | -q] +git notes remove [--ignore-missing] [--stdin] [<object>...] +git notes prune [-n] [-v] +git notes get-ref DESCRIPTION @@ -33,46 +33,48 @@ ENVIRONMENT sections below. If this ref does not exist, it will be quietly created when it is first needed to store a note. A typical use of notes is to supplement a commit message without -changing the commit itself. Notes can be shown by 'git log' along with +changing the commit itself. Notes can be shown by `git log` along with the original commit message. To distinguish these notes from the message stored in the commit object, the notes are indented like the -message, after an unindented line saying "Notes (<refname>):" (or +message, after an unindented line saying "Notes (_<refname>_):" (or "Notes:" for `refs/notes/commits`). Notes can also be added to patches prepared with `git format-patch` by using the `--notes` option. Such notes are added as a patch commentary after a three dash separator line. -To change which notes are shown by 'git log', see the -"notes.displayRef" discussion in <<CONFIGURATION>>. +To change which notes are shown by `git log`, see the +`notes.displayRef` discussion in <<CONFIGURATION,CONFIGURATION>>. -See the "notes.rewrite.<command>" configuration for a way to carry +See the `notes.rewrite.<command>` configuration for a way to carry notes across commands that rewrite commits. SUBCOMMANDS ----------- -list:: +`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:: - Add notes for a given object (defaults to HEAD). Abort if the +`add`:: + Add notes for a given object (defaults to `HEAD`). Abort if the object already has notes (use `-f` to overwrite existing notes). However, if you're using `add` interactively (using an editor to supply the notes contents), then - instead of aborting - the existing notes will be opened in the editor (like the `edit` subcommand). If you specify multiple `-m` and `-F`, a blank line will be inserted between the messages. Use the `--separator` - option to insert other delimiters. + option to insert other delimiters. You can use `-e` to edit and + fine-tune the message(s) supplied from `-m` and `-F` options + interactively (using an editor) before adding the note. -copy:: +`copy`:: Copy the notes for the first object onto the second object (defaults to - HEAD). Abort if the second object already has notes, or if the first - object has none (use -f to overwrite existing notes to the + `HEAD`). Abort if the second object already has notes, or if the first + object has none (use `-f` to overwrite existing notes to the second object). This subcommand is equivalent to: `git notes add [-f] -C $(git notes list <from-object>) <to-object>` + @@ -82,25 +84,27 @@ In `--stdin` mode, take lines in the format <from-object> SP <to-object> [ SP <rest> ] LF ---------- + -on standard input, and copy the notes from each <from-object> to its -corresponding <to-object>. (The optional `<rest>` is ignored so that +on standard input, and copy the notes from each _<from-object>_ to its +corresponding _<to-object>_. (The optional _<rest>_ is ignored so that the command can read the input given to the `post-rewrite` hook.) -append:: +`append`:: Append new message(s) given by `-m` or `-F` options to an existing note, or add them as a new note if one does not - exist, for the object (defaults to HEAD). When appending to + exist, for the object (defaults to `HEAD`). When appending to an existing note, a blank line is added before each new message as an inter-paragraph separator. The separator can be customized with the `--separator` option. + Edit the notes to be appended given by `-m` and `-F` options with + `-e` interactively (using an editor) before appending the note. -edit:: - Edit the notes for a given object (defaults to HEAD). +`edit`:: + Edit the notes for a given object (defaults to `HEAD`). -show:: - Show the notes for a given object (defaults to HEAD). +`show`:: + Show the notes for a given object (defaults to `HEAD`). -merge:: +`merge`:: Merge the given notes ref into the current notes ref. This will try to merge the changes made by the given notes ref (called "remote") since the merge-base (if @@ -108,35 +112,35 @@ merge:: + If conflicts arise and a strategy for automatically resolving conflicting notes (see the "NOTES MERGE STRATEGIES" section) is not given, -the "manual" resolver is used. This resolver checks out the +the `manual` resolver is used. This resolver checks out the conflicting notes in a special worktree (`.git/NOTES_MERGE_WORKTREE`), and instructs the user to manually resolve the conflicts there. When done, the user can either finalize the merge with -'git notes merge --commit', or abort the merge with -'git notes merge --abort'. +`git notes merge --commit`, or abort the merge with +`git notes merge --abort`. -remove:: - Remove the notes for given objects (defaults to HEAD). When +`remove`:: + Remove the notes for given objects (defaults to `HEAD`). When giving zero or one object from the command line, this is equivalent to specifying an empty note message to the `edit` subcommand. -prune:: +`prune`:: Remove all notes for non-existing/unreachable objects. -get-ref:: +`get-ref`:: Print the current notes ref. This provides an easy way to retrieve the current notes ref (e.g. from scripts). OPTIONS ------- --f:: ---force:: +`-f`:: +`--force`:: When adding notes to an object that already has notes, overwrite the existing notes (instead of aborting). --m <msg>:: ---message=<msg>:: +`-m <msg>`:: +`--message=<msg>`:: Use the given note message (instead of prompting). If multiple `-m` options are given, their values are concatenated as separate paragraphs. @@ -144,95 +148,96 @@ OPTIONS single line between paragraphs will be stripped out. If you wish to keep them verbatim, use `--no-stripspace`. --F <file>:: ---file=<file>:: - Take the note message from the given file. Use '-' to +`-F <file>`:: +`--file=<file>`:: + Take the note message from the given file. Use `-` to read the note message from the standard input. Lines starting with `#` and empty lines other than a single line between paragraphs will be stripped out. If you wish to keep them verbatim, use `--no-stripspace`. --C <object>:: ---reuse-message=<object>:: +`-C <object>`:: +`--reuse-message=<object>`:: Take the given blob object (for example, another note) as the note message. (Use `git notes copy <object>` instead to copy notes between objects.). By default, message will be copied verbatim, but if you wish to strip out the lines starting with `#` and empty lines other than a single line - between paragraphs, use with`--stripspace` option. + between paragraphs, use with `--stripspace` option. --c <object>:: ---reedit-message=<object>:: - Like '-C', but with `-c` the editor is invoked, so that +`-c <object>`:: +`--reedit-message=<object>`:: + Like `-C`, but with `-c` the editor is invoked, so that the user can further edit the note message. ---allow-empty:: +`--allow-empty`:: Allow an empty note object to be stored. The default behavior is to automatically remove empty notes. ---[no-]separator, --separator=<paragraph-break>:: +`--[no-]separator`:: +`--separator=<paragraph-break>`:: Specify a string used as a custom inter-paragraph separator (a newline is added at the end as needed). If `--no-separator`, no separators will be added between paragraphs. Defaults to a blank line. ---[no-]stripspace:: +`--[no-]stripspace`:: Strip leading and trailing whitespace from the note message. Also strip out empty lines other than a single line between paragraphs. Lines starting with `#` will be stripped out in non-editor cases like `-m`, `-F` and `-C`, but not in editor case like `git notes edit`, `-c`, etc. ---ref <ref>:: - Manipulate the notes tree in <ref>. This overrides - `GIT_NOTES_REF` and the "core.notesRef" configuration. The ref +`--ref <ref>`:: + Manipulate the notes tree in _<ref>_. This overrides + `GIT_NOTES_REF` and the `core.notesRef` configuration. The ref specifies the full refname when it begins with `refs/notes/`; when it begins with `notes/`, `refs/` and otherwise `refs/notes/` is prefixed to form a full name of the ref. ---ignore-missing:: +`--ignore-missing`:: Do not consider it an error to request removing notes from an object that does not have notes attached to it. ---stdin:: +`--stdin`:: Also read the object names to remove notes from the standard input (there is no reason you cannot combine this with object names from the command line). --n:: ---dry-run:: +`-n`:: +`--dry-run`:: Do not remove anything; just report the object names whose notes would be removed. --s <strategy>:: ---strategy=<strategy>:: +`-s <strategy>`:: +`--strategy=<strategy>`:: When merging notes, resolve notes conflicts using the given - strategy. The following strategies are recognized: "manual" - (default), "ours", "theirs", "union" and "cat_sort_uniq". - This option overrides the "notes.mergeStrategy" configuration setting. + strategy. The following strategies are recognized: `manual` + (default), `ours`, `theirs`, `union` and `cat_sort_uniq`. + This option overrides the `notes.mergeStrategy` configuration setting. See the "NOTES MERGE STRATEGIES" section below for more information on each notes merge strategy. ---commit:: - Finalize an in-progress 'git notes merge'. Use this option - when you have resolved the conflicts that 'git notes merge' - stored in .git/NOTES_MERGE_WORKTREE. This amends the partial - merge commit created by 'git notes merge' (stored in - .git/NOTES_MERGE_PARTIAL) by adding the notes in - .git/NOTES_MERGE_WORKTREE. The notes ref stored in the - .git/NOTES_MERGE_REF symref is updated to the resulting commit. - ---abort:: - Abort/reset an in-progress 'git notes merge', i.e. a notes merge +`--commit`:: + Finalize an in-progress `git notes merge`. Use this option + when you have resolved the conflicts that `git notes merge` + stored in `.git/NOTES_MERGE_WORKTREE`. This amends the partial + merge commit created by `git notes merge` (stored in + `.git/NOTES_MERGE_PARTIAL`) by adding the notes in + `.git/NOTES_MERGE_WORKTREE`. The notes ref stored in the + `.git/NOTES_MERGE_REF` symref is updated to the resulting commit. + +`--abort`:: + Abort/reset an in-progress `git notes merge`, i.e. a notes merge with conflicts. This simply removes all files related to the notes merge. --q:: ---quiet:: +`-q`:: +`--quiet`:: When merging notes, operate quietly. --v:: ---verbose:: +`-v`:: +`--verbose`:: When merging notes, be more verbose. When pruning notes, report all object names whose notes are removed. @@ -266,28 +271,28 @@ object, in which case the history of the notes can be read with NOTES MERGE STRATEGIES ---------------------- -The default notes merge strategy is "manual", which checks out +The default notes merge strategy is `manual`, which checks out conflicting notes in a special work tree for resolving notes conflicts (`.git/NOTES_MERGE_WORKTREE`), and instructs the user to resolve the conflicts in that work tree. When done, the user can either finalize the merge with -'git notes merge --commit', or abort the merge with -'git notes merge --abort'. +`git notes merge --commit`, or abort the merge with +`git notes merge --abort`. Users may select an automated merge strategy from among the following using -either -s/--strategy option or configuring notes.mergeStrategy accordingly: +either `-s`/`--strategy` option or configuring `notes.mergeStrategy` accordingly: -"ours" automatically resolves conflicting notes in favor of the local +`ours` automatically resolves conflicting notes in favor of the local version (i.e. the current notes ref). -"theirs" automatically resolves notes conflicts in favor of the remote +`theirs` automatically resolves notes conflicts in favor of the remote version (i.e. the given notes ref being merged into the current notes ref). -"union" automatically resolves notes conflicts by concatenating the +`union` automatically resolves notes conflicts by concatenating the local and remote versions. -"cat_sort_uniq" is similar to "union", but in addition to concatenating +`cat_sort_uniq` is similar to `union`, but in addition to concatenating the local and remote versions, this strategy also sorts the resulting lines, and removes duplicate lines from the result. This is equivalent to applying the "cat | sort | uniq" shell pipeline to the local and @@ -316,7 +321,7 @@ Notes: In principle, a note is a regular Git blob, and any kind of (non-)format is accepted. You can binary-safely create notes from -arbitrary files using 'git hash-object': +arbitrary files using `git hash-object`: ------------ $ cc *.c @@ -327,7 +332,7 @@ $ git notes --ref=built add --allow-empty -C "$blob" HEAD (You cannot simply use `git notes --ref=built add -F a.out HEAD` because that is not binary-safe.) Of course, it doesn't make much sense to display non-text-format notes -with 'git log', so if you use such notes, you'll probably need to write +with `git log`, so if you use such notes, you'll probably need to write some special-purpose tools to do something useful with them. @@ -335,15 +340,15 @@ some special-purpose tools to do something useful with them. CONFIGURATION ------------- -core.notesRef:: +`core.notesRef`:: Notes ref to read and manipulate instead of `refs/notes/commits`. Must be an unabbreviated ref name. This setting can be overridden through the environment and command line. -include::includes/cmd-config-section-rest.txt[] +include::includes/cmd-config-section-rest.adoc[] -include::config/notes.txt[] +include::config/notes.adoc[] ENVIRONMENT diff --git a/Documentation/git-p4.txt b/Documentation/git-p4.adoc similarity index 100% rename from Documentation/git-p4.txt rename to Documentation/git-p4.adoc diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.adoc similarity index 91% rename from Documentation/git-pack-objects.txt rename to Documentation/git-pack-objects.adoc index e32404c6aaee30..7f69ae4855f6ce 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.adoc @@ -15,7 +15,8 @@ SYNOPSIS [--revs [--unpacked | --all]] [--keep-pack=<pack-name>] [--cruft] [--cruft-expiration=<time>] [--stdout [--filter=<filter-spec>] | <base-name>] - [--shallow] [--keep-true-parents] [--[no-]sparse] < <object-list> + [--shallow] [--keep-true-parents] [--[no-]sparse] + [--name-hash-version=<n>] < <object-list> DESCRIPTION @@ -345,6 +346,35 @@ raise an error. Restrict delta matches based on "islands". See DELTA ISLANDS below. +--name-hash-version=<n>:: + While performing delta compression, Git groups objects that may be + similar based on heuristics using the path to that object. While + grouping objects by an exact path match is good for paths with + many versions, there are benefits for finding delta pairs across + different full paths. Git collects objects by type and then by a + "name hash" of the path and then by size, hoping to group objects + that will compress well together. ++ +The default name hash version is `1`, which prioritizes hash locality by +considering the final bytes of the path as providing the maximum magnitude +to the hash function. This version excels at distinguishing short paths +and finding renames across directories. However, the hash function depends +primarily on the final 16 bytes of the path. If there are many paths in +the repo that have the same final 16 bytes and differ only by parent +directory, then this name-hash may lead to too many collisions and cause +poor results. At the moment, this version is required when writing +reachability bitmap files with `--write-bitmap-index`. ++ +The name hash version `2` has similar locality features as version `1`, +except it considers each path component separately and overlays the hashes +with a shift. This still prioritizes the final bytes of the path, but also +"salts" the lower bits of the hash using the parent directory names. This +method allows for some of the locality benefits of version `1` while +breaking most of the collisions from a similarly-named file appearing in +many different directories. At the moment, this version is not allowed +when writing reachability bitmap files with `--write-bitmap-index` and it +will be automatically changed to version `1`. + DELTA ISLANDS ------------- diff --git a/Documentation/git-pack-redundant.txt b/Documentation/git-pack-redundant.adoc similarity index 100% rename from Documentation/git-pack-redundant.txt rename to Documentation/git-pack-redundant.adoc diff --git a/Documentation/git-pack-refs.txt b/Documentation/git-pack-refs.adoc similarity index 100% rename from Documentation/git-pack-refs.txt rename to Documentation/git-pack-refs.adoc diff --git a/Documentation/git-patch-id.txt b/Documentation/git-patch-id.adoc similarity index 100% rename from Documentation/git-patch-id.txt rename to Documentation/git-patch-id.adoc diff --git a/Documentation/git-prune-packed.txt b/Documentation/git-prune-packed.adoc similarity index 100% rename from Documentation/git-prune-packed.txt rename to Documentation/git-prune-packed.adoc diff --git a/Documentation/git-prune.txt b/Documentation/git-prune.adoc similarity index 100% rename from Documentation/git-prune.txt rename to Documentation/git-prune.adoc diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.adoc similarity index 97% rename from Documentation/git-pull.txt rename to Documentation/git-pull.adoc index b2ae496e488c1e..3f4ecc47301ae3 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.adoc @@ -102,7 +102,7 @@ Options related to merging :git-pull: 1 -include::merge-options.txt[] +include::merge-options.adoc[] -r:: --rebase[=(false|true|merges|interactive)]:: @@ -136,13 +136,13 @@ unless you have read linkgit:git-rebase[1] carefully. Options related to fetching ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -include::fetch-options.txt[] +include::fetch-options.adoc[] -include::pull-fetch-param.txt[] +include::pull-fetch-param.adoc[] -include::urls-remotes.txt[] +include::urls-remotes.adoc[] -include::merge-strategies.txt[] +include::merge-strategies.adoc[] DEFAULT BEHAVIOUR ----------------- @@ -234,7 +234,7 @@ If you tried a pull which resulted in complex conflicts and would want to start over, you can recover with 'git reset'. -include::transfer-data-leaks.txt[] +include::transfer-data-leaks.adoc[] BUGS ---- diff --git a/Documentation/git-push.txt b/Documentation/git-push.adoc similarity index 99% rename from Documentation/git-push.txt rename to Documentation/git-push.adoc index 9b7cfbc5c1d849..d1978650d60a7c 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.adoc @@ -432,7 +432,7 @@ further recursion will occur. In this case, "only" is treated as "on-demand". --ipv6:: Use IPv6 addresses only, ignoring IPv4 addresses. -include::urls-remotes.txt[] +include::urls-remotes.adoc[] OUTPUT ------ @@ -695,14 +695,14 @@ Commits A and B would no longer belong to a branch with a symbolic name, and so would be unreachable. As such, these commits would be removed by a `git gc` command on the origin repository. -include::transfer-data-leaks.txt[] +include::transfer-data-leaks.adoc[] CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/push.txt[] +include::config/push.adoc[] GIT --- diff --git a/Documentation/git-quiltimport.txt b/Documentation/git-quiltimport.adoc similarity index 100% rename from Documentation/git-quiltimport.txt rename to Documentation/git-quiltimport.adoc diff --git a/Documentation/git-range-diff.txt b/Documentation/git-range-diff.adoc similarity index 93% rename from Documentation/git-range-diff.txt rename to Documentation/git-range-diff.adoc index fbdbe0befebab6..db0e4279b52847 100644 --- a/Documentation/git-range-diff.txt +++ b/Documentation/git-range-diff.adoc @@ -10,7 +10,8 @@ SYNOPSIS [verse] 'git range-diff' [--color=[<when>]] [--no-color] [<diff-options>] [--no-dual-color] [--creation-factor=<factor>] - [--left-only | --right-only] + [--left-only | --right-only] [--diff-merges=<format>] + [--remerge-diff] ( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> ) [[--] <path>...] @@ -81,6 +82,20 @@ to revert to color all lines according to the outer diff markers Suppress commits that are missing from the second specified range (or the "right range" when using the `<rev1>...<rev2>` format). +--diff-merges=<format>:: + Instead of ignoring merge commits, generate diffs for them using the + corresponding `--diff-merges=<format>` option of linkgit:git-log[1], + and include them in the comparison. ++ +Note: In the common case, the `remerge` mode will be the most natural one +to use, as it shows only the diff on top of what Git's merge machinery would +have produced. In other words, if a merge commit is the result of a +non-conflicting `git merge`, the `remerge` mode will represent it with an empty +diff. + +--remerge-diff:: + Convenience option, equivalent to `--diff-merges=remerge`. + --[no-]notes[=<ref>]:: This flag is passed to the `git log` program (see linkgit:git-log[1]) that generates the patches. diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.adoc similarity index 100% rename from Documentation/git-read-tree.txt rename to Documentation/git-read-tree.adoc diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.adoc similarity index 99% rename from Documentation/git-rebase.txt rename to Documentation/git-rebase.adoc index b18cdbc0239dbb..153cb69a4f810e 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.adoc @@ -401,7 +401,7 @@ See also INCOMPATIBLE OPTIONS below. + See also INCOMPATIBLE OPTIONS below. -include::rerere-options.txt[] +include::rerere-options.adoc[] -S[<keyid>]:: --gpg-sign[=<keyid>]:: @@ -599,11 +599,11 @@ See also INCOMPATIBLE OPTIONS below. --no-autosquash:: Automatically squash commits with specially formatted messages into previous commits being rebased. If a commit message starts with - "squash! ", "fixup! " or "amend! ", the remainder of the subject line + "squash! ", "fixup! " or "amend! ", the remainder of the title is taken as a commit specifier, which matches a previous commit if it - matches the subject line or the hash of that commit. If no commit + matches the title or the hash of that commit. If no commit matches fully, matches of the specifier with the start of commit - subjects are considered. + titles are considered. + In the rebase todo list, the actions of squash, fixup and amend commits are changed from `pick` to `squash`, `fixup` or `fixup -C`, respectively, and they @@ -613,7 +613,7 @@ be used to review and edit the todo list before proceeding. The recommended way to create commits with squash markers is by using the `--squash`, `--fixup`, `--fixup=amend:` or `--fixup=reword:` options of linkgit:git-commit[1], which take the target commit as an argument and -automatically fill in the subject line of the new commit from that. +automatically fill in the title of the new commit from that. + Setting configuration variable `rebase.autoSquash` to true enables auto-squashing by default for interactive rebase. The `--no-autosquash` @@ -825,7 +825,7 @@ completeness: * State directories: The two backends keep their state in different directories under `.git/` -include::merge-strategies.txt[] +include::merge-strategies.adoc[] NOTES ----- @@ -1294,10 +1294,10 @@ merge cmake CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/rebase.txt[] -include::config/sequencer.txt[] +include::config/rebase.adoc[] +include::config/sequencer.adoc[] GIT --- diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.adoc similarity index 100% rename from Documentation/git-receive-pack.txt rename to Documentation/git-receive-pack.adoc diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.adoc similarity index 100% rename from Documentation/git-reflog.txt rename to Documentation/git-reflog.adoc diff --git a/Documentation/git-refs.txt b/Documentation/git-refs.adoc similarity index 84% rename from Documentation/git-refs.txt rename to Documentation/git-refs.adoc index ce31f93061db5e..4d6dc994f92eb2 100644 --- a/Documentation/git-refs.txt +++ b/Documentation/git-refs.adoc @@ -8,9 +8,9 @@ git-refs - Low-level access to refs SYNOPSIS -------- -[verse] -'git refs migrate' --ref-format=<format> [--dry-run] -'git refs verify' [--strict] [--verbose] +[synopsis] +git refs migrate --ref-format=<format> [--no-reflog] [--dry-run] +git refs verify [--strict] [--verbose] DESCRIPTION ----------- @@ -34,7 +34,7 @@ The following options are specific to 'git refs migrate': --ref-format=<format>:: The ref format to migrate the ref store to. Can be one of: + -include::ref-storage-format.txt[] +include::ref-storage-format.adoc[] --dry-run:: Perform the migration, but do not modify the repository. The migrated @@ -43,6 +43,11 @@ include::ref-storage-format.txt[] can be used to double check that the migration works as expected before performing the actual migration. +--reflog:: +--no-reflog:: + Choose between migrating the reflog data to the new backend, + and discarding them. The default is "--reflog", to migrate. + The following options are specific to 'git refs verify': --strict:: @@ -57,8 +62,6 @@ KNOWN LIMITATIONS The ref format migration has several known limitations in its current form: -* It is not possible to migrate repositories that have reflogs. - * It is not possible to migrate repositories that have worktrees. * There is no way to block concurrent writes to the repository during an diff --git a/Documentation/git-remote-ext.txt b/Documentation/git-remote-ext.adoc similarity index 100% rename from Documentation/git-remote-ext.txt rename to Documentation/git-remote-ext.adoc diff --git a/Documentation/git-remote-fd.txt b/Documentation/git-remote-fd.adoc similarity index 100% rename from Documentation/git-remote-fd.txt rename to Documentation/git-remote-fd.adoc diff --git a/Documentation/git-remote-helpers.txto b/Documentation/git-remote-helpers.adoco similarity index 100% rename from Documentation/git-remote-helpers.txto rename to Documentation/git-remote-helpers.adoco diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.adoc similarity index 100% rename from Documentation/git-remote.txt rename to Documentation/git-remote.adoc diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.adoc similarity index 97% rename from Documentation/git-repack.txt rename to Documentation/git-repack.adoc index c902512a9e89b0..5852a5c9736875 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.adoc @@ -9,7 +9,9 @@ git-repack - Pack unpacked objects in a repository SYNOPSIS -------- [verse] -'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m] [--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>] [--write-midx] +'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m] + [--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>] + [--write-midx] [--name-hash-version=<n>] DESCRIPTION ----------- @@ -249,6 +251,11 @@ linkgit:git-multi-pack-index[1]). Write a multi-pack index (see linkgit:git-multi-pack-index[1]) containing the non-redundant packs. +--name-hash-version=<n>:: + Provide this argument to the underlying `git pack-objects` process. + See linkgit:git-pack-objects[1] for full details. + + CONFIGURATION ------------- diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.adoc similarity index 100% rename from Documentation/git-replace.txt rename to Documentation/git-replace.adoc diff --git a/Documentation/git-replay.txt b/Documentation/git-replay.adoc similarity index 99% rename from Documentation/git-replay.txt rename to Documentation/git-replay.adoc index 8f3300c683a7bf..0b12bf8aa4df42 100644 --- a/Documentation/git-replay.txt +++ b/Documentation/git-replay.adoc @@ -49,7 +49,7 @@ the new commits (in other words, this mimics a cherry-pick operation). to. See "Specifying Ranges" in linkgit:git-rev-parse[1] and the "Commit Limiting" options below. -include::rev-list-options.txt[] +include::rev-list-options.adoc[] OUTPUT ------ diff --git a/Documentation/git-request-pull.txt b/Documentation/git-request-pull.adoc similarity index 100% rename from Documentation/git-request-pull.txt rename to Documentation/git-request-pull.adoc diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.adoc similarity index 100% rename from Documentation/git-rerere.txt rename to Documentation/git-rerere.adoc diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.adoc similarity index 100% rename from Documentation/git-reset.txt rename to Documentation/git-reset.adoc diff --git a/Documentation/git-restore.txt b/Documentation/git-restore.adoc similarity index 70% rename from Documentation/git-restore.txt rename to Documentation/git-restore.adoc index 975825b44aa4d0..751f01b4418b5b 100644 --- a/Documentation/git-restore.txt +++ b/Documentation/git-restore.adoc @@ -7,10 +7,10 @@ git-restore - Restore working tree files SYNOPSIS -------- -[verse] -'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>... -'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] --pathspec-from-file=<file> [--pathspec-file-nul] -'git restore' (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [--] [<pathspec>...] +[synopsis] +git restore [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>... +git restore [<options>] [--source=<tree>] [--staged] [--worktree] --pathspec-from-file=<file> [--pathspec-file-nul] +git restore (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [--] [<pathspec>...] DESCRIPTION ----------- @@ -32,8 +32,8 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. OPTIONS ------- --s <tree>:: ---source=<tree>:: +`-s <tree>`:: +`--source=<tree>`:: Restore the working tree files with the content from the given tree. It is common to specify the source tree by naming a commit, branch or tag associated with it. @@ -41,79 +41,79 @@ OPTIONS If not specified, the contents are restored from `HEAD` if `--staged` is given, otherwise from the index. + -As a special case, you may use `"A...B"` as a shortcut for the -merge base of `A` and `B` if there is exactly one merge base. You can -leave out at most one of `A` and `B`, in which case it defaults to `HEAD`. +As a special case, you may use `"<rev-A>...<rev-B>"` as a shortcut for the +merge base of _<rev-A>_ and _<rev-B>_ if there is exactly one merge base. You can +leave out at most one of _<rev-A>__ and _<rev-B>_, in which case it defaults to `HEAD`. --p:: ---patch:: +`-p`:: +`--patch`:: Interactively select hunks in the difference between the - restore source and the restore location. See the ``Interactive - Mode'' section of linkgit:git-add[1] to learn how to operate + restore source and the restore location. See the "Interactive + Mode" section of linkgit:git-add[1] to learn how to operate the `--patch` mode. + Note that `--patch` can accept no pathspec and will prompt to restore all modified paths. --W:: ---worktree:: --S:: ---staged:: +`-W`:: +`--worktree`:: +`-S`:: +`--staged`:: Specify the restore location. If neither option is specified, by default the working tree is restored. Specifying `--staged` will only restore the index. Specifying both restores both. --q:: ---quiet:: +`-q`:: +`--quiet`:: Quiet, suppress feedback messages. Implies `--no-progress`. ---progress:: ---no-progress:: +`--progress`:: +`--no-progress`:: Progress status is reported on the standard error stream by default when it is attached to a terminal, unless `--quiet` is specified. This flag enables progress reporting even if not attached to a terminal, regardless of `--quiet`. ---ours:: ---theirs:: +`--ours`:: +`--theirs`:: When restoring files in the working tree from the index, use - stage #2 ('ours') or #3 ('theirs') for unmerged paths. + stage #2 (`ours`) or #3 (`theirs`) for unmerged paths. This option cannot be used when checking out paths from a tree-ish (i.e. with the `--source` option). + -Note that during `git rebase` and `git pull --rebase`, 'ours' and -'theirs' may appear swapped. See the explanation of the same options +Note that during `git rebase` and `git pull --rebase`, `ours` and +`theirs` may appear swapped. See the explanation of the same options in linkgit:git-checkout[1] for details. --m:: ---merge:: +`-m`:: +`--merge`:: When restoring files on the working tree from the index, recreate the conflicted merge in the unmerged paths. This option cannot be used when checking out paths from a tree-ish (i.e. with the `--source` option). ---conflict=<style>:: +`--conflict=<style>`:: The same as `--merge` option above, but changes the way the conflicting hunks are presented, overriding the `merge.conflictStyle` configuration variable. Possible values - are "merge" (default), "diff3", and "zdiff3". + are `merge` (default), `diff3`, and `zdiff3`. ---ignore-unmerged:: +`--ignore-unmerged`:: When restoring files on the working tree from the index, do not abort the operation if there are unmerged entries and neither `--ours`, `--theirs`, `--merge` or `--conflict` is specified. Unmerged paths on the working tree are left alone. ---ignore-skip-worktree-bits:: +`--ignore-skip-worktree-bits`:: In sparse checkout mode, the default is to only update entries - matched by `<pathspec>` and sparse patterns in - $GIT_DIR/info/sparse-checkout. This option ignores the sparse + matched by _<pathspec>_ and sparse patterns in + `$GIT_DIR/info/sparse-checkout`. This option ignores the sparse patterns and unconditionally restores any files in - `<pathspec>`. + _<pathspec>_. ---recurse-submodules:: ---no-recurse-submodules:: - If `<pathspec>` names an active submodule and the restore location +`--recurse-submodules`:: +`--no-recurse-submodules`:: + If _<pathspec>_ names an active submodule and the restore location includes the working tree, the submodule will only be updated if this option is given, in which case its working tree will be restored to the commit recorded in the superproject, and any local @@ -122,30 +122,30 @@ in linkgit:git-checkout[1] for details. not be updated. Just like linkgit:git-checkout[1], this will detach `HEAD` of the submodule. ---overlay:: ---no-overlay:: - In overlay mode, the command never removes files when - restoring. In no-overlay mode, tracked files that do not - appear in the `--source` tree are removed, to make them match - `<tree>` exactly. The default is no-overlay mode. - ---pathspec-from-file=<file>:: - 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 +`--overlay`:: +`--no-overlay`:: + In overlay mode, never remove files when restoring. In no-overlay mode, + remove tracked files that do not appear in the _<tree>_ of + `--source=<tree>`, to make them match _<tree>_ exactly. The default + is no-overlay mode. + +`--pathspec-from-file=<file>`:: + 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 global `--literal-pathspecs`. ---pathspec-file-nul:: +`--pathspec-file-nul`:: Only meaningful with `--pathspec-from-file`. Pathspec elements are - separated with NUL character and all other characters are taken + separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). -\--:: +`--`:: Do not interpret any more arguments as options. -<pathspec>...:: +`<pathspec>...`:: Limits the paths affected by the operation. + For more details, see the 'pathspec' entry in linkgit:gitglossary[7]. @@ -154,7 +154,7 @@ EXAMPLES -------- The following sequence switches to the `master` branch, reverts the -`Makefile` to two revisions back, deletes hello.c by mistake, and gets +`Makefile` to two revisions back, deletes `hello.c` by mistake, and gets it back from the index. ------------ @@ -165,7 +165,7 @@ $ git restore hello.c <2> ------------ <1> take a file out of another commit -<2> restore hello.c from the index +<2> restore `hello.c` from the index If you want to restore _all_ C source files to match the version in the index, you can say diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.adoc similarity index 96% rename from Documentation/git-rev-list.txt rename to Documentation/git-rev-list.adoc index 2e05c4b510927a..f582491dd43313 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.adoc @@ -15,7 +15,7 @@ DESCRIPTION ----------- :git-rev-list: 1 -include::rev-list-description.txt[] +include::rev-list-description.adoc[] 'rev-list' is an essential Git command, since it provides the ability to build and traverse commit ancestry graphs. For @@ -27,9 +27,9 @@ OPTIONS ------- :git-rev-list: 1 -include::rev-list-options.txt[] +include::rev-list-options.adoc[] -include::pretty-formats.txt[] +include::pretty-formats.adoc[] EXAMPLES -------- diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.adoc similarity index 99% rename from Documentation/git-rev-parse.txt rename to Documentation/git-rev-parse.adoc index dc12d38534605e..cc32b4b4f0f999 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.adoc @@ -351,7 +351,7 @@ Other Options Flags and parameters to be parsed. -include::revisions.txt[] +include::revisions.adoc[] PARSEOPT -------- diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.adoc similarity index 97% rename from Documentation/git-revert.txt rename to Documentation/git-revert.adoc index 568925db533879..ffba365e63981d 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.adoc @@ -112,7 +112,7 @@ effect to your index in a row. Pass the merge strategy-specific option through to the merge strategy. See linkgit:git-merge[1] for details. -include::rerere-options.txt[] +include::rerere-options.adoc[] --reference:: Instead of starting the body of the log message with "This @@ -125,7 +125,7 @@ include::rerere-options.txt[] SEQUENCER SUBCOMMANDS --------------------- -include::sequencer.txt[] +include::sequencer.adoc[] EXAMPLES -------- @@ -155,9 +155,9 @@ Please consider rewording these to be shorter and more unique. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/revert.txt[] +include::config/revert.adoc[] SEE ALSO -------- diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.adoc similarity index 100% rename from Documentation/git-rm.txt rename to Documentation/git-rm.adoc diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.adoc similarity index 99% rename from Documentation/git-send-email.txt rename to Documentation/git-send-email.adoc index bc3ef45acbd134..7f223db42dd313 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.adoc @@ -492,9 +492,9 @@ Information CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/sendemail.txt[] +include::config/sendemail.adoc[] EXAMPLES -------- diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.adoc similarity index 100% rename from Documentation/git-send-pack.txt rename to Documentation/git-send-pack.adoc diff --git a/Documentation/git-sh-i18n--envsubst.txt b/Documentation/git-sh-i18n--envsubst.adoc similarity index 100% rename from Documentation/git-sh-i18n--envsubst.txt rename to Documentation/git-sh-i18n--envsubst.adoc diff --git a/Documentation/git-sh-i18n.txt b/Documentation/git-sh-i18n.adoc similarity index 100% rename from Documentation/git-sh-i18n.txt rename to Documentation/git-sh-i18n.adoc diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.adoc similarity index 100% rename from Documentation/git-sh-setup.txt rename to Documentation/git-sh-setup.adoc diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.adoc similarity index 100% rename from Documentation/git-shell.txt rename to Documentation/git-shell.adoc diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.adoc similarity index 99% rename from Documentation/git-shortlog.txt rename to Documentation/git-shortlog.adoc index 7d0277d033d602..d8ab38dcc1f1a6 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.adoc @@ -114,7 +114,7 @@ Paths may need to be prefixed with `--` to separate them from options or the revision range, when confusion arises. :git-shortlog: 1 -include::rev-list-options.txt[] +include::rev-list-options.adoc[] MAPPING AUTHORS --------------- diff --git a/Documentation/git-show-branch.txt b/Documentation/git-show-branch.adoc similarity index 98% rename from Documentation/git-show-branch.txt rename to Documentation/git-show-branch.adoc index bc31d8b6d330c4..7e86d54a24fc59 100644 --- a/Documentation/git-show-branch.txt +++ b/Documentation/git-show-branch.adoc @@ -202,9 +202,9 @@ topologically related to each other. CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/showbranch.txt[] +include::config/showbranch.adoc[] GIT --- diff --git a/Documentation/git-show-index.txt b/Documentation/git-show-index.adoc similarity index 92% rename from Documentation/git-show-index.txt rename to Documentation/git-show-index.adoc index e49318a5a0aec7..00b3a908cdba48 100644 --- a/Documentation/git-show-index.txt +++ b/Documentation/git-show-index.adoc @@ -9,7 +9,7 @@ git-show-index - Show packed archive index SYNOPSIS -------- [verse] -'git show-index' [--object-format=<hash-algorithm>] +'git show-index' [--object-format=<hash-algorithm>] < <pack-idx-file> DESCRIPTION @@ -45,7 +45,7 @@ OPTIONS algorithm for the current repository (set by `extensions.objectFormat`), or 'sha1' if no value is set or outside a repository.. + -include::object-format-disclaimer.txt[] +include::object-format-disclaimer.adoc[] GIT --- diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.adoc similarity index 100% rename from Documentation/git-show-ref.txt rename to Documentation/git-show-ref.adoc diff --git a/Documentation/git-show.txt b/Documentation/git-show.adoc similarity index 92% rename from Documentation/git-show.txt rename to Documentation/git-show.adoc index 5eb67439affbef..51044c814f5d06 100644 --- a/Documentation/git-show.txt +++ b/Documentation/git-show.adoc @@ -39,10 +39,10 @@ OPTIONS For a more complete list of ways to spell object names, see "SPECIFYING REVISIONS" section in linkgit:gitrevisions[7]. -include::pretty-options.txt[] +include::pretty-options.adoc[] -include::pretty-formats.txt[] +include::pretty-formats.adoc[] DIFF FORMATTING @@ -52,9 +52,9 @@ diff output. :git-log: 1 :diff-merges-default: `dense-combined` -include::diff-options.txt[] +include::diff-options.adoc[] -include::diff-generate-patch.txt[] +include::diff-generate-patch.adoc[] EXAMPLES @@ -83,7 +83,7 @@ EXAMPLES DISCUSSION ---------- -include::i18n.txt[] +include::i18n.adoc[] GIT --- diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.adoc similarity index 100% rename from Documentation/git-sparse-checkout.txt rename to Documentation/git-sparse-checkout.adoc diff --git a/Documentation/git-stage.txt b/Documentation/git-stage.adoc similarity index 100% rename from Documentation/git-stage.txt rename to Documentation/git-stage.adoc diff --git a/Documentation/git-stash.txt b/Documentation/git-stash.adoc similarity index 99% rename from Documentation/git-stash.txt rename to Documentation/git-stash.adoc index 06fb7f1d18c6be..1a5177f4986ca4 100644 --- a/Documentation/git-stash.txt +++ b/Documentation/git-stash.adoc @@ -388,9 +388,9 @@ xargs git log --merges --no-walk --grep=WIP CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/stash.txt[] +include::config/stash.adoc[] SEE ALSO diff --git a/Documentation/git-status.txt b/Documentation/git-status.adoc similarity index 100% rename from Documentation/git-status.txt rename to Documentation/git-status.adoc diff --git a/Documentation/git-stripspace.txt b/Documentation/git-stripspace.adoc similarity index 100% rename from Documentation/git-stripspace.txt rename to Documentation/git-stripspace.adoc diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.adoc similarity index 100% rename from Documentation/git-submodule.txt rename to Documentation/git-submodule.adoc diff --git a/Documentation/git-survey.adoc b/Documentation/git-survey.adoc new file mode 100644 index 00000000000000..8d433f57e194d0 --- /dev/null +++ b/Documentation/git-survey.adoc @@ -0,0 +1,79 @@ +git-survey(1) +============= + +NAME +---- +git-survey - Measure various repository dimensions of scale + +SYNOPSIS +-------- +[synopsis] +git survey [--[no-]progress] [--all-refs] + [--branches] [--tags] [--remotes] [--detached] [--other] + +DESCRIPTION +----------- + +Survey the repository and measure various dimensions of scale. + +As repositories grow to "monorepo" size, certain data shapes can cause +performance problems. `git-survey` attempts to measure and report on +known problem areas. + +THIS COMMAND IS EXPERIMENTAL. ITS BEHAVIOR MAY CHANGE IN THE FUTURE. + +OPTIONS +------- + +`--[no-]progress`:: + Show progress. This is automatically enabled when interactive. + +Ref Selection +~~~~~~~~~~~~~ + +The following options control the set of refs that `git survey` will examine. +By default, `git survey` will look at tags, local branches, and remote refs. +If any of the following options are given, the default set is cleared and +only refs for the given options are added. + +`--all-refs`:: + Use all refs. This includes local branches, tags, remote refs, + notes, and stashes. This option overrides all of the following. + +`--branches`:: + Add local branches (`refs/heads/`) to the set. + +`--tags`:: + Add tags (`refs/tags/`) to the set. + +`--remotes`:: + Add remote branches (`refs/remote/`) to the set. + +`--detached`:: + Add HEAD to the set. + +`--other`:: + Add notes (`refs/notes/`) and stashes (`refs/stash/`) to the set. + +OUTPUT +------ + +By default, `git survey` will print information about the repository in a +human-readable format that includes overviews and tables. + +References Summary +~~~~~~~~~~~~~~~~~~ + +The references summary includes a count of each kind of reference, +including branches, remote refs, and tags (split by "all" and +"annotated"). + +Reachable Object Summary +~~~~~~~~~~~~~~~~~~~~~~~~ + +The reachable object summary shows the total number of each kind of Git +object, including tags, commits, trees, and blobs. + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.adoc similarity index 100% rename from Documentation/git-svn.txt rename to Documentation/git-svn.adoc diff --git a/Documentation/git-switch.txt b/Documentation/git-switch.adoc similarity index 99% rename from Documentation/git-switch.txt rename to Documentation/git-switch.adoc index f38e4c8afa1bcb..f55315c51ea080 100644 --- a/Documentation/git-switch.txt +++ b/Documentation/git-switch.adoc @@ -273,9 +273,9 @@ $ git switch -c good-surprises CONFIGURATION ------------- -include::includes/cmd-config-section-all.txt[] +include::includes/cmd-config-section-all.adoc[] -include::config/checkout.txt[] +include::config/checkout.adoc[] SEE ALSO -------- diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.adoc similarity index 98% rename from Documentation/git-symbolic-ref.txt rename to Documentation/git-symbolic-ref.adoc index 761b154bcbb58b..33ca381fde0f93 100644 --- a/Documentation/git-symbolic-ref.txt +++ b/Documentation/git-symbolic-ref.adoc @@ -73,6 +73,10 @@ default. symbolic ref were printed correctly, with status 1 if the requested name is not a symbolic ref, or 128 if another error occurs. +SEE ALSO +-------- +linkgit:git-update-ref[1] + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.adoc similarity index 99% rename from Documentation/git-tag.txt rename to Documentation/git-tag.adoc index 4494729f5e167f..a4b1c0ec05a6c9 100644 --- a/Documentation/git-tag.txt +++ b/Documentation/git-tag.adoc @@ -391,7 +391,7 @@ For example: $ GIT_COMMITTER_DATE="2006-10-02 10:31" git tag -s v1.0.1 ------------ -include::date-formats.txt[] +include::date-formats.adoc[] FILES ----- @@ -406,7 +406,7 @@ FILES NOTES ----- -include::ref-reachability-filters.txt[] +include::ref-reachability-filters.adoc[] SEE ALSO -------- diff --git a/Documentation/git-tools.txt b/Documentation/git-tools.adoc similarity index 100% rename from Documentation/git-tools.txt rename to Documentation/git-tools.adoc diff --git a/Documentation/git-unpack-file.txt b/Documentation/git-unpack-file.adoc similarity index 100% rename from Documentation/git-unpack-file.txt rename to Documentation/git-unpack-file.adoc diff --git a/Documentation/git-unpack-objects.txt b/Documentation/git-unpack-objects.adoc similarity index 100% rename from Documentation/git-unpack-objects.txt rename to Documentation/git-unpack-objects.adoc diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.adoc similarity index 100% rename from Documentation/git-update-index.txt rename to Documentation/git-update-index.adoc diff --git a/Documentation/git-update-ref.txt b/Documentation/git-update-ref.adoc similarity index 81% rename from Documentation/git-update-ref.txt rename to Documentation/git-update-ref.adoc index afcf33cf608f19..9e6935d38d031b 100644 --- a/Documentation/git-update-ref.txt +++ b/Documentation/git-update-ref.adoc @@ -25,37 +25,16 @@ value is <old-oid>. You can specify 40 "0" or an empty string as <old-oid> to make sure that the ref you are creating does not exist. -It also allows a "ref" file to be a symbolic pointer to another -ref file by starting with the four-byte header sequence of -"ref:". - -More importantly, it allows the update of a ref file to follow -these symbolic pointers, whether they are symlinks or these -"regular file symbolic refs". It follows *real* symlinks only -if they start with "refs/": otherwise it will just try to read -them and update them as a regular file (i.e. it will allow the -filesystem to follow them, but will overwrite such a symlink to -somewhere else with a regular filename). +The final arguments are object names; this command without any options +does not support updating a symbolic ref to point to another ref (see +linkgit:git-symbolic-ref[1]). But `git update-ref --stdin` does have +the `symref-*` commands so that regular refs and symbolic refs can be +committed in the same transaction. If --no-deref is given, <ref> itself is overwritten, rather than the result of following the symbolic pointers. -In general, using - - git update-ref HEAD "$head" - -should be a _lot_ safer than doing - - echo "$head" > "$GIT_DIR/HEAD" - -both from a symlink following standpoint *and* an error checking -standpoint. The "refs/" rule for symlinks means that symlinks -that point to "outside" the tree are safe: they'll be followed -for reading but not for writing (so we'll never write through a -ref symlink to some other tree, if you have copied a whole -archive by creating a symlink tree). - -With `-d` flag, it deletes the named <ref> after verifying it +With `-d`, it deletes the named <ref> after verifying that it still contains <old-oid>. With `--stdin`, update-ref reads instructions from standard input and @@ -114,11 +93,11 @@ update:: ref does not exist before the update. create:: - Create <ref> with <new-oid> after verifying it does not + Create <ref> with <new-oid> after verifying that it does not exist. The given <new-oid> may not be zero. delete:: - Delete <ref> after verifying it exists with <old-oid>, if + Delete <ref> after verifying that it exists with <old-oid>, if given. If given, <old-oid> may not be zero. symref-update:: @@ -131,11 +110,11 @@ verify:: <old-oid> is zero or missing, the ref must not exist. symref-create: - Create symbolic ref <ref> with <new-target> after verifying + Create symbolic ref <ref> with <new-target> after verifying that it does not exist. symref-delete:: - Delete <ref> after verifying it exists with <old-target>, if given. + Delete <ref> after verifying that it exists with <old-target>, if given. symref-verify:: Verify symbolic <ref> against <old-target> but do not change it. @@ -200,6 +179,21 @@ An update will fail (without changing <ref>) if the current user is unable to create a new log file, append to the existing log file or does not have committer information available. +NOTES +----- + +Symbolic refs were initially implemented using symbolic links. This is +now deprecated since not all filesystems support symbolic links. + +This command follows *real* symlinks only if they start with "refs/": +otherwise it will just try to read them and update them as a regular +file (i.e. it will allow the filesystem to follow them, but will +overwrite such a symlink to somewhere else with a regular filename). + +SEE ALSO +-------- +linkgit:git-symbolic-ref[1] + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-update-server-info.txt b/Documentation/git-update-server-info.adoc similarity index 100% rename from Documentation/git-update-server-info.txt rename to Documentation/git-update-server-info.adoc diff --git a/Documentation/git-upload-archive.txt b/Documentation/git-upload-archive.adoc similarity index 100% rename from Documentation/git-upload-archive.txt rename to Documentation/git-upload-archive.adoc diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.adoc similarity index 100% rename from Documentation/git-upload-pack.txt rename to Documentation/git-upload-pack.adoc diff --git a/Documentation/git-var.txt b/Documentation/git-var.adoc similarity index 100% rename from Documentation/git-var.txt rename to Documentation/git-var.adoc diff --git a/Documentation/git-verify-commit.txt b/Documentation/git-verify-commit.adoc similarity index 100% rename from Documentation/git-verify-commit.txt rename to Documentation/git-verify-commit.adoc diff --git a/Documentation/git-verify-pack.txt b/Documentation/git-verify-pack.adoc similarity index 100% rename from Documentation/git-verify-pack.txt rename to Documentation/git-verify-pack.adoc diff --git a/Documentation/git-verify-tag.txt b/Documentation/git-verify-tag.adoc similarity index 100% rename from Documentation/git-verify-tag.txt rename to Documentation/git-verify-tag.adoc diff --git a/Documentation/git-version.txt b/Documentation/git-version.adoc similarity index 100% rename from Documentation/git-version.txt rename to Documentation/git-version.adoc diff --git a/Documentation/git-web--browse.txt b/Documentation/git-web--browse.adoc similarity index 100% rename from Documentation/git-web--browse.txt rename to Documentation/git-web--browse.adoc diff --git a/Documentation/git-whatchanged.txt b/Documentation/git-whatchanged.adoc similarity index 100% rename from Documentation/git-whatchanged.txt rename to Documentation/git-whatchanged.adoc diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.adoc similarity index 98% rename from Documentation/git-worktree.txt rename to Documentation/git-worktree.adoc index 2a240f53ba7f98..8340b7f028e6c1 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.adoc @@ -157,7 +157,7 @@ will reestablish the connection. If multiple linked worktrees are moved, running `repair` from any worktree with each tree's new `<path>` as an argument, will reestablish the connection to all the specified paths. + -If both the main worktree and linked worktrees have been moved manually, +If both the main worktree and linked worktrees have been moved or copied manually, then running `repair` in the main worktree and specifying the new `<path>` of each linked worktree will reestablish all connections in both directions. @@ -216,6 +216,14 @@ To remove a locked worktree, specify `--force` twice. This can also be set up as the default behaviour by using the `worktree.guessRemote` config option. +--[no-]relative-paths:: + Link worktrees using relative paths or absolute paths (default). + Overrides the `worktree.useRelativePaths` config option, see + linkgit:git-config[1]. ++ +With `repair`, the linking files will be updated if there's an absolute/relative +mismatch, even if the links are correct. + --[no-]track:: When creating a new branch, if `<commit-ish>` is a branch, mark it as "upstream" from the new branch. This is the diff --git a/Documentation/git-write-tree.txt b/Documentation/git-write-tree.adoc similarity index 100% rename from Documentation/git-write-tree.txt rename to Documentation/git-write-tree.adoc diff --git a/Documentation/git.txt b/Documentation/git.adoc similarity index 97% rename from Documentation/git.txt rename to Documentation/git.adoc index d15a8697625d6b..743b7b00e4d751 100644 --- a/Documentation/git.txt +++ b/Documentation/git.adoc @@ -245,17 +245,17 @@ ancillary user utilities. Main porcelain commands ~~~~~~~~~~~~~~~~~~~~~~~ -include::cmds-mainporcelain.txt[] +include::{build_dir}/cmds-mainporcelain.adoc[] Ancillary Commands ~~~~~~~~~~~~~~~~~~ Manipulators: -include::cmds-ancillarymanipulators.txt[] +include::{build_dir}/cmds-ancillarymanipulators.adoc[] Interrogators: -include::cmds-ancillaryinterrogators.txt[] +include::{build_dir}/cmds-ancillaryinterrogators.adoc[] Interacting with Others @@ -264,7 +264,7 @@ Interacting with Others These commands are to interact with foreign SCM and with other people via patch over e-mail. -include::cmds-foreignscminterface.txt[] +include::{build_dir}/cmds-foreignscminterface.adoc[] Reset, restore and revert ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -313,13 +313,13 @@ repositories. Manipulation commands ~~~~~~~~~~~~~~~~~~~~~ -include::cmds-plumbingmanipulators.txt[] +include::{build_dir}/cmds-plumbingmanipulators.adoc[] Interrogation commands ~~~~~~~~~~~~~~~~~~~~~~ -include::cmds-plumbinginterrogators.txt[] +include::{build_dir}/cmds-plumbinginterrogators.adoc[] In general, the interrogate commands do not touch the files in the working tree. @@ -328,12 +328,12 @@ the working tree. Syncing repositories ~~~~~~~~~~~~~~~~~~~~ -include::cmds-synchingrepositories.txt[] +include::{build_dir}/cmds-synchingrepositories.adoc[] The following are helper commands used by the above; end users typically do not use them directly. -include::cmds-synchelpers.txt[] +include::{build_dir}/cmds-synchelpers.adoc[] Internal helper commands @@ -342,14 +342,14 @@ Internal helper commands These are internal helper commands used by other commands; end users typically do not use them directly. -include::cmds-purehelpers.txt[] +include::{build_dir}/cmds-purehelpers.adoc[] Guides ------ The following documentation pages are guides about Git concepts. -include::cmds-guide.txt[] +include::{build_dir}/cmds-guide.adoc[] Repository, command and file interfaces --------------------------------------- @@ -358,7 +358,7 @@ This documentation discusses repository and command interfaces which users are expected to interact with directly. See `--user-formats` in linkgit:git-help[1] for more details on the criteria. -include::cmds-userinterfaces.txt[] +include::{build_dir}/cmds-userinterfaces.adoc[] File formats, protocols and other developer interfaces ------------------------------------------------------ @@ -367,7 +367,7 @@ This documentation discusses file formats, over-the-wire protocols and other git developer interfaces. See `--developer-interfaces` in linkgit:git-help[1]. -include::cmds-developerinterfaces.txt[] +include::{build_dir}/cmds-developerinterfaces.adoc[] Configuration Mechanism ----------------------- @@ -472,11 +472,20 @@ Environment Variables --------------------- Various Git commands pay attention to environment variables and change their behavior. The environment variables marked as "Boolean" take -their values the same way as Boolean valued configuration variables, e.g. -"true", "yes", "on" and positive numbers are taken as "yes". +their values the same way as Boolean valued configuration variables, i.e., +"true", "yes", "on" and positive numbers are taken as "yes", while "false", +"no", "off", and "0" are taken as "no". Here are the variables: +System +~~~~~~ +`HOME`:: + Specifies the path to the user's home directory. On Windows, if + unset, Git will set a process environment variable equal to: + `$HOMEDRIVE$HOMEPATH` if both `$HOMEDRIVE` and `$HOMEPATH` exist; + otherwise `$USERPROFILE` if `$USERPROFILE` exists. + The Git Repository ~~~~~~~~~~~~~~~~~~ These environment variables apply to 'all' core Git commands. Nb: it diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.adoc similarity index 99% rename from Documentation/gitattributes.txt rename to Documentation/gitattributes.adoc index e6150595af8210..a22d1ef1e15438 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.adoc @@ -513,7 +513,7 @@ If the filter command (a string value) is defined via `filter.<driver>.process` then Git can process all blobs with a single filter invocation for the entire life of a single Git command. This is achieved by using the long-running process protocol -(described in technical/long-running-process-protocol.txt). +(described in Documentation/technical/long-running-process-protocol.adoc). When Git encounters the first file that needs to be cleaned or smudged, it starts the filter and performs the handshake. In the handshake, the @@ -701,8 +701,8 @@ where the attribute is not in place would normally cause merge conflicts. To prevent these unnecessary merge conflicts, Git can be told to run a -virtual check-out and check-in of all three stages of a file when -resolving a three-way merge by setting the `merge.renormalize` +virtual check-out and check-in of all three stages of each file that +needs a three-way content merge, by setting the `merge.renormalize` configuration variable. This prevents changes caused by check-in conversion from causing spurious merge conflicts when a converted file is merged with an unconverted file. @@ -1166,7 +1166,7 @@ internal merge and the final merge. The merge driver can learn the pathname in which the merged result 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. +using `%S`, `%X` and `%Y` respectively. `conflict-marker-size` ^^^^^^^^^^^^^^^^^^^^^^ @@ -1177,11 +1177,11 @@ integer has a meaningful effect. For example, this line in `.gitattributes` can be used to tell the merge machinery to leave much longer (instead of the usual 7-character-long) -conflict markers when merging the file `Documentation/git-merge.txt` +conflict markers when merging the file `Documentation/git-merge.adoc` results in a conflict. ------------------------ -Documentation/git-merge.txt conflict-marker-size=32 +Documentation/git-merge.adoc conflict-marker-size=32 ------------------------ diff --git a/Documentation/gitcli.txt b/Documentation/gitcli.adoc similarity index 88% rename from Documentation/gitcli.txt rename to Documentation/gitcli.adoc index 7c709324ba904e..04193ec907827f 100644 --- a/Documentation/gitcli.txt +++ b/Documentation/gitcli.adoc @@ -90,6 +90,15 @@ scripting Git: for long options. An option that takes optional option-argument must be written in the 'stuck' form. + * Despite the above suggestion, when Arg is a path relative to the + home directory of a user, e.g. `~/directory/file` or `~u/d/f`, you + may want to use the separate form, e.g. `git foo --file ~/mine`, + not `git foo --file=~/mine`. The shell will expand `~/` in the + former to your home directory, but most shells keep the tilde in + the latter. Some of our commands know how to tilde-expand the + option value even when given in the stuck form, but not all of + them do. + * When you give a revision parameter to a command, make sure the parameter is not ambiguous with a name of a file in the work tree. E.g. do not write `git log -1 HEAD` but write `git log -1 HEAD --`; the former will not work @@ -152,6 +161,23 @@ can use `--no-track` to override that behaviour. The same goes for `--color` and `--no-color`. +Options trump configuration and environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When there is a configuration variable or an environment variable +that tweak the behaviour of an aspect of a Git command, and also a +command line option that tweaks the same, the command line option +overrides what the configuration and/or environment variable say. + +For example, the `user.name` configuration variable is used to +specify the human-readable name used by the `git commit` command to +record the author and the committer name in a newly created commit. +The `GIT_AUTHOR_NAME` environment variable, if set, takes precedence +when deciding what author name to record. The `--author=<author>` +command line option of the `git commit` command, when given, takes +precedence over these two sources of information. + + Aggregating short options ~~~~~~~~~~~~~~~~~~~~~~~~~ Commands that support the enhanced option parser allow you to aggregate short diff --git a/Documentation/gitcore-tutorial.txt b/Documentation/gitcore-tutorial.adoc similarity index 100% rename from Documentation/gitcore-tutorial.txt rename to Documentation/gitcore-tutorial.adoc diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.adoc similarity index 90% rename from Documentation/gitcredentials.txt rename to Documentation/gitcredentials.adoc index 71dd19731af0df..3337bb475de4c5 100644 --- a/Documentation/gitcredentials.txt +++ b/Documentation/gitcredentials.adoc @@ -66,18 +66,7 @@ storage provided by the OS or other programs. Alternatively, a credential-generating helper might generate credentials for certain servers via some API. -To use a helper, you must first select one to use. Git currently -includes the following helpers: - -cache:: - - Cache credentials in memory for a short period of time. See - linkgit:git-credential-cache[1] for details. - -store:: - - Store credentials indefinitely on disk. See - linkgit:git-credential-store[1] for details. +To use a helper, you must first select one to use (see below for a list). You may also have third-party helpers installed; search for `credential-*` in the output of `git help -a`, and consult the @@ -106,6 +95,28 @@ $ git config --global credential.helper foo === Available helpers +Git currently includes the following helpers: + +cache:: + + Cache credentials in memory for a short period of time. See + linkgit:git-credential-cache[1] for details. + +store:: + + Store credentials indefinitely on disk. See + linkgit:git-credential-store[1] for details. + +Popular helpers with secure persistent storage include: + + - git-credential-libsecret (Linux) + + - git-credential-osxkeychain (macOS) + + - git-credential-wincred (Windows) + + - https://github.com/git-ecosystem/git-credential-manager[Git Credential Manager] (cross platform, included in Git for Windows) + The community maintains a comprehensive list of Git credential helpers at https://git-scm.com/doc/credential-helpers. @@ -116,6 +127,12 @@ OAuth credential helper. Initial authentication opens a browser window to the host. Subsequent authentication happens in the background. Many popular Git hosts support OAuth. +Popular helpers with OAuth support include: + + - https://github.com/git-ecosystem/git-credential-manager[Git Credential Manager] (cross platform, included in Git for Windows) + + - https://github.com/hickford/git-credential-oauth[git-credential-oauth] (cross platform, included in many Linux distributions) + CREDENTIAL CONTEXTS ------------------- @@ -242,6 +259,12 @@ Here are some example specifications: [credential] helper = "foo --bar='whitespace arg'" +# store helper (discouraged) with custom location for the db file; +# use `--file ~/.git-secret.txt`, rather than `--file=~/.git-secret.txt`, +# to allow the shell to expand tilde to the home directory. +[credential] + helper = "store --file ~/.git-secret.txt" + # you can also use an absolute path, which will not use the git wrapper [credential] helper = "/path/to/my/helper --with-arguments" diff --git a/Documentation/gitcvs-migration.txt b/Documentation/gitcvs-migration.adoc similarity index 100% rename from Documentation/gitcvs-migration.txt rename to Documentation/gitcvs-migration.adoc diff --git a/Documentation/gitdiffcore.txt b/Documentation/gitdiffcore.adoc similarity index 100% rename from Documentation/gitdiffcore.txt rename to Documentation/gitdiffcore.adoc diff --git a/Documentation/giteveryday.txt b/Documentation/giteveryday.adoc similarity index 100% rename from Documentation/giteveryday.txt rename to Documentation/giteveryday.adoc diff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.adoc similarity index 100% rename from Documentation/gitfaq.txt rename to Documentation/gitfaq.adoc diff --git a/Documentation/gitformat-bundle.txt b/Documentation/gitformat-bundle.adoc similarity index 100% rename from Documentation/gitformat-bundle.txt rename to Documentation/gitformat-bundle.adoc diff --git a/Documentation/gitformat-chunk.txt b/Documentation/gitformat-chunk.adoc similarity index 100% rename from Documentation/gitformat-chunk.txt rename to Documentation/gitformat-chunk.adoc diff --git a/Documentation/gitformat-commit-graph.txt b/Documentation/gitformat-commit-graph.adoc similarity index 99% rename from Documentation/gitformat-commit-graph.txt rename to Documentation/gitformat-commit-graph.adoc index 3e906e803096df..14d163123402b7 100644 --- a/Documentation/gitformat-commit-graph.txt +++ b/Documentation/gitformat-commit-graph.adoc @@ -122,7 +122,7 @@ All multi-byte numbers are in network byte order. for commits with corrected commit date offsets that cannot be stored within 31 bits. * Generation Data Overflow chunk is present only when Generation Data - chunk is present and atleast one corrected commit date offset cannot + chunk is present and at least one corrected commit date offset cannot be stored within 31 bits. ==== Extra Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional] diff --git a/Documentation/gitformat-index.txt b/Documentation/gitformat-index.adoc similarity index 100% rename from Documentation/gitformat-index.txt rename to Documentation/gitformat-index.adoc diff --git a/Documentation/gitformat-pack.txt b/Documentation/gitformat-pack.adoc similarity index 100% rename from Documentation/gitformat-pack.txt rename to Documentation/gitformat-pack.adoc diff --git a/Documentation/gitformat-signature.txt b/Documentation/gitformat-signature.adoc similarity index 100% rename from Documentation/gitformat-signature.txt rename to Documentation/gitformat-signature.adoc diff --git a/Documentation/gitglossary.txt b/Documentation/gitglossary.adoc similarity index 90% rename from Documentation/gitglossary.txt rename to Documentation/gitglossary.adoc index 571f640f5c1c8f..0e85be48470ea0 100644 --- a/Documentation/gitglossary.txt +++ b/Documentation/gitglossary.adoc @@ -12,7 +12,7 @@ SYNOPSIS DESCRIPTION ----------- -include::glossary-content.txt[] +include::glossary-content.adoc[] SEE ALSO -------- diff --git a/Documentation/githooks.txt b/Documentation/githooks.adoc similarity index 100% rename from Documentation/githooks.txt rename to Documentation/githooks.adoc diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.adoc similarity index 100% rename from Documentation/gitignore.txt rename to Documentation/gitignore.adoc diff --git a/Documentation/gitk.txt b/Documentation/gitk.adoc similarity index 99% rename from Documentation/gitk.txt rename to Documentation/gitk.adoc index 35b39960296b69..58ce40ddb11ba5 100644 --- a/Documentation/gitk.txt +++ b/Documentation/gitk.adoc @@ -98,7 +98,7 @@ linkgit:git-rev-list[1] for a complete list. (See "History simplification" in linkgit:git-log[1] for a more detailed explanation.) -include::line-range-options.txt[] +include::line-range-options.adoc[] <revision range>:: diff --git a/Documentation/gitmailmap.txt b/Documentation/gitmailmap.adoc similarity index 100% rename from Documentation/gitmailmap.txt rename to Documentation/gitmailmap.adoc diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.adoc similarity index 100% rename from Documentation/gitmodules.txt rename to Documentation/gitmodules.adoc diff --git a/Documentation/gitnamespaces.txt b/Documentation/gitnamespaces.adoc similarity index 98% rename from Documentation/gitnamespaces.txt rename to Documentation/gitnamespaces.adoc index 1c8d2ecc358d80..06f4d37efa390e 100644 --- a/Documentation/gitnamespaces.txt +++ b/Documentation/gitnamespaces.adoc @@ -61,7 +61,7 @@ For a simple local test, you can use linkgit:git-remote-ext[1]: git clone ext::'git --namespace=foo %s /tmp/prefixed.git' ---------- -include::transfer-data-leaks.txt[] +include::transfer-data-leaks.adoc[] GIT --- diff --git a/Documentation/gitpacking.txt b/Documentation/gitpacking.adoc similarity index 99% rename from Documentation/gitpacking.txt rename to Documentation/gitpacking.adoc index 321154d4e65dbc..a56596e2d1d84d 100644 --- a/Documentation/gitpacking.txt +++ b/Documentation/gitpacking.adoc @@ -136,7 +136,7 @@ chunks of "stableSize" in order of age. The exact configuration for pseudo-merges is as follows: -include::config/bitmap-pseudo-merge.txt[] +include::config/bitmap-pseudo-merge.adoc[] === Examples diff --git a/Documentation/gitprotocol-capabilities.txt b/Documentation/gitprotocol-capabilities.adoc similarity index 100% rename from Documentation/gitprotocol-capabilities.txt rename to Documentation/gitprotocol-capabilities.adoc diff --git a/Documentation/gitprotocol-common.txt b/Documentation/gitprotocol-common.adoc similarity index 100% rename from Documentation/gitprotocol-common.txt rename to Documentation/gitprotocol-common.adoc diff --git a/Documentation/gitprotocol-http.txt b/Documentation/gitprotocol-http.adoc similarity index 100% rename from Documentation/gitprotocol-http.txt rename to Documentation/gitprotocol-http.adoc diff --git a/Documentation/gitprotocol-pack.txt b/Documentation/gitprotocol-pack.adoc similarity index 100% rename from Documentation/gitprotocol-pack.txt rename to Documentation/gitprotocol-pack.adoc diff --git a/Documentation/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.adoc similarity index 91% rename from Documentation/gitprotocol-v2.txt rename to Documentation/gitprotocol-v2.adoc index 414bc625d5dd21..5598c93e67c314 100644 --- a/Documentation/gitprotocol-v2.txt +++ b/Documentation/gitprotocol-v2.adoc @@ -184,9 +184,13 @@ form `agent=X`) to notify the client that the server is running version the `agent` capability with a value `Y` (in the form `agent=Y`) in its request to the server (but it MUST NOT do so if the server did not advertise the agent capability). The `X` and `Y` strings may contain any -printable ASCII characters except space (i.e., the byte range 32 < x < -127), and are typically of the form "package/version" (e.g., -"git/1.8.3.1"). The agent strings are purely informative for statistics +printable ASCII characters except space (i.e., the byte range 33 <= x <= +126), and are typically of the form "package/version-os" (e.g., +"git/1.8.3.1-Linux") where `os` is the operating system name (e.g., +"Linux"). `X` and `Y` can be configured using the GIT_USER_AGENT +environment variable and it takes priority. The `os` is +retrieved using the 'sysname' field of the `uname(2)` system call +or its equivalent. The agent strings are purely informative for statistics and debugging purposes, and MUST NOT be used to programmatically assume the presence or absence of particular features. @@ -527,8 +531,8 @@ a request. The provided options must not contain a NUL or LF character. - object-format -~~~~~~~~~~~~~~~ +object-format +~~~~~~~~~~~~~ The server can advertise the `object-format` capability with a value `X` (in the form `object-format=X`) to notify the client that the server is able to deal @@ -776,11 +780,65 @@ This would allow for optimizing the common case of servers who'd like to provide one "big bundle" containing only their "main" branch, and/or incremental updates thereof. + -A client receiving such a a response MAY assume that they can skip +A client receiving such a response MAY assume that they can skip retrieving the header from a bundle at the indicated URI, and thus save themselves and the server(s) the request(s) needed to inspect the headers of that bundle or bundles. +promisor-remote=<pr-infos> +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The server may advertise some promisor remotes it is using or knows +about to a client which may want to use them as its promisor remotes, +instead of this repository. In this case <pr-infos> should be of the +form: + + pr-infos = pr-info | pr-infos ";" pr-info + + pr-info = "name=" pr-name | "name=" pr-name "," "url=" pr-url + +where `pr-name` is the urlencoded name of a promisor remote, and +`pr-url` the urlencoded URL of that promisor remote. + +In this case, if the client decides to use one or more promisor +remotes the server advertised, it can reply with +"promisor-remote=<pr-names>" where <pr-names> should be of the form: + + pr-names = pr-name | pr-names ";" pr-name + +where `pr-name` is the urlencoded name of a promisor remote the server +advertised and the client accepts. + +Note that, everywhere in this document, `pr-name` MUST be a valid +remote name, and the ';' and ',' characters MUST be encoded if they +appear in `pr-name` or `pr-url`. + +If the server doesn't know any promisor remote that could be good for +a client to use, or prefers a client not to use any promisor remote it +uses or knows about, it shouldn't advertise the "promisor-remote" +capability at all. + +In this case, or if the client doesn't want to use any promisor remote +the server advertised, the client shouldn't advertise the +"promisor-remote" capability at all in its reply. + +The "promisor.advertise" and "promisor.acceptFromServer" configuration +options can be used on the server and client side to control what they +advertise or accept respectively. See the documentation of these +configuration options for more information. + +Note that in the future it would be nice if the "promisor-remote" +protocol capability could be used by the server, when responding to +`git fetch` or `git clone`, to advertise better-connected remotes that +the client can use as promisor remotes, instead of this repository, so +that the client can lazily fetch objects from these other +better-connected remotes. This would require the server to omit in its +response the objects available on the better-connected remotes that +the client has accepted. This hasn't been implemented yet though. So +for now this "promisor-remote" capability is useful only when the +server advertises some promisor remotes it already uses to borrow +objects from. + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.adoc similarity index 100% rename from Documentation/gitremote-helpers.txt rename to Documentation/gitremote-helpers.adoc diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.adoc similarity index 96% rename from Documentation/gitrepository-layout.txt rename to Documentation/gitrepository-layout.adoc index 949cd8a31e9a9e..7421ef956d35ac 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.adoc @@ -152,8 +152,9 @@ config.worktree:: working directory in multiple working directory setup (see linkgit:git-worktree[1]). +ifndef::with-breaking-changes[] branches:: - A slightly deprecated way to store shorthands to be used + A deprecated way to store shorthands to be used to specify a URL to 'git fetch', 'git pull' and 'git push'. A file can be stored as `branches/<name>` and then 'name' can be given to these commands in place of @@ -162,7 +163,9 @@ branches:: and not likely to be found in modern repositories. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/branches" will be used instead. - ++ +Git will stop reading remotes from this directory in Git 3.0. +endif::with-breaking-changes[] hooks:: Hooks are customization scripts used by various Git @@ -230,6 +233,7 @@ info/sparse-checkout:: This file stores sparse checkout patterns. See also: linkgit:git-read-tree[1]. +ifndef::with-breaking-changes[] remotes:: Stores shorthands for URL and default refnames for use when interacting with remote repositories via 'git fetch', @@ -238,6 +242,9 @@ remotes:: and not likely to be found in modern repositories. This directory is ignored if $GIT_COMMON_DIR is set and "$GIT_COMMON_DIR/remotes" will be used instead. ++ +Git will stop reading remotes from this directory in Git 3.0. +endif::with-breaking-changes[] logs:: Records of changes made to refs are stored in this directory. @@ -292,12 +299,13 @@ worktrees/<id>/locked:: worktrees/<id>/config.worktree:: Working directory specific configuration file. -include::technical/repository-version.txt[] +include::technical/repository-version.adoc[] SEE ALSO -------- linkgit:git-init[1], linkgit:git-clone[1], +linkgit:git-config[1], linkgit:git-fetch[1], linkgit:git-pack-refs[1], linkgit:git-gc[1], diff --git a/Documentation/gitrevisions.txt b/Documentation/gitrevisions.adoc similarity index 96% rename from Documentation/gitrevisions.txt rename to Documentation/gitrevisions.adoc index d407b7dee127b1..7146117de5f23f 100644 --- a/Documentation/gitrevisions.txt +++ b/Documentation/gitrevisions.adoc @@ -24,7 +24,7 @@ linkgit:git-push[1]) can also take revision parameters which denote other objects than commits, e.g. blobs ("files") or trees ("directories of files"). -include::revisions.txt[] +include::revisions.adoc[] SEE ALSO diff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.adoc similarity index 100% rename from Documentation/gitsubmodules.txt rename to Documentation/gitsubmodules.adoc diff --git a/Documentation/gittutorial-2.txt b/Documentation/gittutorial-2.adoc similarity index 100% rename from Documentation/gittutorial-2.txt rename to Documentation/gittutorial-2.adoc diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.adoc similarity index 100% rename from Documentation/gittutorial.txt rename to Documentation/gittutorial.adoc diff --git a/Documentation/gitweb.txt b/Documentation/gitweb.adoc similarity index 99% rename from Documentation/gitweb.txt rename to Documentation/gitweb.adoc index 56d24a30a3f7b9..5e2b491ec2256b 100644 --- a/Documentation/gitweb.txt +++ b/Documentation/gitweb.adoc @@ -234,7 +234,7 @@ from the template during repository creation, usually installed in configuration variable, but the file takes precedence. category (or `gitweb.category`):: - Singe line category of a project, used to group projects if + Single line category of a project, used to group projects if `$projects_list_group_categories` is enabled. By default (file and configuration variable absent), uncategorized projects are put in the `$project_list_default_category` category. You can use the diff --git a/Documentation/gitweb.conf.txt b/Documentation/gitweb.conf.adoc similarity index 100% rename from Documentation/gitweb.conf.txt rename to Documentation/gitweb.conf.adoc diff --git a/Documentation/gitworkflows.txt b/Documentation/gitworkflows.adoc similarity index 100% rename from Documentation/gitworkflows.txt rename to Documentation/gitworkflows.adoc diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.adoc similarity index 99% rename from Documentation/glossary-content.txt rename to Documentation/glossary-content.adoc index 42afe048691242..575c18f776efac 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.adoc @@ -696,6 +696,11 @@ the `refs/tags/` hierarchy is used to represent local tags.. that each contain very well defined concepts or small incremental yet related changes. +[[def_trailer]]trailer:: + Key-value metadata. Trailers are optionally found at the end of + a commit message. Might be called "footers" or "tags" in other + communities. See linkgit:git-interpret-trailers[1]. + [[def_tree]]tree:: Either a <<def_working_tree,working tree>>, or a <<def_tree_object,tree object>> together with the dependent <<def_blob_object,blob>> and tree objects diff --git a/Documentation/howto/coordinate-embargoed-releases.txt b/Documentation/howto/coordinate-embargoed-releases.adoc similarity index 100% rename from Documentation/howto/coordinate-embargoed-releases.txt rename to Documentation/howto/coordinate-embargoed-releases.adoc diff --git a/Documentation/howto-index.sh b/Documentation/howto/howto-index.sh similarity index 64% rename from Documentation/howto-index.sh rename to Documentation/howto/howto-index.sh index 167b363668b8b5..ace49830a8234f 100755 --- a/Documentation/howto-index.sh +++ b/Documentation/howto/howto-index.sh @@ -9,9 +9,9 @@ people describing how they use Git in their workflow. EOF -for txt +for adoc do - title=$(expr "$txt" : '.*/\(.*\)\.txt$') + title=$(expr "$adoc" : '.*/\(.*\)\.adoc$') from=$(sed -ne ' /^$/q /^From:[ ]/{ @@ -21,7 +21,7 @@ do s/^/by / p } - ' "$txt") + ' "$adoc") abstract=$(sed -ne ' /^Abstract:[ ]/{ @@ -39,16 +39,16 @@ do x p q - }' "$txt") + }' "$adoc") - if grep 'Content-type: text/asciidoc' >/dev/null $txt + if grep 'Content-type: text/asciidoc' >/dev/null $adoc then - file=$(expr "$txt" : '\(.*\)\.txt$').html + file=$(expr "$adoc" : '\(.*\)\.adoc$').html else - file="$txt" + file="$adoc" fi - echo "* link:$file[$title] $from + echo "* link:howto/$(basename "$file")[$title] $from $abstract " diff --git a/Documentation/howto/keep-canonical-history-correct.txt b/Documentation/howto/keep-canonical-history-correct.adoc similarity index 99% rename from Documentation/howto/keep-canonical-history-correct.txt rename to Documentation/howto/keep-canonical-history-correct.adoc index 5f800fd85a3dbd..e98f03275e2437 100644 --- a/Documentation/howto/keep-canonical-history-correct.txt +++ b/Documentation/howto/keep-canonical-history-correct.adoc @@ -13,7 +13,7 @@ that appears to be "backwards" from what other project developers expect. This howto presents a suggested integration workflow for maintaining a central repository. -Suppose that that central repository has this history: +Suppose that the central repository has this history: ------------ ---o---o---A diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.adoc similarity index 88% rename from Documentation/howto/maintain-git.txt rename to Documentation/howto/maintain-git.adoc index da31332f11398d..45e2599c5dd157 100644 --- a/Documentation/howto/maintain-git.txt +++ b/Documentation/howto/maintain-git.adoc @@ -67,7 +67,22 @@ the mailing list after each feature release is made: before getting merged to 'master'. - 'seen' branch is used to publish other proposed changes that do - not yet pass the criteria set for 'next' (see above). + not yet pass the criteria set for 'next' (see above), but there + is no promise that 'seen' will contain everything. A topic that + had no reviewer reaction may not be picked up. + + - A new topic will first get merged to 'seen', unless it is + trivially correct and clearly urgent, in which case it may be + directly merged to 'next' or even to 'master'. + + - If a topic that was picked up to 'seen' becomes and stays + inactive for 3 calendar weeks without having seen a clear + consensus that it is good enough to be moved to 'next', the + topic may be discarded from 'seen'. Interested parties are + still free to revive the topic. For the purpose of this + guideline, the definition of being "inactive" is that nobody + has discussed the topic, no new iteration of the topic was + posted, and no responses to the review comments were given. - The tips of 'master' and 'maint' branches will not be rewound to allow people to build their own customization on top of them. @@ -122,6 +137,13 @@ Note that before v1.9.0 release, the version numbers used to be structured slightly differently. vX.Y.Z were feature releases while vX.Y.Z.W were maintenance releases for vX.Y.Z. +Because most of the lines of code in Git are written by individual +contributors, and contributions come in the form of e-mailed patches +published on the mailing list, the project maintains a mapping from +individual commits to the Message-Id of the e-mail that resulted in +the commit, to help tracking the origin of the changes. The notes +in "refs/notes/amlog" are used for this purpose, and are published +along with the broken-out branches to the maintainer's repository. A Typical Git Day ----------------- @@ -165,6 +187,43 @@ by doing the following: In practice, almost no patch directly goes to 'master' or 'maint'. + Applying the e-mailed patches using "git am" automatically records + the mappings from 'Message-Id' to the applied commit in the "amlog" + notes. Periodically check that this is working with "git show -s + --notes=amlog $commit". + + This mapping is maintained with the aid of the "post-applypatch" + hook found in the 'todo' branch. That hook should be installed + before applying patches. It is also helpful to carry forward any + relevant amlog entries when rebasing, so the following config may + be useful: + + [notes] + rewriteRef = refs/notes/amlog + + Avoid "cherry-pick", as it does not propagate notes by design. Use + either "git commit --amend" or "git rebase" to make corrections to + an existing commit, even for a single-patch topic. + + Make sure that a push refspec for 'refs/notes/amlog' is in the + remote configuration for publishing repositories. A few sample + configurations look like the following: + + [remote "github"] + url = https://github.com/gitster/git + pushurl = github.com:gitster/git.git + mirror + + [remote "github2"] + url = https://github.com/git/git + fetch = +refs/heads/*:refs/remotes/github2/* + pushurl = github.com:git/git.git + push = refs/heads/maint:refs/heads/maint + push = refs/heads/master:refs/heads/master + push = refs/heads/next:refs/heads/next + push = +refs/heads/seen:refs/heads/seen + push = +refs/notes/amlog + - Review the last issue of "What's cooking" message, review the topics ready for merging (topic->master and topic->maint). Use "Meta/cook -w" script (where Meta/ contains a checkout of the diff --git a/Documentation/howto/meson.build b/Documentation/howto/meson.build new file mode 100644 index 00000000000000..81000028c08ee6 --- /dev/null +++ b/Documentation/howto/meson.build @@ -0,0 +1,62 @@ +howto_sources = [ + 'coordinate-embargoed-releases.adoc', + 'keep-canonical-history-correct.adoc', + 'maintain-git.adoc', + 'new-command.adoc', + 'rebase-from-internal-branch.adoc', + 'rebuild-from-update-hook.adoc', + 'recover-corrupted-blob-object.adoc', + 'recover-corrupted-object-harder.adoc', + 'revert-a-faulty-merge.adoc', + 'revert-branch-rebase.adoc', + 'separating-topic-branches.adoc', + 'setup-git-server-over-http.adoc', + 'update-hook-example.adoc', + 'use-git-daemon.adoc', + 'using-merge-subtree.adoc', + 'using-signed-tag-in-pull-request.adoc', +] + +howto_index = custom_target( + command: [ + shell, + meson.current_source_dir() / 'howto-index.sh', + '@INPUT@', + ], + env: script_environment, + capture: true, + input: howto_sources, + output: 'howto-index.adoc', +) + +custom_target( + command: asciidoc_html_options, + input: howto_index, + output: 'howto-index.html', + depends: documentation_deps, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', +) + +foreach howto : howto_sources + howto_stripped = custom_target( + command: [ + sed, + '-e', + '1,/^$/d', + '@INPUT@', + ], + input: howto, + output: fs.stem(howto) + '.stripped', + capture: true, + ) + + custom_target( + command: asciidoc_html_options, + input: howto_stripped, + output: fs.stem(howto_stripped.full_path()) + '.html', + depends: documentation_deps, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc/howto', + ) +endforeach diff --git a/Documentation/howto/new-command.txt b/Documentation/howto/new-command.adoc similarity index 98% rename from Documentation/howto/new-command.txt rename to Documentation/howto/new-command.adoc index 880c51112ba478..ac73c98be72ded 100644 --- a/Documentation/howto/new-command.txt +++ b/Documentation/howto/new-command.adoc @@ -48,7 +48,7 @@ binary); this organization makes it easy for people reading the code to find things. See the CodingGuidelines document for other guidance on what we consider -good practice in C and shell, and api-builtin.txt for the support +good practice in C and shell, and builtin.h for the support functions available to built-in commands written in C. What every extension command needs diff --git a/Documentation/howto/rebase-from-internal-branch.txt b/Documentation/howto/rebase-from-internal-branch.adoc similarity index 100% rename from Documentation/howto/rebase-from-internal-branch.txt rename to Documentation/howto/rebase-from-internal-branch.adoc diff --git a/Documentation/howto/rebuild-from-update-hook.txt b/Documentation/howto/rebuild-from-update-hook.adoc similarity index 100% rename from Documentation/howto/rebuild-from-update-hook.txt rename to Documentation/howto/rebuild-from-update-hook.adoc diff --git a/Documentation/howto/recover-corrupted-blob-object.txt b/Documentation/howto/recover-corrupted-blob-object.adoc similarity index 100% rename from Documentation/howto/recover-corrupted-blob-object.txt rename to Documentation/howto/recover-corrupted-blob-object.adoc diff --git a/Documentation/howto/recover-corrupted-object-harder.txt b/Documentation/howto/recover-corrupted-object-harder.adoc similarity index 100% rename from Documentation/howto/recover-corrupted-object-harder.txt rename to Documentation/howto/recover-corrupted-object-harder.adoc diff --git a/Documentation/howto/revert-a-faulty-merge.txt b/Documentation/howto/revert-a-faulty-merge.adoc similarity index 100% rename from Documentation/howto/revert-a-faulty-merge.txt rename to Documentation/howto/revert-a-faulty-merge.adoc diff --git a/Documentation/howto/revert-branch-rebase.txt b/Documentation/howto/revert-branch-rebase.adoc similarity index 100% rename from Documentation/howto/revert-branch-rebase.txt rename to Documentation/howto/revert-branch-rebase.adoc diff --git a/Documentation/howto/separating-topic-branches.txt b/Documentation/howto/separating-topic-branches.adoc similarity index 100% rename from Documentation/howto/separating-topic-branches.txt rename to Documentation/howto/separating-topic-branches.adoc diff --git a/Documentation/howto/setup-git-server-over-http.txt b/Documentation/howto/setup-git-server-over-http.adoc similarity index 100% rename from Documentation/howto/setup-git-server-over-http.txt rename to Documentation/howto/setup-git-server-over-http.adoc diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.adoc similarity index 100% rename from Documentation/howto/update-hook-example.txt rename to Documentation/howto/update-hook-example.adoc diff --git a/Documentation/howto/use-git-daemon.txt b/Documentation/howto/use-git-daemon.adoc similarity index 100% rename from Documentation/howto/use-git-daemon.txt rename to Documentation/howto/use-git-daemon.adoc diff --git a/Documentation/howto/using-merge-subtree.txt b/Documentation/howto/using-merge-subtree.adoc similarity index 100% rename from Documentation/howto/using-merge-subtree.txt rename to Documentation/howto/using-merge-subtree.adoc diff --git a/Documentation/howto/using-signed-tag-in-pull-request.txt b/Documentation/howto/using-signed-tag-in-pull-request.adoc similarity index 100% rename from Documentation/howto/using-signed-tag-in-pull-request.txt rename to Documentation/howto/using-signed-tag-in-pull-request.adoc diff --git a/Documentation/i18n.txt b/Documentation/i18n.adoc similarity index 96% rename from Documentation/i18n.txt rename to Documentation/i18n.adoc index 3a866af4a4205d..baff780a7e369e 100644 --- a/Documentation/i18n.txt +++ b/Documentation/i18n.adoc @@ -34,7 +34,7 @@ project find it more convenient to use legacy encodings, Git does not forbid it. However, there are a few things to keep in mind. -. 'git commit' and 'git commit-tree' issue +. `git commit` and `git commit-tree` issue a warning if the commit log message given to it does not look like a valid UTF-8 string, unless you explicitly say your project uses a legacy encoding. The way to say this is to @@ -50,7 +50,7 @@ of `i18n.commitEncoding` in their `encoding` header. This is to help other people who look at them later. Lack of this header implies that the commit log message is encoded in UTF-8. -. 'git log', 'git show', 'git blame' and friends look at the +. `git log`, `git show`, `git blame` and friends look at the `encoding` header of a commit object, and try to re-code the log message into UTF-8 unless otherwise specified. You can specify the desired output encoding with diff --git a/Documentation/includes/cmd-config-section-all.txt b/Documentation/includes/cmd-config-section-all.adoc similarity index 100% rename from Documentation/includes/cmd-config-section-all.txt rename to Documentation/includes/cmd-config-section-all.adoc diff --git a/Documentation/includes/cmd-config-section-rest.txt b/Documentation/includes/cmd-config-section-rest.adoc similarity index 100% rename from Documentation/includes/cmd-config-section-rest.txt rename to Documentation/includes/cmd-config-section-rest.adoc diff --git a/Documentation/install-webdoc.sh b/Documentation/install-webdoc.sh index ed8b4ff3e5874e..b237b311c34414 100755 --- a/Documentation/install-webdoc.sh +++ b/Documentation/install-webdoc.sh @@ -3,10 +3,10 @@ T="$1" for h in \ - *.txt *.html \ - howto/*.txt howto/*.html \ - technical/*.txt technical/*.html \ - RelNotes/*.txt *.css + *.adoc *.html \ + howto/*.adoc howto/*.html \ + technical/*.adoc technical/*.html \ + RelNotes/*.adoc *.css do if test ! -f "$h" then @@ -24,13 +24,13 @@ do done strip_leading=$(echo "$T/" | sed -e 's|.|.|g') for th in \ - "$T"/*.html "$T"/*.txt \ - "$T"/howto/*.txt "$T"/howto/*.html \ - "$T"/technical/*.txt "$T"/technical/*.html + "$T"/*.html "$T"/*.adoc \ + "$T"/howto/*.adoc "$T"/howto/*.html \ + "$T"/technical/*.adoc "$T"/technical/*.html do h=$(expr "$th" : "$strip_leading"'\(.*\)') case "$h" in - RelNotes-*.txt | index.html) continue ;; + RelNotes-*.adoc | index.html) continue ;; esac test -f "$h" && continue echo >&2 "# rm -f $th" diff --git a/Documentation/line-range-format.txt b/Documentation/line-range-format.adoc similarity index 100% rename from Documentation/line-range-format.txt rename to Documentation/line-range-format.adoc diff --git a/Documentation/line-range-options.txt b/Documentation/line-range-options.adoc similarity index 95% rename from Documentation/line-range-options.txt rename to Documentation/line-range-options.adoc index 8e295a62b8019b..f275df3b69fa9d 100644 --- a/Documentation/line-range-options.txt +++ b/Documentation/line-range-options.adoc @@ -12,4 +12,4 @@ (namely `--raw`, `--numstat`, `--shortstat`, `--dirstat`, `--summary`, `--name-only`, `--name-status`, `--check`) are not currently implemented. + -include::line-range-format.txt[] +include::line-range-format.adoc[] diff --git a/Documentation/lint-gitlink.perl b/Documentation/lint-gitlink.perl index 1c61dd9512b9e3..aea564dad7edbd 100755 --- a/Documentation/lint-gitlink.perl +++ b/Documentation/lint-gitlink.perl @@ -5,7 +5,7 @@ # Parse arguments, a simple state machine for input like: # -# <file-to-check.txt> <valid-files-to-link-to> --section=1 git.txt git-add.txt [...] --to-lint git-add.txt a-file.txt [...] +# <file-to-check.adoc> <valid-files-to-link-to> --section=1 git.adoc git-add.adoc [...] --to-lint git-add.adoc a-file.adoc [...] my %TXT; my %SECTION; my $section; @@ -17,7 +17,7 @@ next; } - my ($name) = $arg =~ /^(.*?)\.txt$/s; + my ($name) = $arg =~ /^(.*?)\.adoc$/s; unless (defined $section) { $TXT{$name} = $arg; next; diff --git a/Documentation/lint-manpages.sh b/Documentation/lint-manpages.sh index 92cfc0a15abd56..a0ea572382d8d9 100755 --- a/Documentation/lint-manpages.sh +++ b/Documentation/lint-manpages.sh @@ -31,7 +31,7 @@ check_missing_docs () ( git-?*--?* ) continue ;; esac - if ! test -f "$v.txt" + if ! test -f "$v.adoc" then echo "no doc: $v" ret=1 @@ -63,9 +63,9 @@ check_extraneous_docs () { -e 's/[ ].*//' \ -e 's/^/listed /' ../command-list.txt make print-man1 | - grep '\.txt$' | + grep '\.adoc$' | sed -e 's|^|documented |' \ - -e 's/\.txt//' + -e 's/\.adoc//' ) | ( all_commands="$(printf "%s " "$ALL_COMMANDS" "$BUILT_INS" "$EXCLUDED_PROGRAMS" | tr '\n' ' ')" ret=0 diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.adoc similarity index 99% rename from Documentation/merge-options.txt rename to Documentation/merge-options.adoc index 3eaefc4e940518..0022185201fc26 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.adoc @@ -102,7 +102,7 @@ endif::git-pull[] With --no-log do not list one-line descriptions from the actual commits being merged. -include::signoff-option.txt[] +include::signoff-option.adoc[] --stat:: -n:: diff --git a/Documentation/merge-strategies.txt b/Documentation/merge-strategies.adoc similarity index 92% rename from Documentation/merge-strategies.txt rename to Documentation/merge-strategies.adoc index 5fc54ec060b963..93822ebc4e83b0 100644 --- a/Documentation/merge-strategies.txt +++ b/Documentation/merge-strategies.adoc @@ -22,6 +22,13 @@ ort:: was written as a replacement for the previous default algorithm, `recursive`. + +In the case where the path is a submodule, if the submodule commit used on +one side of the merge is a descendant of the submodule commit used on the +other side of the merge, Git attempts to fast-forward to the +descendant. Otherwise, Git will treat this case as a conflict, suggesting +as a resolution a submodule commit that is descendant of the conflicting +ones, if one exists. ++ The 'ort' strategy can take the following options: ours;; @@ -56,7 +63,7 @@ ignore-cr-at-eol;; renormalize;; This runs a virtual check-out and check-in of all three stages - of a file when resolving a three-way merge. This option is + of any file which needs a three-way merge. This option is meant to be used when merging branches with different clean filters or end-of-line normalization rules. See "Merging branches with differing checkin/checkout attributes" in @@ -96,6 +103,9 @@ recursive:: the default strategy for resolving two heads from Git v0.99.9k until v2.33.0. + +For a path that is a submodule, the same caution as 'ort' applies to this +strategy. ++ The 'recursive' strategy takes the same options as 'ort'. However, there are three additional options that 'ort' ignores (not documented above) that are potentially useful with the 'recursive' strategy: diff --git a/Documentation/mergetools/vimdiff.txt b/Documentation/mergetools/vimdiff.adoc similarity index 100% rename from Documentation/mergetools/vimdiff.txt rename to Documentation/mergetools/vimdiff.adoc diff --git a/Documentation/meson.build b/Documentation/meson.build new file mode 100644 index 00000000000000..138b03dae02a5c --- /dev/null +++ b/Documentation/meson.build @@ -0,0 +1,509 @@ +manpages = { + # Category 1. + 'git-add.adoc' : 1, + 'git-am.adoc' : 1, + 'git-annotate.adoc' : 1, + 'git-apply.adoc' : 1, + 'git-archimport.adoc' : 1, + 'git-archive.adoc' : 1, + 'git-backfill.adoc' : 1, + 'git-bisect.adoc' : 1, + 'git-blame.adoc' : 1, + 'git-branch.adoc' : 1, + 'git-bugreport.adoc' : 1, + 'git-bundle.adoc' : 1, + 'git-cat-file.adoc' : 1, + 'git-check-attr.adoc' : 1, + 'git-check-ignore.adoc' : 1, + 'git-check-mailmap.adoc' : 1, + 'git-checkout-index.adoc' : 1, + 'git-checkout.adoc' : 1, + 'git-check-ref-format.adoc' : 1, + 'git-cherry-pick.adoc' : 1, + 'git-cherry.adoc' : 1, + 'git-citool.adoc' : 1, + 'git-clean.adoc' : 1, + 'git-clone.adoc' : 1, + 'git-column.adoc' : 1, + 'git-commit-graph.adoc' : 1, + 'git-commit-tree.adoc' : 1, + 'git-commit.adoc' : 1, + 'git-config.adoc' : 1, + 'git-count-objects.adoc' : 1, + 'git-credential-cache--daemon.adoc' : 1, + 'git-credential-cache.adoc' : 1, + 'git-credential-store.adoc' : 1, + 'git-credential.adoc' : 1, + 'git-cvsexportcommit.adoc' : 1, + 'git-cvsimport.adoc' : 1, + 'git-cvsserver.adoc' : 1, + 'git-daemon.adoc' : 1, + 'git-describe.adoc' : 1, + 'git-diagnose.adoc' : 1, + 'git-diff-files.adoc' : 1, + 'git-diff-index.adoc' : 1, + 'git-difftool.adoc' : 1, + 'git-diff-tree.adoc' : 1, + 'git-diff.adoc' : 1, + 'git-fast-export.adoc' : 1, + 'git-fast-import.adoc' : 1, + 'git-fetch-pack.adoc' : 1, + 'git-fetch.adoc' : 1, + 'git-filter-branch.adoc' : 1, + 'git-fmt-merge-msg.adoc' : 1, + 'git-for-each-ref.adoc' : 1, + 'git-for-each-repo.adoc' : 1, + 'git-format-patch.adoc' : 1, + 'git-fsck-objects.adoc' : 1, + 'git-fsck.adoc' : 1, + 'git-fsmonitor--daemon.adoc' : 1, + 'git-gc.adoc' : 1, + 'git-get-tar-commit-id.adoc' : 1, + 'git-grep.adoc' : 1, + 'git-gui.adoc' : 1, + 'git-hash-object.adoc' : 1, + 'git-help.adoc' : 1, + 'git-hook.adoc' : 1, + 'git-http-backend.adoc' : 1, + 'git-http-fetch.adoc' : 1, + 'git-http-push.adoc' : 1, + 'git-imap-send.adoc' : 1, + 'git-index-pack.adoc' : 1, + 'git-init-db.adoc' : 1, + 'git-init.adoc' : 1, + 'git-instaweb.adoc' : 1, + 'git-interpret-trailers.adoc' : 1, + 'git-log.adoc' : 1, + 'git-ls-files.adoc' : 1, + 'git-ls-remote.adoc' : 1, + 'git-ls-tree.adoc' : 1, + 'git-mailinfo.adoc' : 1, + 'git-mailsplit.adoc' : 1, + 'git-maintenance.adoc' : 1, + 'git-merge-base.adoc' : 1, + 'git-merge-file.adoc' : 1, + 'git-merge-index.adoc' : 1, + 'git-merge-one-file.adoc' : 1, + 'git-mergetool--lib.adoc' : 1, + 'git-mergetool.adoc' : 1, + 'git-merge-tree.adoc' : 1, + 'git-merge.adoc' : 1, + 'git-mktag.adoc' : 1, + 'git-mktree.adoc' : 1, + 'git-multi-pack-index.adoc' : 1, + 'git-mv.adoc' : 1, + 'git-name-rev.adoc' : 1, + 'git-notes.adoc' : 1, + 'git-p4.adoc' : 1, + 'git-pack-objects.adoc' : 1, + 'git-pack-redundant.adoc' : 1, + 'git-pack-refs.adoc' : 1, + 'git-patch-id.adoc' : 1, + 'git-prune-packed.adoc' : 1, + 'git-prune.adoc' : 1, + 'git-pull.adoc' : 1, + 'git-push.adoc' : 1, + 'git-quiltimport.adoc' : 1, + 'git-range-diff.adoc' : 1, + 'git-read-tree.adoc' : 1, + 'git-rebase.adoc' : 1, + 'git-receive-pack.adoc' : 1, + 'git-reflog.adoc' : 1, + 'git-refs.adoc' : 1, + 'git-remote-ext.adoc' : 1, + 'git-remote-fd.adoc' : 1, + 'git-remote.adoc' : 1, + 'git-repack.adoc' : 1, + 'git-replace.adoc' : 1, + 'git-replay.adoc' : 1, + 'git-request-pull.adoc' : 1, + 'git-rerere.adoc' : 1, + 'git-reset.adoc' : 1, + 'git-restore.adoc' : 1, + 'git-revert.adoc' : 1, + 'git-rev-list.adoc' : 1, + 'git-rev-parse.adoc' : 1, + 'git-rm.adoc' : 1, + 'git-send-email.adoc' : 1, + 'git-send-pack.adoc' : 1, + 'git-shell.adoc' : 1, + 'git-sh-i18n--envsubst.adoc' : 1, + 'git-sh-i18n.adoc' : 1, + 'git-shortlog.adoc' : 1, + 'git-show-branch.adoc' : 1, + 'git-show-index.adoc' : 1, + 'git-show-ref.adoc' : 1, + 'git-show.adoc' : 1, + 'git-sh-setup.adoc' : 1, + 'git-sparse-checkout.adoc' : 1, + 'git-stage.adoc' : 1, + 'git-stash.adoc' : 1, + 'git-status.adoc' : 1, + 'git-stripspace.adoc' : 1, + 'git-submodule.adoc' : 1, + 'git-survey.adoc' : 1, + 'git-svn.adoc' : 1, + 'git-switch.adoc' : 1, + 'git-symbolic-ref.adoc' : 1, + 'git-tag.adoc' : 1, + 'git-unpack-file.adoc' : 1, + 'git-unpack-objects.adoc' : 1, + 'git-update-index.adoc' : 1, + 'git-update-ref.adoc' : 1, + 'git-update-server-info.adoc' : 1, + 'git-upload-archive.adoc' : 1, + 'git-upload-pack.adoc' : 1, + 'git-var.adoc' : 1, + 'git-verify-commit.adoc' : 1, + 'git-verify-pack.adoc' : 1, + 'git-verify-tag.adoc' : 1, + 'git-version.adoc' : 1, + 'git-web--browse.adoc' : 1, + 'git-whatchanged.adoc' : 1, + 'git-worktree.adoc' : 1, + 'git-write-tree.adoc' : 1, + 'git.adoc' : 1, + 'gitk.adoc' : 1, + 'gitweb.adoc' : 1, + 'scalar.adoc' : 1, + + # Category 5. + 'gitattributes.adoc' : 5, + 'gitformat-bundle.adoc' : 5, + 'gitformat-chunk.adoc' : 5, + 'gitformat-commit-graph.adoc' : 5, + 'gitformat-index.adoc' : 5, + 'gitformat-pack.adoc' : 5, + 'gitformat-signature.adoc' : 5, + 'githooks.adoc' : 5, + 'gitignore.adoc' : 5, + 'gitmailmap.adoc' : 5, + 'gitmodules.adoc' : 5, + 'gitprotocol-capabilities.adoc' : 5, + 'gitprotocol-common.adoc' : 5, + 'gitprotocol-http.adoc' : 5, + 'gitprotocol-pack.adoc' : 5, + 'gitprotocol-v2.adoc' : 5, + 'gitrepository-layout.adoc' : 5, + 'gitweb.conf.adoc' : 5, + + # Category 7. + 'gitcli.adoc' : 7, + 'gitcore-tutorial.adoc' : 7, + 'gitcredentials.adoc' : 7, + 'gitcvs-migration.adoc' : 7, + 'gitdiffcore.adoc' : 7, + 'giteveryday.adoc' : 7, + 'gitfaq.adoc' : 7, + 'gitglossary.adoc' : 7, + 'gitpacking.adoc' : 7, + 'gitnamespaces.adoc' : 7, + 'gitremote-helpers.adoc' : 7, + 'gitrevisions.adoc' : 7, + 'gitsubmodules.adoc' : 7, + 'gittutorial-2.adoc' : 7, + 'gittutorial.adoc' : 7, + 'gitworkflows.adoc' : 7, +} + +docs_backend = get_option('docs_backend') +if docs_backend == 'auto' + if find_program('asciidoc', dirs: program_path, required: false).found() + docs_backend = 'asciidoc' + elif find_program('asciidoctor', dirs: program_path, required: false).found() + docs_backend = 'asciidoctor' + else + error('Neither asciidoc nor asciidoctor were found.') + endif +endif + +if docs_backend == 'asciidoc' + asciidoc = find_program('asciidoc', dirs: program_path) + asciidoc_html = 'xhtml11' + asciidoc_docbook = 'docbook' + xmlto_extra = [ ] + + asciidoc_conf = custom_target( + command: [ + shell, + meson.project_source_root() / 'GIT-VERSION-GEN', + meson.project_source_root(), + '@INPUT@', + '@OUTPUT@', + ], + input: 'asciidoc.conf.in', + output: 'asciidoc.conf', + depends: [git_version_file], + env: version_gen_environment, + ) + + asciidoc_common_options = [ + asciidoc, + '--conf-file=' + asciidoc_conf.full_path(), + '--attribute=build_dir=' + meson.current_build_dir(), + ] + + documentation_deps = [ + asciidoc_conf, + ] +elif docs_backend == 'asciidoctor' + asciidoctor = find_program('asciidoctor', dirs: program_path) + asciidoc_html = 'xhtml5' + asciidoc_docbook = 'docbook5' + xmlto_extra = [ + '--skip-validation', + '-x', meson.current_source_dir() / 'manpage.xsl', + ] + + asciidoctor_extensions = custom_target( + command: [ + shell, + meson.project_source_root() / 'GIT-VERSION-GEN', + meson.project_source_root(), + '@INPUT@', + '@OUTPUT@', + ], + input: 'asciidoctor-extensions.rb.in', + output: 'asciidoctor-extensions.rb', + depends: [git_version_file], + env: version_gen_environment, + ) + + asciidoc_common_options = [ + asciidoctor, + '--attribute', 'compat-mode', + '--attribute', 'tabsize=8', + '--attribute', 'litdd=--', + '--attribute', 'docinfo=shared', + '--attribute', 'build_dir=' + meson.current_build_dir(), + '--load-path', meson.current_build_dir(), + '--require', 'asciidoctor-extensions', + ] + + documentation_deps = [ + asciidoctor_extensions, + ] +endif + +if get_option('breaking_changes') + asciidoc_common_options += ['--attribute', 'with-breaking-changes'] +endif + +xmlto = find_program('xmlto', dirs: program_path) + +cmd_lists = [ + 'cmds-ancillaryinterrogators.adoc', + 'cmds-ancillarymanipulators.adoc', + 'cmds-mainporcelain.adoc', + 'cmds-plumbinginterrogators.adoc', + 'cmds-plumbingmanipulators.adoc', + 'cmds-synchingrepositories.adoc', + 'cmds-synchelpers.adoc', + 'cmds-guide.adoc', + 'cmds-developerinterfaces.adoc', + 'cmds-userinterfaces.adoc', + 'cmds-purehelpers.adoc', + 'cmds-foreignscminterface.adoc', +] + +documentation_deps += custom_target( + command: [ + perl, + '@INPUT@', + meson.project_source_root(), + meson.current_build_dir(), + ] + cmd_lists, + input: 'cmd-list.perl', + output: cmd_lists +) + +foreach mode : [ 'diff', 'merge' ] + documentation_deps += custom_target( + command: [ + shell, + '@INPUT@', + '..', + mode, + '@OUTPUT@' + ], + env: [ + 'MERGE_TOOLS_DIR=' + meson.project_source_root() / 'mergetools', + ], + input: 'generate-mergetool-list.sh', + output: 'mergetools-' + mode + '.adoc', + ) +endforeach + +foreach manpage, category : manpages + if get_option('docs').contains('man') + manpage_xml_target = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: manpage, + output: fs.stem(manpage) + '.xml', + ) + + manpage_path = fs.stem(manpage) + '.' + category.to_string() + manpage_target = custom_target( + command: [ + xmlto, + '-m', '@INPUT0@', + '-m', '@INPUT1@', + '--stringparam', + 'man.base.url.for.relative.links=' + get_option('prefix') / get_option('mandir'), + 'man', + manpage_xml_target, + '-o', + meson.current_build_dir(), + ] + xmlto_extra, + input: [ + 'manpage-normal.xsl', + 'manpage-bold-literal.xsl', + ], + output: manpage_path, + install: true, + install_dir: get_option('mandir') / 'man' + category.to_string(), + ) + endif + + if get_option('docs').contains('html') + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: manpage, + output: fs.stem(manpage) + '.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) + endif +endforeach + +if get_option('docs').contains('html') + configure_file( + input: 'docinfo-html.in', + output: 'docinfo.html', + copy: true, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) + + configure_file( + input: 'docbook-xsl.css', + output: 'docbook-xsl.css', + copy: true, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) + + install_symlink('index.html', + install_dir: get_option('datadir') / 'doc/git-doc', + pointing_to: 'git.html', + ) + + xsltproc = find_program('xsltproc', dirs: program_path) + + user_manual_xml = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=book', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + input: 'user-manual.adoc', + output: 'user-manual.xml', + depends: documentation_deps, + ) + + custom_target( + command: [ + xsltproc, + '--xinclude', + '--stringparam', 'html.stylesheet', 'docbook-xsl.css', + '--param', 'generate.consistent.ids', '1', + '--output', '@OUTPUT@', + '@INPUT@', + user_manual_xml, + ], + input: 'docbook.xsl', + output: 'user-manual.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) + + articles = [ + 'DecisionMaking.adoc', + 'MyFirstContribution.adoc', + 'MyFirstObjectWalk.adoc', + 'ReviewingGuidelines.adoc', + 'SubmittingPatches', + 'ToolsForGit.adoc', + 'git-bisect-lk2009.adoc', + 'git-tools.adoc', + ] + + foreach article : articles + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--out-file=@OUTPUT@', + '@INPUT@', + ], + input: article, + output: fs.stem(article) + '.html', + depends: documentation_deps, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) + endforeach + + asciidoc_html_options = asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--out-file=@OUTPUT@', + '--attribute', 'git-relative-html-prefix=../', + '@INPUT@', + ] + + subdir('howto') + subdir('technical') +endif + +# Sanity check that we are not missing any tests present in 't/'. This check +# only runs once at configure time and is thus best-effort, only. Furthermore, +# it only verifies man pages for the sake of simplicity. +configured_manpages = manpages.keys() + [ 'git-bisect-lk2009.adoc', 'git-tools.adoc' ] +actual_manpages = run_command(shell, '-c', 'ls git*.adoc scalar.adoc', + check: true, + env: script_environment, +).stdout().strip().split('\n') + +if configured_manpages != actual_manpages + missing_manpage = [ ] + foreach actual_manpage : actual_manpages + if actual_manpage not in configured_manpages + missing_manpage += actual_manpage + endif + endforeach + if missing_manpage.length() > 0 + error('Man page found, but not configured:\n\n - ' + '\n - '.join(missing_manpage)) + endif + + superfluous_manpage = [ ] + foreach configured_manpage : configured_manpages + if configured_manpage not in actual_manpages + superfluous_manpage += configured_manpage + endif + endforeach + if superfluous_manpage.length() > 0 + error('Man page configured, but not found:\n\n - ' + '\n - '.join(superfluous_manpage)) + endif +endif diff --git a/Documentation/object-format-disclaimer.txt b/Documentation/object-format-disclaimer.adoc similarity index 100% rename from Documentation/object-format-disclaimer.txt rename to Documentation/object-format-disclaimer.adoc diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.adoc similarity index 98% rename from Documentation/pretty-formats.txt rename to Documentation/pretty-formats.adoc index 8ee940b6a452da..07475de8c33702 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.adoc @@ -339,10 +339,10 @@ insert an empty string unless we are traversing reflog entries (e.g., by decoration format if `--decorate` was not already provided on the command line. -The boolean options accept an optional value `[=<bool-value>]`. The values -`true`, `false`, `on`, `off` etc. are all accepted. See the "boolean" -sub-section in "EXAMPLES" in linkgit:git-config[1]. If a boolean -option is given with no value, it's enabled. +The boolean options accept an optional value `[=<bool-value>]`. The +values taken by `--type=bool` git-config[1], like `yes` and `off`, +are all accepted. Giving a boolean option without `=<value>` is +equivalent to giving it with `=true`. If you add a `+` (plus sign) after '%' of a placeholder, a line-feed is inserted immediately before the expansion if and only if the diff --git a/Documentation/pretty-options.txt b/Documentation/pretty-options.adoc similarity index 100% rename from Documentation/pretty-options.txt rename to Documentation/pretty-options.adoc diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.adoc similarity index 95% rename from Documentation/pull-fetch-param.txt rename to Documentation/pull-fetch-param.adoc index c718f7946f065d..d79d2f6065bcd4 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.adoc @@ -25,14 +25,15 @@ endif::git-pull[] + The format of a <refspec> parameter is an optional plus `+`, followed by the source <src>, followed -by a colon `:`, followed by the destination ref <dst>. +by a colon `:`, followed by the destination <dst>. The colon can be omitted when <dst> is empty. <src> is -typically a ref, but it can also be a fully spelled hex object +typically a ref, or a glob pattern with a single `*` that is used +to match a set of refs, but it can also be a fully spelled hex object name. + A <refspec> may contain a `*` in its <src> to indicate a simple pattern match. Such a refspec functions like a glob that matches any ref with the -same prefix. A pattern <refspec> must have a `*` in both the <src> and +pattern. A pattern <refspec> must have one and only one `*` in both the <src> and <dst>. It will map refs to the destination by replacing the `*` with the contents matched from the source. + diff --git a/Documentation/ref-reachability-filters.txt b/Documentation/ref-reachability-filters.adoc similarity index 100% rename from Documentation/ref-reachability-filters.txt rename to Documentation/ref-reachability-filters.adoc diff --git a/Documentation/ref-storage-format.txt b/Documentation/ref-storage-format.adoc similarity index 100% rename from Documentation/ref-storage-format.txt rename to Documentation/ref-storage-format.adoc diff --git a/Documentation/rerere-options.txt b/Documentation/rerere-options.adoc similarity index 100% rename from Documentation/rerere-options.txt rename to Documentation/rerere-options.adoc diff --git a/Documentation/rev-list-description.txt b/Documentation/rev-list-description.adoc similarity index 100% rename from Documentation/rev-list-description.txt rename to Documentation/rev-list-description.adoc diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.adoc similarity index 97% rename from Documentation/rev-list-options.txt rename to Documentation/rev-list-options.adoc index 00ccf68744103d..785c0786e0cf2c 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.adoc @@ -412,7 +412,8 @@ Default mode:: --ancestry-path[=<commit>]:: When given a range of commits to display (e.g. 'commit1..commit2' - or 'commit2 {caret}commit1'), only display commits in that range + or 'commit2 {caret}commit1'), and a commit <commit> in that range, + only display commits in that range that are ancestors of <commit>, descendants of <commit>, or <commit> itself. If no commit is specified, use 'commit1' (the excluded part of the range) as <commit>. Can be passed multiple @@ -1023,6 +1024,25 @@ Unexpected missing objects will raise an error. The form '--missing=print' is like 'allow-any', but will also print a list of the missing objects. Object IDs are prefixed with a ``?'' character. + +The form '--missing=print-info' is like 'print', but will also print additional +information about the missing object inferred from its containing object. The +information is all printed on the same line with the missing object ID in the +form: `?<oid> [<token>=<value>]...`. The `<token>=<value>` pairs containing +additional information are separated from each other by a SP. The value is +encoded in a token specific fashion, but SP or LF contained in value are always +expected to be represented in such a way that the resulting encoded value does +not have either of these two problematic bytes. Each `<token>=<value>` may be +one of the following: ++ +-- +* The `path=<path>` shows the path of the missing object inferred from a + containing object. A path containing SP or special characters is enclosed in + double-quotes in the C style as needed. ++ +* The `type=<type>` shows the type of the missing object inferred from a + containing object. +-- ++ If some tips passed to the traversal are missing, they will be considered as missing too, and the traversal will ignore them. In case we cannot get their Object ID though, an error will be raised. @@ -1058,7 +1078,7 @@ more specialized family of commit log tools: linkgit:git-log[1], linkgit:git-show[1], and linkgit:git-whatchanged[1] endif::git-rev-list[] -include::pretty-options.txt[] +include::pretty-options.adoc[] --relative-date:: Synonym for `--date=relative`. diff --git a/Documentation/revisions.txt b/Documentation/revisions.adoc similarity index 100% rename from Documentation/revisions.txt rename to Documentation/revisions.adoc diff --git a/Documentation/scalar.txt b/Documentation/scalar.adoc similarity index 100% rename from Documentation/scalar.txt rename to Documentation/scalar.adoc diff --git a/Documentation/sequencer.txt b/Documentation/sequencer.adoc similarity index 100% rename from Documentation/sequencer.txt rename to Documentation/sequencer.adoc diff --git a/Documentation/signoff-option.txt b/Documentation/signoff-option.adoc similarity index 85% rename from Documentation/signoff-option.txt rename to Documentation/signoff-option.adoc index d98758f3cb70d7..cddfb225d1d62a 100644 --- a/Documentation/signoff-option.txt +++ b/Documentation/signoff-option.adoc @@ -1,8 +1,8 @@ ifdef::git-commit[] --s:: +`-s`:: endif::git-commit[] ---signoff:: ---no-signoff:: +`--signoff`:: +`--no-signoff`:: Add a `Signed-off-by` trailer by the committer at the end of the commit log message. The meaning of a signoff depends on the project to which you're committing. For example, it may certify that @@ -14,5 +14,5 @@ endif::git-commit[] leadership of the project to which you're contributing to understand how the signoffs are used in that project. + -The --no-signoff option can be used to countermand an earlier --signoff +The `--no-signoff` option can be used to countermand an earlier `--signoff` option on the command line. diff --git a/Documentation/technical/.gitignore b/Documentation/technical/.gitignore index 8aa891daee050f..3caef14a9383df 100644 --- a/Documentation/technical/.gitignore +++ b/Documentation/technical/.gitignore @@ -1 +1,2 @@ api-index.txt +api-index.adoc diff --git a/Documentation/technical/api-error-handling.txt b/Documentation/technical/api-error-handling.adoc similarity index 100% rename from Documentation/technical/api-error-handling.txt rename to Documentation/technical/api-error-handling.adoc diff --git a/Documentation/technical/api-index-skel.txt b/Documentation/technical/api-index-skel.adoc similarity index 100% rename from Documentation/technical/api-index-skel.txt rename to Documentation/technical/api-index-skel.adoc diff --git a/Documentation/technical/api-index.sh b/Documentation/technical/api-index.sh index 9c3f4131b85864..dd206b1ca4954e 100755 --- a/Documentation/technical/api-index.sh +++ b/Documentation/technical/api-index.sh @@ -1,28 +1,39 @@ #!/bin/sh +if test $# -ne 2 +then + echo >&2 "USAGE: $0 <SOURCE_DIR> <OUTPUT>" + exit 1 +fi + +SOURCE_DIR="$1" +OUTPUT="$2" + ( + cd "$SOURCE_DIR" + c=//////////////////////////////////////////////////////////////// - skel=api-index-skel.txt + skel=api-index-skel.adoc sed -e '/^\/\/ table of contents begin/q' "$skel" echo "$c" - ls api-*.txt | + ls api-*.adoc | while read filename do case "$filename" in - api-index-skel.txt | api-index.txt) continue ;; + api-index-skel.adoc | api-index.adoc) continue ;; esac title=$(sed -e 1q "$filename") - html=${filename%.txt}.html + html=${filename%.adoc}.html echo "* link:$html[$title]" done echo "$c" sed -n -e '/^\/\/ table of contents end/,$p' "$skel" -) >api-index.txt+ +) >"$OUTPUT"+ -if test -f api-index.txt && cmp api-index.txt api-index.txt+ >/dev/null +if test -f "$OUTPUT" && cmp "$OUTPUT" "$OUTPUT"+ >/dev/null then - rm -f api-index.txt+ + rm -f "$OUTPUT"+ else - mv api-index.txt+ api-index.txt + mv "$OUTPUT"+ "$OUTPUT" fi diff --git a/Documentation/technical/api-merge.txt b/Documentation/technical/api-merge.adoc similarity index 100% rename from Documentation/technical/api-merge.txt rename to Documentation/technical/api-merge.adoc diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.adoc similarity index 100% rename from Documentation/technical/api-parse-options.txt rename to Documentation/technical/api-parse-options.adoc diff --git a/Documentation/technical/api-path-walk.adoc b/Documentation/technical/api-path-walk.adoc new file mode 100644 index 00000000000000..4fb6b0393e167e --- /dev/null +++ b/Documentation/technical/api-path-walk.adoc @@ -0,0 +1,73 @@ +Path-Walk API +============= + +The path-walk API is used to walk reachable objects, but to visit objects +in batches based on a common path they appear in, or by type. + +For example, all reachable commits are visited in a group. All tags are +visited in a group. Then, all root trees are visited. At some point, all +blobs reachable via a path `my/dir/to/A` are visited. When there are +multiple paths possible to reach the same object, then only one of those +paths is used to visit the object. + +Basics +------ + +To use the path-walk API, include `path-walk.h` and call +`walk_objects_by_path()` with a customized `path_walk_info` struct. The +struct is used to set all of the options for how the walk should proceed. +Let's dig into the different options and their use. + +`path_fn` and `path_fn_data`:: + The most important option is the `path_fn` option, which is a + function pointer to the callback that can execute logic on the + object IDs for objects grouped by type and path. This function + also receives a `data` value that corresponds to the + `path_fn_data` member, for providing custom data structures to + this callback function. + +`revs`:: + To configure the exact details of the reachable set of objects, + use the `revs` member and initialize it using the revision + machinery in `revision.h`. Initialize `revs` using calls such as + `setup_revisions()` or `parse_revision_opt()`. Do not call + `prepare_revision_walk()`, as that will be called within + `walk_objects_by_path()`. ++ +It is also important that you do not specify the `--objects` flag for the +`revs` struct. The revision walk should only be used to walk commits, and +the objects will be walked in a separate way based on those starting +commits. + +`commits`, `blobs`, `trees`, `tags`:: + By default, these members are enabled and signal that the path-walk + API should call the `path_fn` on objects of these types. Specialized + applications could disable some options to make it simpler to walk + the objects or to have fewer calls to `path_fn`. ++ +While it is possible to walk only commits in this way, consumers would be +better off using the revision walk API instead. + +`prune_all_uninteresting`:: + By default, all reachable paths are emitted by the path-walk API. + This option allows consumers to declare that they are not + interested in paths where all included objects are marked with the + `UNINTERESTING` flag. This requires using the `boundary` option in + the revision walk so that the walk emits commits marked with the + `UNINTERESTING` flag. + +`pl`:: + This pattern list pointer allows focusing the path-walk search to + a set of patterns, only emitting paths that match the given + patterns. See linkgit:gitignore[5] or + linkgit:git-sparse-checkout[1] for details about pattern lists. + When the pattern list uses cone-mode patterns, then the path-walk + API can prune the set of paths it walks to improve performance. + +Examples +-------- + +See example usages in: + `builtin/backfill.c` + `t/helper/test-path-walk.c` + `builtin/survey.c` diff --git a/Documentation/technical/api-simple-ipc.txt b/Documentation/technical/api-simple-ipc.adoc similarity index 98% rename from Documentation/technical/api-simple-ipc.txt rename to Documentation/technical/api-simple-ipc.adoc index c4fb152b23291c..972178b042bc99 100644 --- a/Documentation/technical/api-simple-ipc.txt +++ b/Documentation/technical/api-simple-ipc.adoc @@ -36,7 +36,7 @@ Comparison with sub-process model --------------------------------- The Simple-IPC mechanism differs from the existing `sub-process.c` -model (Documentation/technical/long-running-process-protocol.txt) and +model (Documentation/technical/long-running-process-protocol.adoc) and used by applications like Git-LFS. In the LFS-style sub-process model, the helper is started by the foreground process, communication happens via a pair of file descriptors bound to the stdin/stdout of the diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.adoc similarity index 99% rename from Documentation/technical/api-trace2.txt rename to Documentation/technical/api-trace2.adoc index 5817b18310c0f9..cf493dae03f3ac 100644 --- a/Documentation/technical/api-trace2.txt +++ b/Documentation/technical/api-trace2.adoc @@ -140,7 +140,7 @@ $ cat ~/log.event To enable a target, set the corresponding environment variable or system or global config value to one of the following: -include::../trace2-target-values.txt[] +include::../trace2-target-values.adoc[] When trace files are written to a target directory, they will be named according to the last component of the SID (optionally followed by a counter to avoid diff --git a/Documentation/technical/bitmap-format.txt b/Documentation/technical/bitmap-format.adoc similarity index 100% rename from Documentation/technical/bitmap-format.txt rename to Documentation/technical/bitmap-format.adoc diff --git a/Documentation/technical/build-systems.adoc b/Documentation/technical/build-systems.adoc new file mode 100644 index 00000000000000..d9dafb407c4090 --- /dev/null +++ b/Documentation/technical/build-systems.adoc @@ -0,0 +1,224 @@ += Build Systems + +The build system is the primary way for both developers and system integrators +to interact with the Git project. As such, being easy to use and extend for +those who are not directly developing Git itself is just as important as other +requirements we have on any potential build system. + +This document outlines the different requirements that we have for the build +system and then compares available build systems using these criteria. + +== Requirements + +The following subsections present a list of requirements that we have for any +potential build system. Sections are sorted by decreasing priority. + +=== Platform support + +The build system must have support for all of our platforms that we continually +test against as outlined by our platform support policy. These platforms are: + + - Linux + - Windows + - macOS + +Furthermore, the build system should have support for the following platforms +that generally have somebody running test pipelines against regularly: + + - AIX + - FreeBSD + - NetBSD + - NonStop + - OpenBSD + +The platforms which must be supported by the tool should be aligned with our +[platform support policy](platform-support.txt). + +=== Auto-detection of supported features + +The build system must support auto-detection of features which are or aren't +available on the current platform. Platform maintainers should not be required +to manually configure the complete build. + +Auto-detection of the following items is considered to be important: + + - Check for the existence of headers. + - Check for the existence of libraries. + - Check for the existence of exectuables. + - Check for the runtime behavior of specific functions. + - Check for specific link order requirements when multiple libraries are + involved. + +=== Ease of use + +The build system should be both easy to use and easy to extend. While this is +naturally a subjective metric it is likely not controversial to say that some +build systems are considerably harder to use than others. + +=== IDE support + +The build system should integrate with well-known IDEs. Well-known IDEs include: + + - Microsoft Visual Studio + - Visual Studio Code + - Xcode + +There are four levels of support: + + - Native integration into the IDE. + - Integration into the IDE via a plugin. + - Integration into the IDE via generating a project description with the build + system. + - No integration. + +Native integration is preferable, but integration via either a plugin or by +generating a project description via the build system are considered feasible +alternatives. + +Another important distinction is the level of integration. There are two +features that one generally wants to have: + + - Integration of build targets. + - Automatic setup of features like code completion with detected build + dependencies. + +The first bullet point is the bare minimum, but is not sufficient to be +considered proper integration. + +=== Out-of-tree builds + +The build system should support out-of-tree builds. Out-of-tree builds allow a +developer to configure multiple different build directories with different +configuration, e.g. one "debug" build and one "release" build. + +=== Cross-platform builds + +The build system should support cross-platform builds, e.g. building for arm on +an x86-64 host. + +=== Language support + +The following languages and toolchains are of relevance and should be supported +by the build system: + + - C: the primary compiled language used by Git, must be supported. Relevant + toolchains are GCC, Clang and MSVC. + - Rust: candidate as a second compiled lanugage, should be supported. Relevant + toolchains is the LLVM-based rustc. + +Built-in support for the respective languages is preferred over support that +needs to be wired up manually to avoid unnecessary complexity. Native support +includes the following features: + + - Compiling objects. + - Dependency tracking. + - Detection of available features. + - Discovery of relevant toolchains. + - Linking libraries and executables. + - Templating placeholders in scripts. + +=== Test integration + +It should be possible to integrate tests into the build system such that it is +possible to build and test Git within the build system. Features which are nice +to have: + + - Track build-time dependencies for respective tests. Unit tests have + different requirements than integration tests. + - Allow filtering of which tests to run. + - Allow running tests such that utilities like `test_pause` or `debug` work. + +== Comparison + +The following list of build systems are considered: + +- GNU Make +- autoconf +- CMake +- Meson + +=== GNU Make + +- Platform support: ubitquitous on all platforms, but not well-integrated into Windows. +- Auto-detection: no built-in support for auto-detection of features. +- Ease of use: easy to use, but discovering available options is hard. Makefile + rules can quickly get out of hand once reaching a certain scope. +- IDE support: execution of Makefile targets is supported by many IDEs +- Out-of-tree builds: supported in theory, not wired up in practice. +- Cross-platform builds: supported in theory, not wired up in practice. +- Language support: + - C: Limited built-in support, many parts need to be wired up manually. + - Rust: No built-in support, needs to be wired up manually. +- Test integration: partially supported, many parts need to be wired up + manually. + +=== autoconf + +- Platform support: ubiquitous on all platforms, but not well-integrated into Windows. +- Auto-detection: supported. +- Ease of use: easy to use, discovering available options is comparatively + easy. The autoconf syntax is prohibitively hard to extend though due to its + complex set of interacting files and the hard-to-understand M4 language. +- IDE support: no integration into IDEs at generation time. The generated + Makefiles have the same level of support as GNU Make. +- Out-of-tree builds: supported in theory, not wired up in practice. +- Cross-platform builds: supported. +- Language support: + - C: Limited built-in support, many parts need to be wired up manually. + - Rust: No built-in support, needs to be wired up manually. +- Test integration: partially supported, many parts need to be wired up + manually. + +=== CMake + +- Platform support: not as extensive as GNU Make or autoconf, but all major + platforms are supported. + - AIX + - Cygwin + - FreeBSD + - Linux + - OpenBSD + - Solaris + - Windows + - macOS +- Ease of use: easy to use, discovering available options is not always + trivial. The scripting language used by CMake is somewhat cumbersome to use, + but extending CMake build instructions is doable. +- IDE support: natively integrated into Microsoft Visual Studio. Can generate + project descriptions for Xcode. An extension is available for Visual Studio + Code. Many other IDEs have plugins for CMake. +- Out-of-tree builds: supported. +- Cross-platform builds: supported. +- Language support: + - C: Supported for GCC, Clang, MSVC and other toolchains. + - Rust: No built-in support, needs to be wired up manually. +- Test integration: supported, even though test dependencies are a bit + cumbersome to use via "test fixtures". Interactive test runs are not + supported. + +=== Meson + +- Platform: not as extensive as GNU Make or autoconf, but all major platforms + and some smaller ones are supported. + - AIX + - Cygwin + - DragonflyBSD + - FreeBSD + - Haiku + - Linux + - NetBSD + - OpenBSD + - Solaris + - Windows + - macOS +- Ease of use: easy to use, discovering available options is easy. The + scripting language is straight-forward to use. +- IDE support: Supports generating build instructions for Xcode and Microsoft + Visual Studio, a plugin exists for Visual Studio Code. +- Out-of-tree builds: supported. +- Cross-platform builds: supported. +- Language support: + - C: Supported for GCC, Clang, MSVC and other toolchains. + - Rust: Supported for rustc. +- Test integration: supported. Interactive tests are supported starting with + Meson 1.5.0 via the `--interactive` flag. diff --git a/Documentation/technical/bundle-uri.txt b/Documentation/technical/bundle-uri.adoc similarity index 100% rename from Documentation/technical/bundle-uri.txt rename to Documentation/technical/bundle-uri.adoc diff --git a/Documentation/technical/commit-graph.txt b/Documentation/technical/commit-graph.adoc similarity index 100% rename from Documentation/technical/commit-graph.txt rename to Documentation/technical/commit-graph.adoc diff --git a/Documentation/technical/directory-rename-detection.txt b/Documentation/technical/directory-rename-detection.adoc similarity index 100% rename from Documentation/technical/directory-rename-detection.txt rename to Documentation/technical/directory-rename-detection.adoc diff --git a/Documentation/technical/hash-function-transition.txt b/Documentation/technical/hash-function-transition.adoc similarity index 99% rename from Documentation/technical/hash-function-transition.txt rename to Documentation/technical/hash-function-transition.adoc index ed574810891cad..f047fd80cadd1e 100644 --- a/Documentation/technical/hash-function-transition.txt +++ b/Documentation/technical/hash-function-transition.adoc @@ -148,8 +148,8 @@ Detailed Design Repository format extension ~~~~~~~~~~~~~~~~~~~~~~~~~~~ A SHA-256 repository uses repository format version `1` (see -Documentation/technical/repository-version.txt) with extensions -`objectFormat` and `compatObjectFormat`: +linkgit:gitrepository-layout[5]) with `extensions.objectFormat` and +`extensions.compatObjectFormat` (see linkgit:git-config[1]) set to: [core] repositoryFormatVersion = 1 @@ -394,7 +394,7 @@ inflated again in step 3, for a total of two inflations. Step 4 is probably necessary for good read-time performance. "git pack-objects" on the server optimizes the pack file for good data -locality (see Documentation/technical/pack-heuristics.txt). +locality (see Documentation/technical/pack-heuristics.adoc). Details of this process are likely to change. It will take some experimenting to get this to perform well. diff --git a/Documentation/technical/large-object-promisors.adoc b/Documentation/technical/large-object-promisors.adoc new file mode 100644 index 00000000000000..dea8dafa669908 --- /dev/null +++ b/Documentation/technical/large-object-promisors.adoc @@ -0,0 +1,656 @@ +Large Object Promisors +====================== + +Since Git has been created, users have been complaining about issues +with storing large files in Git. Some solutions have been created to +help, but they haven't helped much with some issues. + +Git currently supports multiple promisor remotes, which could help +with some of these remaining issues, but it's very hard to use them to +help, because a number of important features are missing. + +The goal of the effort described in this document is to add these +important features. + +We will call a "Large Object Promisor", or "LOP" in short, a promisor +remote which is used to store only large blobs and which is separate +from the main remote that should store the other Git objects and the +rest of the repos. + +By extension, we will also call "Large Object Promisor", or LOP, the +effort described in this document to add a set of features to make it +easier to handle large blobs/files in Git by using LOPs. + +This effort aims to especially improve things on the server side, and +especially for large blobs that are already compressed in a binary +format. + +This effort aims to provide an alternative to Git LFS +(https://git-lfs.com/) and similar tools like git-annex +(https://git-annex.branchable.com/) for handling large files, even +though a complete alternative would very likely require other efforts +especially on the client side, where it would likely help to implement +a new object representation for large blobs as discussed in: + +https://lore.kernel.org/git/xmqqbkdometi.fsf@gitster.g/ + +0) Non goals +------------ + +- We will not discuss those client side improvements here, as they + would require changes in different parts of Git than this effort. ++ +So we don't pretend to fully replace Git LFS with only this effort, +but we nevertheless believe that it can significantly improve the +current situation on the server side, and that other separate +efforts could also improve the situation on the client side. + +- In the same way, we are not going to discuss all the possible ways + to implement a LOP or their underlying object storage, or to + optimize how LOP works. ++ +Our opinion is that the simplest solution for now is for LOPs to use +object storage through a remote helper (see section II.2 below for +more details) to store their objects. So we consider that this is the +default implementation. If there are improvements on top of this, +that's great, but our opinion is that such improvements are not +necessary for LOPs to already be useful. Such improvements are likely +a different technical topic, and can be taken care of separately +anyway. ++ +So in particular we are not going to discuss pluggable ODBs or other +object database backends that could chunk large blobs, dedup the +chunks and store them efficiently. Sure, that would be a nice +improvement to store large blobs on the server side, but we believe +it can just be a separate effort as it's also not technically very +related to this effort. ++ +We are also not going to discuss data transfer improvements between +LOPs and clients or servers. Sure, there might be some easy and very +effective optimizations there (as we know that objects on LOPs are +very likely incompressible and not deltifying well), but this can be +dealt with separately in a separate effort. + +In other words, the goal of this document is not to talk about all the +possible ways to optimize how Git could handle large blobs, but to +describe how a LOP based solution can already work well and alleviate +a number of current issues in the context of Git clients and servers +sharing Git objects. + +Even if LOPs are used not very efficiently, they can still be useful +and worth using in some cases, as we will see in more details +later in this document: + + - they can make it simpler for clients to use promisor remotes and + therefore avoid fetching a lot of large blobs they might not need + locally, + + - they can make it significantly cheaper or easier for servers to + host a significant part of the current repository content, and + even more to host content with larger blobs or more large blobs + than currently. + +I) Issues with the current situation +------------------------------------ + +- Some statistics made on GitLab repos have shown that more than 75% + of the disk space is used by blobs that are larger than 1MB and + often in a binary format. + +- So even if users could use Git LFS or similar tools to store a lot + of large blobs out of their repos, it's a fact that in practice they + don't do it as much as they probably should. + +- On the server side ideally, the server should be able to decide for + itself how it stores things. It should not depend on users deciding + to use tools like Git LFS on some blobs or not. + +- It's much more expensive to store large blobs that don't delta + compress well on regular fast seeking drives (like SSDs) than on + object storage (like Amazon S3 or GCP Buckets). Using fast drives + for regular Git repos makes sense though, as serving regular Git + content (blobs containing text or code) needs drives where seeking + is fast, but the content is relatively small. On the other hand, + object storage for Git LFS blobs makes sense as seeking speed is not + as important when dealing with large files, while costs are more + important. So the fact that users don't use Git LFS or similar tools + for a significant number of large blobs has likely some bad + consequences on the cost of repo storage for most Git hosting + platforms. + +- Having large blobs handled in the same way as other blobs and Git + objects in Git repos instead of on object storage also has a cost in + increased memory and CPU usage, and therefore decreased performance, + when creating packfiles. (This is because Git tries to use delta + compression or zlib compression which is unlikely to work well on + already compressed binary content.) So it's not just a storage cost + increase. + +- When a large blob has been committed into a repo, it might not be + possible to remove this blob from the repo without rewriting + history, even if the user then decides to use Git LFS or a similar + tool to handle it. + +- In fact Git LFS and similar tools are not very flexible in letting + users change their minds about the blobs they should handle or not. + +- Even when users are using Git LFS or similar tools, they are often + complaining that these tools require significant effort to set up, + learn and use correctly. + +II) Main features of the "Large Object Promisors" solution +---------------------------------------------------------- + +The main features below should give a rough overview of how the +solution may work. Details about needed elements can be found in +following sections. + +Even if each feature below is very useful for the full solution, it is +very likely to be also useful on its own in some cases where the full +solution is not required. However, we'll focus primarily on the big +picture here. + +Also each feature doesn't need to be implemented entirely in Git +itself. Some could be scripts, hooks or helpers that are not part of +the Git repo. It would be helpful if those could be shared and +improved on collaboratively though. So we want to encourage sharing +them. + +1) Large blobs are stored on LOPs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Large blobs should be stored on special promisor remotes that we will +call "Large Object Promisors" or LOPs. These LOPs should be additional +remotes dedicated to contain large blobs especially those in binary +format. They should be used along with main remotes that contain the +other objects. + +Note 1 +++++++ + +To clarify, a LOP is a normal promisor remote, except that: + +- it should store only large blobs, + +- it should be separate from the main remote, so that the main remote + can focus on serving other objects and the rest of the repos (see + feature 4) below) and can use the LOP as a promisor remote for + itself. + +Note 2 +++++++ + +Git already makes it possible for a main remote to also be a promisor +remote storing both regular objects and large blobs for a client that +clones from it with a filter on blob size. But here we explicitly want +to avoid that. + +Rationale ++++++++++ + +LOPs aim to be good at handling large blobs while main remotes are +already good at handling other objects. + +Implementation +++++++++++++++ + +Git already has support for multiple promisor remotes, see +link:partial-clone.html#using-many-promisor-remotes[the partial clone documentation]. + +Also, Git already has support for partial clone using a filter on the +size of the blobs (with `git clone --filter=blob:limit=<size>`). Most +of the other main features below are based on these existing features +and are about making them easy and efficient to use for the purpose of +better handling large blobs. + +2) LOPs can use object storage +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +LOPs can be implemented using object storage, like an Amazon S3 or GCP +Bucket or MinIO (which is open source under the GNU AGPLv3 license) to +actually store the large blobs, and can be accessed through a Git +remote helper (see linkgit:gitremote-helpers[7]) which makes the +underlying object storage appear like a remote to Git. + +Note +++++ + +A LOP can be a promisor remote accessed using a remote helper by +both some clients and the main remote. + +Rationale ++++++++++ + +This looks like the simplest way to create LOPs that can cheaply +handle many large blobs. + +Implementation +++++++++++++++ + +Remote helpers are quite easy to write as shell scripts, but it might +be more efficient and maintainable to write them using other languages +like Go. + +Some already exist under open source licenses, for example: + + - https://github.com/awslabs/git-remote-s3 + - https://gitlab.com/eric.p.ju/git-remote-gs + +Other ways to implement LOPs are certainly possible, but the goal of +this document is not to discuss how to best implement a LOP or its +underlying object storage (see the "0) Non goals" section above). + +3) LOP object storage can be Git LFS storage +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The underlying object storage that a LOP uses could also serve as +storage for large files handled by Git LFS. + +Rationale ++++++++++ + +This would simplify the server side if it wants to both use a LOP and +act as a Git LFS server. + +4) A main remote can offload to a LOP with a configurable threshold +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +On the server side, a main remote should have a way to offload to a +LOP all its blobs with a size over a configurable threshold. + +Rationale ++++++++++ + +This makes it easy to set things up and to clean things up. For +example, an admin could use this to manually convert a repo not using +LOPs to a repo using a LOP. On a repo already using a LOP but where +some users would sometimes push large blobs, a cron job could use this +to regularly make sure the large blobs are moved to the LOP. + +Implementation +++++++++++++++ + +Using something based on `git repack --filter=...` to separate the +blobs we want to offload from the other Git objects could be a good +idea. The missing part is to connect to the LOP, check if the blobs we +want to offload are already there and if not send them. + +5) A main remote should try to remain clean from large blobs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A main remote should try to avoid containing a lot of oversize +blobs. For that purpose, it should offload as needed to a LOP and it +should have ways to prevent oversize blobs to be fetched, and also +perhaps pushed, into it. + +Rationale ++++++++++ + +A main remote containing many oversize blobs would defeat the purpose +of LOPs. + +Implementation +++++++++++++++ + +The way to offload to a LOP discussed in 4) above can be used to +regularly offload oversize blobs. About preventing oversize blobs from +being fetched into the repo see 6) below. About preventing oversize +blob pushes, a pre-receive hook could be used. + +Also there are different scenarios in which large blobs could get +fetched into the main remote, for example: + +- A client that doesn't implement the "promisor-remote" protocol + (described in 6) below) clones from the main remote. + +- The main remote gets a request for information about a large blob + and is not able to get that information without fetching the blob + from the LOP. + +It might not be possible to completely prevent all these scenarios +from happening. So the goal here should be to implement features that +make the fetching of large blobs less likely. For example adding a +`remote-object-info` command in the `git cat-file --batch` protocol +and its variants might make it possible for a main repo to respond to +some requests about large blobs without fetching them. + +6) A protocol negotiation should happen when a client clones +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When a client clones from a main repo, there should be a protocol +negotiation so that the server can advertise one or more LOPs and so +that the client and the server can discuss if the client could +directly use a LOP the server is advertising. If the client and the +server can agree on that, then the client would be able to get the +large blobs directly from the LOP and the server would not need to +fetch those blobs from the LOP to be able to serve the client. + +Note +++++ + +For fetches instead of clones, a protocol negotiation might not always +happen, see the "What about fetches?" FAQ entry below for details. + +Rationale ++++++++++ + +Security, configurability and efficiency of setting things up. + +Implementation +++++++++++++++ + +A "promisor-remote" protocol v2 capability looks like a good way to +implement this. The way the client and server use this capability +could be controlled by configuration variables. + +Information that the server could send to the client through that +protocol could be things like: LOP name, LOP URL, filter-spec (for +example `blob:limit=<size>`) or just size limit that should be used as +a filter when cloning, token to be used with the LOP, etc. + +7) A client can offload to a LOP +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When a client is using a LOP that is also a LOP of its main remote, +the client should be able to offload some large blobs it has fetched, +but might not need anymore, to the LOP. + +Note +++++ + +It might depend on the context if it should be OK or not for clients +to offload large blobs they have created, instead of fetched, directly +to the LOP without the main remote checking them in some ways +(possibly using hooks or other tools). + +This should be discussed and refined when we get closer to +implementing this feature. + +Rationale ++++++++++ + +On the client, the easiest way to deal with unneeded large blobs is to +offload them. + +Implementation +++++++++++++++ + +This is very similar to what 4) above is about, except on the client +side instead of the server side. So a good solution to 4) could likely +be adapted to work on the client side too. + +There might be some security issues here, as there is no negotiation, +but they might be mitigated if the client can reuse a token it got +when cloning (see 6) above). Also if the large blobs were fetched from +a LOP, it is likely, and can easily be confirmed, that the LOP still +has them, so that they can just be removed from the client. + +III) Benefits of using LOPs +--------------------------- + +Many benefits are related to the issues discussed in "I) Issues with +the current situation" above: + +- No need to rewrite history when deciding which blobs are worth + handling separately than other objects, or when moving or removing + the threshold. + +- If the protocol between client and server is developed and secured + enough, then many details might be setup on the server side only and + all the clients could then easily get all the configuration + information and use it to set themselves up mostly automatically. + +- Storage costs benefits on the server side. + +- Reduced memory and CPU needs on main remotes on the server side. + +- Reduced storage needs on the client side. + +IV) FAQ +------- + +What about using multiple LOPs on the server and client side? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +That could perhaps be useful in some cases, but for now it's more +likely that in most cases a single LOP will be advertised by the +server and should be used by the client. + +A case where it could be useful for a server to advertise multiple +LOPs is if a LOP is better for some users while a different LOP is +better for other users. For example some clients might have a better +connection to a LOP than others. + +In those cases it's the responsibility of the server to have some +documentation to help clients. It could say for example something like +"Users in this part of the world might want to pick only LOP A as it +is likely to be better connected to them, while users in other parts +of the world should pick only LOP B for the same reason." + +When should we trust or not trust the LOPs advertised by the server? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In some contexts, like in corporate setup where the server and all the +clients are parts of an internal network in a company where admins +have all the rights on every system, it's OK, and perhaps even a good +thing, if the clients fully trust the server, as it can help ensure +that all the clients are on the same page. + +There are also contexts in which clients trust a code hosting platform +serving them some repos, but might not fully trust other users +managing or contributing to some of these repos. For example, the code +hosting platform could have hooks in place to check that any object it +receives doesn't contain malware or otherwise bad content. In this +case it might be OK for the client to use a main remote and its LOP if +they are both hosted by the code hosting platform, but not if the LOP +is hosted elsewhere (where the content is not checked). + +In other contexts, a client should just not trust a server. + +So there should be different ways to configure how the client should +behave when a server advertises a LOP to it at clone time. + +As the basic elements that a server can advertise about a LOP are a +LOP name and a LOP URL, the client should base its decision about +accepting a LOP on these elements. + +One simple way to be very strict in the LOP it accepts is for example +for the client to check that the LOP is already configured on the +client with the same name and URL as what the server advertises. + +In general default and "safe" settings should require that the LOP are +configured on the client separately from the "promisor-remote" +protocol and that the client accepts a LOP only when information about +it from the protocol matches what has been already configured +separately. + +What about LOP names? +~~~~~~~~~~~~~~~~~~~~~ + +In some contexts, for example if the clients sometimes fetch from each +other, it can be a good idea for all the clients to use the same names +for all the remotes they use, including LOPs. + +In other contexts, each client might want to be able to give the name +it wants to each remote, including each LOP, it interacts with. + +So there should be different ways to configure how the client accepts +or not the LOP name the server advertises. + +If a default or "safe" setting is used, then as such a setting should +require that the LOP be configured separately, then the name would be +configured separately and there is no risk that the server could +dictate a name to a client. + +Could the main remote be bogged down by old or paranoid clients? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Yes, it could happen if there are too many clients that are either +unwilling to trust the main remote or that just don't implement the +"promisor-remote" protocol because they are too old or not fully +compatible with the 'git' client. + +When serving such a client, the main remote has no other choice than +to first fetch from its LOP, to then be able to provide to the client +everything it requested. So the main remote, even if it has cleanup +mechanisms (see section II.4 above), would be burdened at least +temporarily with the large blobs it had to fetch from its LOP. + +Not behaving like this would be breaking backward compatibility, and +could be seen as segregating clients. For example, it might be +possible to implement a special mode that allows the server to just +reject clients that don't implement the "promisor-remote" protocol or +aren't willing to trust the main remote. This mode might be useful in +a special context like a corporate environment. There is no plan to +implement such a mode though, and this should be discussed separately +later anyway. + +A better way to proceed is probably for the main remote to show a +message telling clients that don't implement the protocol or are +unwilling to accept the advertised LOP(s) that they would get faster +clone and fetches by upgrading client software or properly setting +them up to accept LOP(s). + +Waiting for clients to upgrade, monitoring these upgrades and limiting +the use of LOPs to repos that are not very frequently accessed might +be other good ways to make sure that some benefits are still reaped +from LOPs. Over time, as more and more clients upgrade and benefit +from LOPs, using them in more and more frequently accessed repos will +become worth it. + +Corporate environments, where it might be easier to make sure that all +the clients are up-to-date and properly configured, could hopefully +benefit more and earlier from using LOPs. + +What about fetches? +~~~~~~~~~~~~~~~~~~~ + +There are different kinds of fetches. A regular fetch happens when +some refs have been updated on the server and the client wants the ref +updates and possibly the new objects added with them. A "backfill" or +"lazy" fetch, on the contrary, happens when the client needs to use +some objects it already knows about but doesn't have because they are +on a promisor remote. + +Regular fetch ++++++++++++++ + +In a regular fetch, the client will contact the main remote and a +protocol negotiation will happen between them. It's a good thing that +a protocol negotiation happens every time, as the configuration on the +client or the main remote could have changed since the previous +protocol negotiation. In this case, the new protocol negotiation +should ensure that the new fetch will happen in a way that satisfies +the new configuration of both the client and the server. + +In most cases though, the configurations on the client and the main +remote will not have changed between 2 fetches or between the initial +clone and a subsequent fetch. This means that the result of a new +protocol negotiation will be the same as the previous result, so the +new fetch will happen in the same way as the previous clone or fetch, +using, or not using, the same LOP(s) as last time. + +"Backfill" or "lazy" fetch +++++++++++++++++++++++++++ + +When there is a backfill fetch, the client doesn't necessarily contact +the main remote first. It will try to fetch from its promisor remotes +in the order they appear in the config file, except that a remote +configured using the `extensions.partialClone` config variable will be +tried last. See +link:partial-clone.html#using-many-promisor-remotes[the partial clone documentation]. + +This is not new with this effort. In fact this is how multiple remotes +have already been working for around 5 years. + +When using LOPs, having the main remote configured using +`extensions.partialClone`, so it's tried last, makes sense, as missing +objects should only be large blobs that are on LOPs. + +This means that a protocol negotiation will likely not happen as the +missing objects will be fetched from the LOPs, and then there will be +nothing left to fetch from the main remote. + +To secure that, it could be a good idea for LOPs to require a token +from the client when it fetches from them. The client could get the +token when performing a protocol negotiation with the main remote (see +section II.6 above). + +V) Future improvements +---------------------- + +It is expected that at the beginning using LOPs will be mostly worth +it either in a corporate context where the Git version that clients +use can easily be controlled, or on repos that are infrequently +accessed. (See the "Could the main remote be bogged down by old or +paranoid clients?" section in the FAQ above.) + +Over time, as more and more clients upgrade to a version that +implements the "promisor-remote" protocol v2 capability described +above in section II.6), it will be worth it to use LOPs more widely. + +A lot of improvements may also help using LOPs more widely. Some of +these improvements are part of the scope of this document like the +following: + + - Implementing a "remote-object-info" command in the + `git cat-file --batch` protocol and its variants to allow main + remotes to respond to requests about large blobs without fetching + them. (Eric Ju has started working on this based on previous work + by Calvin Wan.) + + - Creating better cleanup and offload mechanisms for main remotes + and clients to prevent accumulation of large blobs. + + - Developing more sophisticated protocol negotiation capabilities + between clients and servers for handling LOPs, for example adding + a filter-spec (e.g., blob:limit=<size>) or size limit for + filtering when cloning, or adding a token for LOP authentication. + + - Improving security measures for LOP access, particularly around + token handling and authentication. + + - Developing standardized ways to configure and manage multiple LOPs + across different environments. Especially in the case where + different LOPs serve the same content to clients in different + geographical locations, there is a need for replication or + synchronization between LOPs. + +Some improvements, including some that have been mentioned in the "0) +Non Goals" section of this document, are out of the scope of this +document: + + - Implementing a new object representation for large blobs on the + client side. + + - Developing pluggable ODBs or other object database backends that + could chunk large blobs, dedup the chunks and store them + efficiently. + + - Optimizing data transfer between LOPs and clients/servers, + particularly for incompressible and non-deltifying content. + + - Creating improved client side tools for managing large objects + more effectively, for example tools for migrating from Git LFS or + git-annex, or tools to find which objects could be offloaded and + how much disk space could be reclaimed by offloading them. + +Some improvements could be seen as part of the scope of this document, +but might already have their own separate projects from the Git +project, like: + + - Improving existing remote helpers to access object storage or + developing new ones. + + - Improving existing object storage solutions or developing new + ones. + +Even though all the above improvements may help, this document and the +LOP effort should try to focus, at least first, on a relatively small +number of improvements mostly those that are in its current scope. + +For example introducing pluggable ODBs and a new object database +backend is likely a multi-year effort on its own that can happen +separately in parallel. It has different technical requirements, +touches other part of the Git code base and should have its own design +document(s). diff --git a/Documentation/technical/long-running-process-protocol.txt b/Documentation/technical/long-running-process-protocol.adoc similarity index 100% rename from Documentation/technical/long-running-process-protocol.txt rename to Documentation/technical/long-running-process-protocol.adoc diff --git a/Documentation/technical/meson.build b/Documentation/technical/meson.build new file mode 100644 index 00000000000000..a13aafcfbb8c75 --- /dev/null +++ b/Documentation/technical/meson.build @@ -0,0 +1,67 @@ +api_docs = [ + 'api-error-handling.adoc', + 'api-merge.adoc', + 'api-parse-options.adoc', + 'api-simple-ipc.adoc', + 'api-trace2.adoc', +] + +articles = [ + 'bitmap-format.adoc', + 'build-systems.adoc', + 'bundle-uri.adoc', + 'commit-graph.adoc', + 'directory-rename-detection.adoc', + 'hash-function-transition.adoc', + 'long-running-process-protocol.adoc', + 'multi-pack-index.adoc', + 'packfile-uri.adoc', + 'pack-heuristics.adoc', + 'parallel-checkout.adoc', + 'partial-clone.adoc', + 'platform-support.adoc', + 'racy-git.adoc', + 'reftable.adoc', + 'remembering-renames.adoc', + 'repository-version.adoc', + 'rerere.adoc', + 'scalar.adoc', + 'send-pack-pipeline.adoc', + 'shallow.adoc', + 'sparse-checkout.adoc', + 'sparse-index.adoc', + 'trivial-merge.adoc', + 'unit-tests.adoc', +] + +api_index = custom_target( + command: [ + shell, + meson.current_source_dir() / 'api-index.sh', + meson.current_source_dir(), + '@OUTPUT@', + ], + env: script_environment, + input: api_docs, + output: 'api-index.adoc', +) + +custom_target( + command: asciidoc_html_options, + input: api_index, + output: 'api-index.html', + depends: documentation_deps, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc/technical', +) + +foreach article : api_docs + articles + custom_target( + command: asciidoc_html_options, + input: article, + output: fs.stem(article) + '.html', + depends: documentation_deps, + install: true, + install_dir: get_option('datadir') / 'doc/git-doc/technical', + ) +endforeach diff --git a/Documentation/technical/multi-pack-index.txt b/Documentation/technical/multi-pack-index.adoc similarity index 100% rename from Documentation/technical/multi-pack-index.txt rename to Documentation/technical/multi-pack-index.adoc diff --git a/Documentation/technical/pack-heuristics.txt b/Documentation/technical/pack-heuristics.adoc similarity index 100% rename from Documentation/technical/pack-heuristics.txt rename to Documentation/technical/pack-heuristics.adoc diff --git a/Documentation/technical/packfile-uri.txt b/Documentation/technical/packfile-uri.adoc similarity index 100% rename from Documentation/technical/packfile-uri.txt rename to Documentation/technical/packfile-uri.adoc diff --git a/Documentation/technical/parallel-checkout.txt b/Documentation/technical/parallel-checkout.adoc similarity index 100% rename from Documentation/technical/parallel-checkout.txt rename to Documentation/technical/parallel-checkout.adoc diff --git a/Documentation/technical/partial-clone.txt b/Documentation/technical/partial-clone.adoc similarity index 98% rename from Documentation/technical/partial-clone.txt rename to Documentation/technical/partial-clone.adoc index cd948b00722cba..e513e391ea82ca 100644 --- a/Documentation/technical/partial-clone.txt +++ b/Documentation/technical/partial-clone.adoc @@ -85,7 +85,7 @@ See "filter" in linkgit:gitprotocol-pack[5]. server to request filtering during packfile construction. + There are various filters available to accommodate different situations. -See "--filter=<filter-spec>" in Documentation/rev-list-options.txt. +See "--filter=<filter-spec>" in Documentation/rev-list-options.adoc. - On the server pack-objects applies the requested filter-spec as it creates "filtered" packfiles for the client. @@ -102,7 +102,7 @@ or commits that reference missing trees. - On the client a repository extension is added to the local config to prevent older versions of git from failing mid-operation because of missing objects that they cannot handle. - See "extensions.partialClone" in Documentation/technical/repository-version.txt" + See `extensions.partialClone` in linkgit:git-config[1]. Handling Missing Objects diff --git a/Documentation/technical/platform-support.txt b/Documentation/technical/platform-support.adoc similarity index 98% rename from Documentation/technical/platform-support.txt rename to Documentation/technical/platform-support.adoc index a227c363d7824c..0a2fb28d6277f1 100644 --- a/Documentation/technical/platform-support.txt +++ b/Documentation/technical/platform-support.adoc @@ -49,7 +49,7 @@ will be fixed in a later release: notice problems before they are considered "done with review"; whereas watching `master` means the stable branch could break for your platform, but you have a decent chance of avoiding a tagged release breaking you. See "The - Policy" in link:../howto/maintain-git.txt["How to maintain Git"] for an + Policy" in link:../howto/maintain-git.html["How to maintain Git"] for an overview of which branches are used in the Git project, and how. * The bug report should include information about what platform you are using. @@ -125,7 +125,7 @@ Compatible on `next` To avoid reactive debugging and fixing when changes hit a release or stable, you can aim to ensure `next` always works for your platform. (See "The Policy" in -link:../howto/maintain-git.txt["How to maintain Git"] for an overview of how +link:../howto/maintain-git.html["How to maintain Git"] for an overview of how `next` is used in the Git project.) To do that: * You should add a runner for your platform to the GitHub Actions or GitLab CI diff --git a/Documentation/technical/racy-git.txt b/Documentation/technical/racy-git.adoc similarity index 100% rename from Documentation/technical/racy-git.txt rename to Documentation/technical/racy-git.adoc diff --git a/Documentation/technical/reftable.txt b/Documentation/technical/reftable.adoc similarity index 100% rename from Documentation/technical/reftable.txt rename to Documentation/technical/reftable.adoc diff --git a/Documentation/technical/remembering-renames.txt b/Documentation/technical/remembering-renames.adoc similarity index 100% rename from Documentation/technical/remembering-renames.txt rename to Documentation/technical/remembering-renames.adoc diff --git a/Documentation/technical/repository-version.txt b/Documentation/technical/repository-version.adoc similarity index 68% rename from Documentation/technical/repository-version.txt rename to Documentation/technical/repository-version.adoc index 47281420fc4a0c..b9bb81a81f9ea1 100644 --- a/Documentation/technical/repository-version.txt +++ b/Documentation/technical/repository-version.adoc @@ -65,44 +65,6 @@ Note that if no extensions are specified in the config file, then provides no benefit, and makes the repository incompatible with older implementations of git). -This document will serve as the master list for extensions. Any -implementation wishing to define a new extension should make a note of -it here, in order to claim the name. - -The defined extensions are: - -==== `noop` - -This extension does not change git's behavior at all. It is useful only -for testing format-1 compatibility. - -==== `preciousObjects` - -When the config key `extensions.preciousObjects` is set to `true`, -objects in the repository MUST NOT be deleted (e.g., by `git-prune` or -`git repack -d`). - -==== `partialClone` - -When the config key `extensions.partialClone` is set, it indicates -that the repo was created with a partial clone (or later performed -a partial fetch) and that the remote may have omitted sending -certain unwanted objects. Such a remote is called a "promisor remote" -and it promises that all such omitted objects can be fetched from it -in the future. - -The value of this key is the name of the promisor remote. - -==== `worktreeConfig` - -If set, by default "git config" reads from both "config" and -"config.worktree" files from GIT_DIR in that order. In -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). +The defined extensions are given in the `extensions.*` section of +linkgit:git-config[1]. Any implementation wishing to define a new +extension should make a note of it there, in order to claim the name. diff --git a/Documentation/technical/rerere.txt b/Documentation/technical/rerere.adoc similarity index 100% rename from Documentation/technical/rerere.txt rename to Documentation/technical/rerere.adoc diff --git a/Documentation/technical/scalar.txt b/Documentation/technical/scalar.adoc similarity index 100% rename from Documentation/technical/scalar.txt rename to Documentation/technical/scalar.adoc diff --git a/Documentation/technical/send-pack-pipeline.txt b/Documentation/technical/send-pack-pipeline.adoc similarity index 100% rename from Documentation/technical/send-pack-pipeline.txt rename to Documentation/technical/send-pack-pipeline.adoc diff --git a/Documentation/technical/shallow.txt b/Documentation/technical/shallow.adoc similarity index 100% rename from Documentation/technical/shallow.txt rename to Documentation/technical/shallow.adoc diff --git a/Documentation/technical/sparse-checkout.txt b/Documentation/technical/sparse-checkout.adoc similarity index 100% rename from Documentation/technical/sparse-checkout.txt rename to Documentation/technical/sparse-checkout.adoc diff --git a/Documentation/technical/sparse-index.txt b/Documentation/technical/sparse-index.adoc similarity index 100% rename from Documentation/technical/sparse-index.txt rename to Documentation/technical/sparse-index.adoc diff --git a/Documentation/technical/trivial-merge.txt b/Documentation/technical/trivial-merge.adoc similarity index 100% rename from Documentation/technical/trivial-merge.txt rename to Documentation/technical/trivial-merge.adoc diff --git a/Documentation/technical/unit-tests.txt b/Documentation/technical/unit-tests.adoc similarity index 100% rename from Documentation/technical/unit-tests.txt rename to Documentation/technical/unit-tests.adoc diff --git a/Documentation/trace2-target-values.txt b/Documentation/trace2-target-values.adoc similarity index 100% rename from Documentation/trace2-target-values.txt rename to Documentation/trace2-target-values.adoc diff --git a/Documentation/transfer-data-leaks.txt b/Documentation/transfer-data-leaks.adoc similarity index 100% rename from Documentation/transfer-data-leaks.txt rename to Documentation/transfer-data-leaks.adoc diff --git a/Documentation/urls-remotes.txt b/Documentation/urls-remotes.adoc similarity index 99% rename from Documentation/urls-remotes.txt rename to Documentation/urls-remotes.adoc index bf17012241536c..9b101511988471 100644 --- a/Documentation/urls-remotes.txt +++ b/Documentation/urls-remotes.adoc @@ -1,4 +1,4 @@ -include::urls.txt[] +include::urls.adoc[] REMOTES[[REMOTES]] ------------------ diff --git a/Documentation/urls.txt b/Documentation/urls.adoc similarity index 72% rename from Documentation/urls.txt rename to Documentation/urls.adoc index 7cec85aef17f43..9c871e716a10b0 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.adoc @@ -10,19 +10,19 @@ Git supports ssh, git, http, and https protocols (in addition, ftp and ftps can be used for fetching, but this is inefficient and deprecated; do not use them). -The native transport (i.e. git:// URL) does no authentication and +The native transport (i.e. `git://` URL) does no authentication and should be used with caution on unsecured networks. The following syntaxes may be used with them: -- ++ssh://++{startsb}__<user>__++@++{endsb}__<host>__{startsb}++:++__<port>__{endsb}++/++__<path-to-git-repo>__ -- ++git://++__<host>__{startsb}:__<port>__{endsb}++/++__<path-to-git-repo>__ -- ++http++{startsb}++s++{endsb}++://++__<host>__{startsb}++:++__<port>__{endsb}++/++__<path-to-git-repo>__ -- ++ftp++{startsb}++s++{endsb}++://++__<host>__{startsb}++:++__<port>__{endsb}++/++__<path-to-git-repo>__ +- `ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>` +- `git://<host>[:<port>]/<path-to-git-repo>` +- `http[s]://<host>[:<port>]/<path-to-git-repo>` +- `ftp[s]://<host>[:<port>]/<path-to-git-repo>` An alternative scp-like syntax may also be used with the ssh protocol: -- {startsb}__<user>__++@++{endsb}__<host>__++:/++__<path-to-git-repo>__ +- `[<user>@]<host>:/<path-to-git-repo>` This syntax is only recognized if there are no slashes before the first colon. This helps differentiate a local path that contains a @@ -30,17 +30,17 @@ colon. For example the local path `foo:bar` could be specified as an absolute path or `./foo:bar` to avoid being misinterpreted as an ssh url. -The ssh and git protocols additionally support ++~++__<username>__ expansion: +The ssh and git protocols additionally support `~<username>` expansion: -- ++ssh://++{startsb}__<user>__++@++{endsb}__<host>__{startsb}++:++__<port>__{endsb}++/~++__<user>__++/++__<path-to-git-repo>__ -- ++git://++__<host>__{startsb}++:++__<port>__{endsb}++/~++__<user>__++/++__<path-to-git-repo>__ -- {startsb}__<user>__++@++{endsb}__<host>__++:~++__<user>__++/++__<path-to-git-repo>__ +- `ssh://[<user>@]<host>[:<port>]/~<user>/<path-to-git-repo>` +- `git://<host>[:<port>]/~<user>/<path-to-git-repo>` +- `[<user>@]<host>:~<user>/<path-to-git-repo>` For local repositories, also supported by Git natively, the following syntaxes may be used: - `/path/to/repo.git/` -- ++file:///path/to/repo.git/++ +- `file:///path/to/repo.git/` ifndef::git-clone[] These two syntaxes are mostly equivalent, except when cloning, when @@ -57,11 +57,11 @@ endif::git-clone[] accept a suitable bundle file. See linkgit:git-bundle[1]. When Git doesn't know how to handle a certain transport protocol, it -attempts to use the `remote-`{empty}__<transport>__ remote helper, if one +attempts to use the `remote-<transport>` remote helper, if one exists. To explicitly request a remote helper, the following syntax may be used: -- _<transport>_::__<address>__ +- `<transport>::<address>` where _<address>_ may be a path, a server and path, or an arbitrary URL-like string recognized by the specific remote helper being diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.adoc similarity index 99% rename from Documentation/user-manual.txt rename to Documentation/user-manual.adoc index 90a4189358300b..d2b478ad23221a 100644 --- a/Documentation/user-manual.txt +++ b/Documentation/user-manual.adoc @@ -4354,7 +4354,7 @@ itself! [[git-explained]] === Git explained -include::glossary-content.txt[] +include::glossary-content.adoc[] [[git-quick-start]] [appendix] diff --git a/Documentation/user-manual.conf b/Documentation/user-manual.conf deleted file mode 100644 index 0148f126dcdf6a..00000000000000 --- a/Documentation/user-manual.conf +++ /dev/null @@ -1,11 +0,0 @@ -[titles] - underlines="__","==","--","~~","^^" - -[attributes] -caret=^ -startsb=[ -endsb=] -tilde=~ - -[linkgit-inlinemacro] -<ulink url="{target}.html">{target}{0?({0})}</ulink> diff --git a/GIT-BUILD-OPTIONS.in b/GIT-BUILD-OPTIONS.in new file mode 100644 index 00000000000000..0a9884e0ade556 --- /dev/null +++ b/GIT-BUILD-OPTIONS.in @@ -0,0 +1,48 @@ +BROKEN_PATH_FIX=@BROKEN_PATH_FIX@ +DIFF=@DIFF@ +FSMONITOR_DAEMON_BACKEND=@FSMONITOR_DAEMON_BACKEND@ +FSMONITOR_OS_SETTINGS=@FSMONITOR_OS_SETTINGS@ +GITWEBDIR=@GITWEBDIR@ +GIT_INTEROP_MAKE_OPTS=@GIT_INTEROP_MAKE_OPTS@ +GIT_PERF_LARGE_REPO=@GIT_PERF_LARGE_REPO@ +GIT_PERF_MAKE_COMMAND=@GIT_PERF_MAKE_COMMAND@ +GIT_PERF_MAKE_OPTS=@GIT_PERF_MAKE_OPTS@ +GIT_PERF_REPEAT_COUNT=@GIT_PERF_REPEAT_COUNT@ +GIT_PERF_REPO=@GIT_PERF_REPO@ +GIT_SOURCE_DIR=@GIT_SOURCE_DIR@ +GIT_TEST_CMP=@GIT_TEST_CMP@ +GIT_TEST_CMP_USE_COPIED_CONTEXT=@GIT_TEST_CMP_USE_COPIED_CONTEXT@ +GIT_TEST_GITPERLLIB=@GIT_TEST_GITPERLLIB@ +GIT_TEST_INDEX_VERSION=@GIT_TEST_INDEX_VERSION@ +GIT_TEST_OPTS=@GIT_TEST_OPTS@ +GIT_TEST_PERL_FATAL_WARNINGS=@GIT_TEST_PERL_FATAL_WARNINGS@ +GIT_TEST_TEMPLATE_DIR=@GIT_TEST_TEMPLATE_DIR@ +GIT_TEST_TEXTDOMAINDIR=@GIT_TEST_TEXTDOMAINDIR@ +GIT_TEST_UTF8_LOCALE=@GIT_TEST_UTF8_LOCALE@ +LOCALEDIR=@LOCALEDIR@ +NO_CURL=@NO_CURL@ +NO_EXPAT=@NO_EXPAT@ +NO_GETTEXT=@NO_GETTEXT@ +NO_GITWEB=@NO_GITWEB@ +NO_ICONV=@NO_ICONV@ +NO_PERL=@NO_PERL@ +NO_PERL_CPAN_FALLBACKS=@NO_PERL_CPAN_FALLBACKS@ +NO_PTHREADS=@NO_PTHREADS@ +NO_PYTHON=@NO_PYTHON@ +NO_REGEX=@NO_REGEX@ +NO_UNIX_SOCKETS=@NO_UNIX_SOCKETS@ +PAGER_ENV=@PAGER_ENV@ +PERL_LOCALEDIR=@PERL_LOCALEDIR@ +PERL_PATH=@PERL_PATH@ +PYTHON_PATH=@PYTHON_PATH@ +RUNTIME_PREFIX=@RUNTIME_PREFIX@ +SANITIZE_ADDRESS=@SANITIZE_ADDRESS@ +SANITIZE_LEAK=@SANITIZE_LEAK@ +SHELL_PATH=@SHELL_PATH@ +TAR=@TAR@ +TEST_OUTPUT_DIRECTORY=@TEST_OUTPUT_DIRECTORY@ +TEST_SHELL_PATH=@TEST_SHELL_PATH@ +USE_GETTEXT_SCHEME=@USE_GETTEXT_SCHEME@ +USE_LIBPCRE2=@USE_LIBPCRE2@ +WITH_BREAKING_CHANGES=@WITH_BREAKING_CHANGES@ +X=@X@ diff --git a/GIT-VERSION-FILE.in b/GIT-VERSION-FILE.in new file mode 100644 index 00000000000000..3789a48a34a3f9 --- /dev/null +++ b/GIT-VERSION-FILE.in @@ -0,0 +1 @@ +GIT_VERSION=@GIT_VERSION@ diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 38e920725c5f43..3abfe7d3d7e79d 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,40 +1,106 @@ #!/bin/sh -GVF=GIT-VERSION-FILE -DEF_VER=v2.47.0-rc0 +DEF_VER=v2.49.0 LF=' ' -# First see if there is a version file (included in release tarballs), -# then try git-describe, then default. -if test -f version +if test "$#" -lt 2 || test "$#" -gt 3 then - VN=$(cat version) || VN="$DEF_VER" -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) ;; - v[0-9]*) - git update-index -q --refresh - test -z "$(git diff-index --name-only HEAD --)" || - VN="$VN-dirty" ;; - esac + echo >&2 "USAGE: $0 <SOURCE_DIR> (--format=<STRING>|<INPUT>) [<OUTPUT>]" + exit 1 +fi + +SOURCE_DIR="$1" + +case "$2" in +--format=*) + INPUT="${2#--format=}" + ;; +*) + if ! test -f "$2" + then + echo >&2 "Input is not a file: $2" + exit 1 + fi + INPUT=$(cat "$2") + ;; +esac + +OUTPUT="$3" + +# Protect us from reading Git version information outside of the Git directory +# in case it is not a repository itself, but embedded in an unrelated +# repository. +GIT_CEILING_DIRECTORIES="$SOURCE_DIR/.." +export GIT_CEILING_DIRECTORIES + +if test -z "$GIT_VERSION" then - VN=$(echo "$VN" | sed -e 's/-/./g'); -else - VN="$DEF_VER" + # First see if there is a version file (included in release tarballs), + # then try git-describe, then default. + if test -f "$SOURCE_DIR"/version + then + VN=$(cat "$SOURCE_DIR"/version) || VN="$DEF_VER" + elif { + test -d "$SOURCE_DIR/.git" || + test -d "${GIT_DIR:-.git}" || + test -f "$SOURCE_DIR"/.git; + } && + VN=$(git -C "$SOURCE_DIR" describe --dirty --match="v[0-9]*" 2>/dev/null) && + case "$VN" in + *$LF*) (exit 1) ;; + esac + then + VN=$(echo "$VN" | sed -e 's/-/./g'); + else + VN="$DEF_VER" + fi + + GIT_VERSION=$(expr "$VN" : v*'\(.*\)') +fi + +if test -z "$GIT_BUILT_FROM_COMMIT" +then + GIT_BUILT_FROM_COMMIT=$(git -C "$SOURCE_DIR" rev-parse -q --verify HEAD 2>/dev/null) +fi + +if test -z "$GIT_DATE" +then + GIT_DATE=$(git -C "$SOURCE_DIR" show --quiet --format='%as' 2>/dev/null) fi -VN=$(expr "$VN" : v*'\(.*\)') +if test -z "$GIT_USER_AGENT" +then + GIT_USER_AGENT="git/$GIT_VERSION" +fi + +# While released Git versions only have three numbers, development builds also +# have a fourth number that corresponds to the number of patches since the last +# release. +read GIT_MAJOR_VERSION GIT_MINOR_VERSION GIT_MICRO_VERSION GIT_PATCH_LEVEL trailing <<EOF +$(echo "$GIT_VERSION" 0 0 0 0 | tr '.a-zA-Z-' ' ') +EOF + +REPLACED=$(printf "%s" "$INPUT" | sed -e "s|@GIT_VERSION@|$GIT_VERSION|" \ + -e "s|@GIT_MAJOR_VERSION@|$GIT_MAJOR_VERSION|" \ + -e "s|@GIT_MINOR_VERSION@|$GIT_MINOR_VERSION|" \ + -e "s|@GIT_MICRO_VERSION@|$GIT_MICRO_VERSION|" \ + -e "s|@GIT_PATCH_LEVEL@|$GIT_PATCH_LEVEL|" \ + -e "s|@GIT_BUILT_FROM_COMMIT@|$GIT_BUILT_FROM_COMMIT|" \ + -e "s|@GIT_USER_AGENT@|$GIT_USER_AGENT|" \ + -e "s|@GIT_DATE@|$GIT_DATE|" +) -if test -r $GVF +if test -z "$OUTPUT" then - VC=$(sed -e 's/^GIT_VERSION = //' <$GVF) + printf "%s\n" "$REPLACED" else - VC=unset + printf "%s\n" "$REPLACED" >"$OUTPUT".$$+ + if ! test -f "$OUTPUT" || ! cmp "$OUTPUT".$$+ "$OUTPUT" >/dev/null + then + mv "$OUTPUT".$$+ "$OUTPUT" + else + rm "$OUTPUT".$$+ + fi fi -test "$VN" = "$VC" || { - echo >&2 "GIT_VERSION = $VN" - echo "GIT_VERSION = $VN" >$GVF -} diff --git a/INSTALL b/INSTALL index 2a46d045928a11..54d7528f9e5f0d 100644 --- a/INSTALL +++ b/INSTALL @@ -119,7 +119,7 @@ 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.1 or later is needed to use some of the + - "Perl" version 5.26.0 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 @@ -129,17 +129,12 @@ Issues of note: itself, e.g. Digest::MD5, File::Spec, File::Temp, Net::Domain, Net::SMTP, and Time::HiRes. - - git-imap-send needs the OpenSSL library to talk IMAP over SSL if - you are using libcurl older than 7.34.0. Otherwise you can use - NO_OPENSSL without losing git-imap-send. - - "libcurl" library is used for fetching and pushing repositories over http:// or https://, as well as by - git-imap-send if the curl version is >= 7.34.0. If you do - not need that functionality, use NO_CURL to build without - it. + git-imap-send. If you do not need that functionality, + use NO_CURL to build without it. - Git requires version "7.21.3" or later of "libcurl" to build + Git requires version "7.61.0" or later of "libcurl" to build without NO_CURL. This version requirement may be bumped in the future. diff --git a/Makefile b/Makefile index 7344a7f7257af6..cb06c2dcc475d4 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,8 @@ include shared.mak # byte-order mark (BOM) when writing UTF-16 or UTF-32 and always writes in # big-endian format. # -# Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. +# Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. Define +# ZLIB_NG if you want to use zlib-ng instead of zlib. # # Define NO_NORETURN if using buggy versions of gcc 4.6+ and profile feedback, # as the compiler can crash (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49299) @@ -193,7 +194,7 @@ include shared.mak # Linux, kernel 2.6.11 or newer is required for reliable sub-second file times # on file systems with exactly 1 ns or 1 s resolution. If you intend to use Git # on other file systems (e.g. CEPH, CIFS, NTFS, UDF), don't enable USE_NSEC. See -# Documentation/technical/racy-git.txt for details. +# Documentation/technical/racy-git.adoc for details. # # Define USE_ST_TIMESPEC if your "struct stat" uses "st_ctimespec" instead of # "st_ctim" @@ -416,6 +417,9 @@ include shared.mak # Define LINK_FUZZ_PROGRAMS if you want `make all` to also build the fuzz test # programs in oss-fuzz/. # +# Define INCLUDE_LIBGIT_RS if you want `make all` and `make test` to build and +# test the Rust crates in contrib/libgit-sys and contrib/libgit-rs. +# # === Optional library: libintl === # # Define NO_GETTEXT if you don't want Git output to be translated. @@ -521,6 +525,10 @@ include shared.mak # Define APPLE_COMMON_CRYPTO_SHA1 to use Apple's CommonCrypto for # SHA-1. # +# Define the same Makefile knobs as above, but suffixed with _UNSAFE to +# use the corresponding implementations for unsafe SHA-1 hashing for +# non-cryptographic purposes. +# # If don't enable any of the *_SHA1 settings in this section, Git will # default to its built-in sha1collisiondetection library, which is a # collision-detecting sha1 This is slower, but may detect attempted @@ -587,10 +595,6 @@ include shared.mak # # Disable -pedantic compilation. -GIT-VERSION-FILE: FORCE - @$(SHELL_PATH) ./GIT-VERSION-GEN --include GIT-VERSION-FILE - # Set our default configuration. # # Among the variables below, these: @@ -657,6 +661,8 @@ CURL_CONFIG = curl-config GCOV = gcov STRIP = strip SPATCH = spatch +LD = ld +OBJCOPY = objcopy export TCL_PATH TCLTK_PATH @@ -675,6 +681,7 @@ FUZZ_OBJS = FUZZ_PROGRAMS = GIT_OBJS = LIB_OBJS = +LIBGIT_PUB_OBJS = SCALAR_OBJS = OBJECTS = OTHER_PROGRAMS = @@ -812,12 +819,14 @@ TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o TEST_BUILTINS_OBJS += test-match-trees.o TEST_BUILTINS_OBJS += test-mergesort.o TEST_BUILTINS_OBJS += test-mktemp.o +TEST_BUILTINS_OBJS += test-name-hash.o TEST_BUILTINS_OBJS += test-online-cpus.o TEST_BUILTINS_OBJS += test-pack-mtimes.o TEST_BUILTINS_OBJS += test-parse-options.o TEST_BUILTINS_OBJS += test-parse-pathspec-file.o TEST_BUILTINS_OBJS += test-partial-clone.o TEST_BUILTINS_OBJS += test-path-utils.o +TEST_BUILTINS_OBJS += test-path-walk.o TEST_BUILTINS_OBJS += test-pcre2-config.o TEST_BUILTINS_OBJS += test-pkt-line.o TEST_BUILTINS_OBJS += test-proc-receive.o @@ -981,10 +990,11 @@ LIB_OBJS += combine-diff.o LIB_OBJS += commit-graph.o LIB_OBJS += commit-reach.o LIB_OBJS += commit.o +LIB_OBJS += common-exit.o +LIB_OBJS += common-init.o LIB_OBJS += compat/nonblock.o LIB_OBJS += compat/obstack.o LIB_OBJS += compat/terminal.o -LIB_OBJS += compat/zlib-uncompress2.o LIB_OBJS += config.o LIB_OBJS += connect.o LIB_OBJS += connected.o @@ -1094,6 +1104,7 @@ LIB_OBJS += parse-options.o LIB_OBJS += patch-delta.o LIB_OBJS += patch-ids.o LIB_OBJS += path.o +LIB_OBJS += path-walk.o LIB_OBJS += pathspec.o LIB_OBJS += pkt-line.o LIB_OBJS += preload-index.o @@ -1201,6 +1212,7 @@ BUILTIN_OBJS += builtin/am.o BUILTIN_OBJS += builtin/annotate.o BUILTIN_OBJS += builtin/apply.o BUILTIN_OBJS += builtin/archive.o +BUILTIN_OBJS += builtin/backfill.o BUILTIN_OBJS += builtin/bisect.o BUILTIN_OBJS += builtin/blame.o BUILTIN_OBJS += builtin/branch.o @@ -1271,7 +1283,9 @@ BUILTIN_OBJS += builtin/mv.o BUILTIN_OBJS += builtin/name-rev.o BUILTIN_OBJS += builtin/notes.o BUILTIN_OBJS += builtin/pack-objects.o +ifndef WITH_BREAKING_CHANGES BUILTIN_OBJS += builtin/pack-redundant.o +endif BUILTIN_OBJS += builtin/pack-refs.o BUILTIN_OBJS += builtin/patch-id.o BUILTIN_OBJS += builtin/prune-packed.o @@ -1305,6 +1319,7 @@ BUILTIN_OBJS += builtin/sparse-checkout.o BUILTIN_OBJS += builtin/stash.o BUILTIN_OBJS += builtin/stripspace.o BUILTIN_OBJS += builtin/submodule--helper.o +BUILTIN_OBJS += builtin/survey.o BUILTIN_OBJS += builtin/symbolic-ref.o BUILTIN_OBJS += builtin/tag.o BUILTIN_OBJS += builtin/unpack-file.o @@ -1337,21 +1352,25 @@ THIRD_PARTY_SOURCES += sha1dc/% THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/% THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/% -CLAR_TEST_SUITES += ctype -CLAR_TEST_SUITES += strvec +CLAR_TEST_SUITES += u-ctype +CLAR_TEST_SUITES += u-example-decorate +CLAR_TEST_SUITES += u-hash +CLAR_TEST_SUITES += u-hashmap +CLAR_TEST_SUITES += u-mem-pool +CLAR_TEST_SUITES += u-oid-array +CLAR_TEST_SUITES += u-oidmap +CLAR_TEST_SUITES += u-oidtree +CLAR_TEST_SUITES += u-prio-queue +CLAR_TEST_SUITES += u-reftable-tree +CLAR_TEST_SUITES += u-strbuf +CLAR_TEST_SUITES += u-strcmp-offset +CLAR_TEST_SUITES += u-strvec CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X) CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES)) CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o +CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/lib-oid.o -UNIT_TEST_PROGRAMS += t-example-decorate -UNIT_TEST_PROGRAMS += t-hash -UNIT_TEST_PROGRAMS += t-hashmap -UNIT_TEST_PROGRAMS += t-mem-pool -UNIT_TEST_PROGRAMS += t-oid-array -UNIT_TEST_PROGRAMS += t-oidmap -UNIT_TEST_PROGRAMS += t-oidtree -UNIT_TEST_PROGRAMS += t-prio-queue UNIT_TEST_PROGRAMS += t-reftable-basics UNIT_TEST_PROGRAMS += t-reftable-block UNIT_TEST_PROGRAMS += t-reftable-merged @@ -1360,14 +1379,10 @@ UNIT_TEST_PROGRAMS += t-reftable-reader UNIT_TEST_PROGRAMS += t-reftable-readwrite UNIT_TEST_PROGRAMS += t-reftable-record UNIT_TEST_PROGRAMS += t-reftable-stack -UNIT_TEST_PROGRAMS += t-reftable-tree -UNIT_TEST_PROGRAMS += t-strbuf -UNIT_TEST_PROGRAMS += t-strcmp-offset UNIT_TEST_PROGRAMS += t-trailer UNIT_TEST_PROGRAMS += t-urlmatch-normalization UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS)) UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o -UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-oid.o UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-reftable.o # xdiff and reftable libs may in turn depend on what is in libgit.a @@ -1458,6 +1473,18 @@ ifdef DEVELOPER include config.mak.dev endif +GIT-VERSION-FILE: FORCE + @OLD=$$(cat $@ 2>/dev/null || :) && \ + $(call version_gen,"$(shell pwd)",GIT-VERSION-FILE.in,$@) && \ + NEW=$$(cat $@ 2>/dev/null || :) && \ + if test "$$OLD" != "$$NEW"; then echo "$$NEW" >&2; fi + +# We need to set GIT_VERSION_OVERRIDE before including the version file as +# otherwise any user-provided value for GIT_VERSION would have been overridden +# already. +GIT_VERSION_OVERRIDE := $(GIT_VERSION) +-include GIT-VERSION-FILE + # what 'all' will build and 'install' will install in gitexecdir, # excluding programs for built-in commands ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) @@ -1483,7 +1510,6 @@ ifneq ($(filter undefined,$(SANITIZERS)),) BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS endif ifneq ($(filter leak,$(SANITIZERS)),) -BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS BASIC_CFLAGS += -O0 SANITIZE_LEAK = YesCompiledWithIt endif @@ -1551,10 +1577,10 @@ endif ifdef SANE_TOOL_PATH SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH)) -BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix "$(SANE_TOOL_PATH_SQ)"|' +BROKEN_PATH_FIX = s|^\# @BROKEN_PATH_FIX@$$|git_broken_path_fix "$(SANE_TOOL_PATH_SQ)"| PATH := $(SANE_TOOL_PATH):${PATH} else -BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d' +BROKEN_PATH_FIX = /^\# @BROKEN_PATH_FIX@$$/d endif ifeq (,$(HOST_CPU)) @@ -1677,11 +1703,20 @@ else endif IMAP_SEND_LDFLAGS += $(OPENSSL_LINK) $(OPENSSL_LIBSSL) $(LIB_4_CRYPTO) -ifdef ZLIB_PATH - BASIC_CFLAGS += -I$(ZLIB_PATH)/include - EXTLIBS += $(call libpath_template,$(ZLIB_PATH)/$(lib)) +ifdef ZLIB_NG + BASIC_CFLAGS += -DHAVE_ZLIB_NG + ifdef ZLIB_NG_PATH + BASIC_CFLAGS += -I$(ZLIB_NG_PATH)/include + EXTLIBS += $(call libpath_template,$(ZLIB_NG_PATH)/$(lib)) + endif + EXTLIBS += -lz-ng +else + ifdef ZLIB_PATH + BASIC_CFLAGS += -I$(ZLIB_PATH)/include + EXTLIBS += $(call libpath_template,$(ZLIB_PATH)/$(lib)) + endif + EXTLIBS += -lz endif -EXTLIBS += -lz ifndef NO_OPENSSL OPENSSL_LIBSSL = -lssl @@ -1997,6 +2032,27 @@ endif endif endif +ifdef OPENSSL_SHA1_UNSAFE +ifndef OPENSSL_SHA1 + EXTLIBS += $(LIB_4_CRYPTO) + BASIC_CFLAGS += -DSHA1_OPENSSL_UNSAFE +endif +else +ifdef BLK_SHA1_UNSAFE +ifndef BLK_SHA1 + LIB_OBJS += block-sha1/sha1.o + BASIC_CFLAGS += -DSHA1_BLK_UNSAFE +endif +else +ifdef APPLE_COMMON_CRYPTO_SHA1_UNSAFE +ifndef APPLE_COMMON_CRYPTO_SHA1 + COMPAT_CFLAGS += -DCOMMON_DIGEST_FOR_OPENSSL + BASIC_CFLAGS += -DSHA1_APPLE_UNSAFE +endif +endif +endif +endif + ifdef OPENSSL_SHA256 EXTLIBS += $(LIB_4_CRYPTO) BASIC_CFLAGS += -DSHA256_OPENSSL @@ -2202,6 +2258,16 @@ ifdef FSMONITOR_OS_SETTINGS COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o endif +ifdef WITH_BREAKING_CHANGES + BASIC_CFLAGS += -DWITH_BREAKING_CHANGES +endif + +ifdef INCLUDE_LIBGIT_RS + # Enable symbol hiding in contrib/libgit-sys/libgitpub.a without making + # us rebuild the whole tree every time we run a Rust build. + BASIC_CFLAGS += -fvisibility=hidden +endif + ifeq ($(TCLTK_PATH),) NO_TCLTK = NoThanks endif @@ -2397,9 +2463,12 @@ endif FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o FUZZ_OBJS += oss-fuzz/fuzz-config.o +FUZZ_OBJS += oss-fuzz/fuzz-credential-from-url-gently.o FUZZ_OBJS += oss-fuzz/fuzz-date.o FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o +FUZZ_OBJS += oss-fuzz/fuzz-parse-attr-line.o +FUZZ_OBJS += oss-fuzz/fuzz-url-decode-mem.o .PHONY: fuzz-objs fuzz-objs: $(FUZZ_OBJS) @@ -2480,13 +2549,10 @@ PAGER_ENV_CQ_SQ = $(subst ','\'',$(PAGER_ENV_CQ)) pager.sp pager.s pager.o: EXTRA_CPPFLAGS = \ -DPAGER_ENV='$(PAGER_ENV_CQ_SQ)' -version.sp version.s version.o: GIT-VERSION-FILE GIT-USER-AGENT -version.sp version.s version.o: EXTRA_CPPFLAGS = \ - '-DGIT_VERSION="$(GIT_VERSION)"' \ - '-DGIT_USER_AGENT=$(GIT_USER_AGENT_CQ_SQ)' \ - '-DGIT_BUILT_FROM_COMMIT="$(shell \ - GIT_CEILING_DIRECTORIES="$(CURDIR)/.." \ - git rev-parse -q --verify HEAD 2>/dev/null)"' +version-def.h: version-def.h.in GIT-VERSION-GEN GIT-VERSION-FILE GIT-USER-AGENT + $(QUIET_GEN)$(call version_gen,"$(shell pwd)",$<,$@) + +version.sp version.s version.o: version-def.h $(BUILT_INS): git$X $(QUIET_BUILT_IN)$(RM) $@ && \ @@ -2496,18 +2562,18 @@ $(BUILT_INS): git$X config-list.h: generate-configlist.sh -config-list.h: Documentation/*config.txt Documentation/config/*.txt - $(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh >$@ +config-list.h: Documentation/*config.adoc Documentation/config/*.adoc + $(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh . $@ command-list.h: generate-cmdlist.sh command-list.txt -command-list.h: $(wildcard Documentation/git*.txt) +command-list.h: $(wildcard Documentation/git*.adoc) $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh \ $(patsubst %,--exclude-program %,$(EXCLUDED_PROGRAMS)) \ - command-list.txt >$@ + . $@ -hook-list.h: generate-hooklist.sh Documentation/githooks.txt - $(QUIET_GEN)$(SHELL_PATH) ./generate-hooklist.sh >$@ +hook-list.h: generate-hooklist.sh Documentation/githooks.adoc + $(QUIET_GEN)$(SHELL_PATH) ./generate-hooklist.sh . $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\ $(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\ @@ -2520,33 +2586,15 @@ GIT-SCRIPT-DEFINES: FORCE echo "$$FLAGS" >$@; \ fi -define cmd_munge_script -sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ - -e 's|@@DIFF@@|$(DIFF_SQ)|' \ - -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \ - -e 's/@@USE_GETTEXT_SCHEME@@/$(USE_GETTEXT_SCHEME)/g' \ - -e $(BROKEN_PATH_FIX) \ - -e 's|@@GITWEBDIR@@|$(gitwebdir_SQ)|g' \ - -e 's|@@PERL@@|$(PERL_PATH_SQ)|g' \ - -e 's|@@PAGER_ENV@@|$(PAGER_ENV_SQ)|g' \ - $@.sh >$@+ -endef - -$(SCRIPT_SH_GEN) : % : %.sh GIT-SCRIPT-DEFINES - $(QUIET_GEN)$(cmd_munge_script) && \ - chmod +x $@+ && \ +$(SCRIPT_SH_GEN) $(SCRIPT_LIB) : % : %.sh generate-script.sh GIT-BUILD-OPTIONS GIT-SCRIPT-DEFINES + $(QUIET_GEN)./generate-script.sh "$<" "$@+" ./GIT-BUILD-OPTIONS && \ mv $@+ $@ -$(SCRIPT_LIB) : % : %.sh GIT-SCRIPT-DEFINES - $(QUIET_GEN)$(cmd_munge_script) && \ - mv $@+ $@ +git.rc: git.rc.in GIT-VERSION-GEN GIT-VERSION-FILE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)",$<,$@) -git.res: git.rc GIT-VERSION-FILE GIT-PREFIX - $(QUIET_RC)$(RC) \ - $(join -DMAJOR= -DMINOR= -DMICRO= -DPATCHLEVEL=, $(wordlist 1, 4, \ - $(shell echo $(GIT_VERSION) 0 0 0 0 | tr '.a-zA-Z-' ' '))) \ - -DGIT_VERSION="\\\"$(GIT_VERSION)\\\"" -i $< -o $@ +git.res: git.rc GIT-PREFIX + $(QUIET_RC)$(RC) -i $< -o $@ # This makes sure we depend on the NO_PERL setting itself. $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS @@ -2579,16 +2627,8 @@ endif PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir) -$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE - $(QUIET_GEN) \ - sed -e '1{' \ - -e ' s|#!.*perl|#!$(PERL_PATH_SQ)|' \ - -e ' r GIT-PERL-HEADER' \ - -e ' G' \ - -e '}' \ - -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ - $< >$@+ && \ - chmod +x $@+ && \ +$(SCRIPT_PERL_GEN): % : %.perl generate-perl.sh GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE + $(QUIET_GEN)$(SHELL_PATH) generate-perl.sh ./GIT-BUILD-OPTIONS ./GIT-VERSION-FILE GIT-PERL-HEADER "$<" "$@+" && \ mv $@+ $@ PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES)) @@ -2604,11 +2644,11 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile INSTLIBDIR='$(perllibdir_SQ)' && \ INSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \ INSTLIBDIR="$$INSTLIBDIR$${INSTLIBDIR_EXTRA:+:$$INSTLIBDIR_EXTRA}" && \ - sed -e 's=@@PATHSEP@@=$(pathsep)=g' \ - -e "s=@@INSTLIBDIR@@=$$INSTLIBDIR=g" \ - -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \ - -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \ - -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \ + sed -e 's=@PATHSEP@=$(pathsep)=g' \ + -e "s=@INSTLIBDIR@=$$INSTLIBDIR=g" \ + -e 's=@PERLLIBDIR_REL@=$(perllibdir_relative_SQ)=g' \ + -e 's=@GITEXECDIR_REL@=$(gitexecdir_relative_SQ)=g' \ + -e 's=@LOCALEDIR_REL@=$(localedir_relative_SQ)=g' \ $< >$@+ && \ mv $@+ $@ @@ -2616,15 +2656,15 @@ GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile perllibdir: @echo '$(perllibdir_SQ)' -git-instaweb: git-instaweb.sh GIT-SCRIPT-DEFINES - $(QUIET_GEN)$(cmd_munge_script) && \ +git-instaweb: git-instaweb.sh generate-script.sh GIT-BUILD-OPTIONS GIT-SCRIPT-DEFINES + $(QUIET_GEN)./generate-script.sh "$<" "$@+" ./GIT-BUILD-OPTIONS && \ chmod +x $@+ && \ mv $@+ $@ else # NO_PERL $(SCRIPT_PERL_GEN) git-instaweb: % : unimplemented.sh $(QUIET_GEN) \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's|@@REASON@@|NO_PERL=$(NO_PERL)|g' \ + -e 's|@REASON@|NO_PERL=$(NO_PERL)|g' \ unimplemented.sh >$@+ && \ chmod +x $@+ && \ mv $@+ $@ @@ -2634,24 +2674,20 @@ endif # NO_PERL $(SCRIPT_PYTHON_GEN): GIT-BUILD-OPTIONS ifndef NO_PYTHON -$(SCRIPT_PYTHON_GEN): GIT-CFLAGS GIT-PREFIX GIT-PYTHON-VARS +$(SCRIPT_PYTHON_GEN): generate-python.sh $(SCRIPT_PYTHON_GEN): % : %.py - $(QUIET_GEN) \ - sed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \ - $< >$@+ && \ - chmod +x $@+ && \ - mv $@+ $@ + $(QUIET_GEN)$(SHELL_PATH) generate-python.sh ./GIT-BUILD-OPTIONS "$<" "$@" else # NO_PYTHON $(SCRIPT_PYTHON_GEN): % : unimplemented.sh $(QUIET_GEN) \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's|@@REASON@@|NO_PYTHON=$(NO_PYTHON)|g' \ + -e 's|@REASON@|NO_PYTHON=$(NO_PYTHON)|g' \ unimplemented.sh >$@+ && \ chmod +x $@+ && \ mv $@+ $@ endif # NO_PYTHON -CONFIGURE_RECIPE = sed -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \ +CONFIGURE_RECIPE = sed -e 's/@GIT_VERSION@/$(GIT_VERSION)/g' \ configure.ac >configure.ac+ && \ autoconf -o configure configure.ac+ && \ $(RM) configure.ac+ @@ -2692,12 +2728,12 @@ REFTABLE_OBJS += reftable/error.o REFTABLE_OBJS += reftable/block.o REFTABLE_OBJS += reftable/blocksource.o REFTABLE_OBJS += reftable/iter.o -REFTABLE_OBJS += reftable/publicbasics.o REFTABLE_OBJS += reftable/merged.o REFTABLE_OBJS += reftable/pq.o REFTABLE_OBJS += reftable/reader.o REFTABLE_OBJS += reftable/record.o REFTABLE_OBJS += reftable/stack.o +REFTABLE_OBJS += reftable/system.o REFTABLE_OBJS += reftable/tree.o REFTABLE_OBJS += reftable/writer.o @@ -2728,6 +2764,10 @@ OBJECTS += $(UNIT_TEST_OBJS) OBJECTS += $(CLAR_TEST_OBJS) OBJECTS += $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS)) +ifdef INCLUDE_LIBGIT_RS + OBJECTS += contrib/libgit-sys/public_symbol_export.o +endif + ifndef NO_CURL OBJECTS += http.o http-walker.o remote-curl.o endif @@ -3077,13 +3117,9 @@ endif NO_PERL_CPAN_FALLBACKS_SQ = $(subst ','\'',$(NO_PERL_CPAN_FALLBACKS)) endif -perl/build/lib/%.pm: perl/%.pm GIT-PERL-DEFINES +perl/build/lib/%.pm: perl/%.pm generate-perl.sh GIT-BUILD-OPTIONS GIT-VERSION-FILE GIT-PERL-DEFINES $(call mkdir_p_parent_template) - $(QUIET_GEN) \ - sed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \ - -e 's|@@NO_GETTEXT@@|$(NO_GETTEXT_SQ)|g' \ - -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \ - < $< > $@ + $(QUIET_GEN)$(SHELL_PATH) generate-perl.sh ./GIT-BUILD-OPTIONS ./GIT-VERSION-FILE GIT-PERL-HEADER "$<" "$@" perl/build/man/man3/Git.3pm: perl/Git.pm $(call mkdir_p_parent_template) @@ -3136,79 +3172,67 @@ GIT-LDFLAGS: FORCE echo "$$FLAGS" >GIT-LDFLAGS; \ fi +ifdef RUNTIME_PREFIX +RUNTIME_PREFIX_OPTION = true +else +RUNTIME_PREFIX_OPTION = false +endif + # We need to apply sq twice, once to protect from the shell # that runs GIT-BUILD-OPTIONS, and then again to protect it # and the first level quoting from the shell that runs "echo". GIT-BUILD-OPTIONS: FORCE - @echo SHELL_PATH=\''$(subst ','\'',$(SHELL_PATH_SQ))'\' >$@+ - @echo TEST_SHELL_PATH=\''$(subst ','\'',$(TEST_SHELL_PATH_SQ))'\' >>$@+ - @echo PERL_PATH=\''$(subst ','\'',$(PERL_PATH_SQ))'\' >>$@+ - @echo DIFF=\''$(subst ','\'',$(subst ','\'',$(DIFF)))'\' >>$@+ - @echo PYTHON_PATH=\''$(subst ','\'',$(PYTHON_PATH_SQ))'\' >>$@+ - @echo TAR=\''$(subst ','\'',$(subst ','\'',$(TAR)))'\' >>$@+ - @echo NO_CURL=\''$(subst ','\'',$(subst ','\'',$(NO_CURL)))'\' >>$@+ - @echo NO_EXPAT=\''$(subst ','\'',$(subst ','\'',$(NO_EXPAT)))'\' >>$@+ - @echo USE_LIBPCRE2=\''$(subst ','\'',$(subst ','\'',$(USE_LIBPCRE2)))'\' >>$@+ - @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@+ - @echo NO_PTHREADS=\''$(subst ','\'',$(subst ','\'',$(NO_PTHREADS)))'\' >>$@+ - @echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@+ - @echo NO_REGEX=\''$(subst ','\'',$(subst ','\'',$(NO_REGEX)))'\' >>$@+ - @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+ - @echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+ - @echo SANITIZE_LEAK=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_LEAK)))'\' >>$@+ - @echo SANITIZE_ADDRESS=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_ADDRESS)))'\' >>$@+ - @echo X=\'$(X)\' >>$@+ -ifdef FSMONITOR_DAEMON_BACKEND - @echo FSMONITOR_DAEMON_BACKEND=\''$(subst ','\'',$(subst ','\'',$(FSMONITOR_DAEMON_BACKEND)))'\' >>$@+ -endif -ifdef FSMONITOR_OS_SETTINGS - @echo FSMONITOR_OS_SETTINGS=\''$(subst ','\'',$(subst ','\'',$(FSMONITOR_OS_SETTINGS)))'\' >>$@+ -endif -ifdef TEST_OUTPUT_DIRECTORY - @echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+ -endif -ifdef GIT_TEST_OPTS - @echo GIT_TEST_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_OPTS)))'\' >>$@+ -endif -ifdef GIT_TEST_CMP - @echo GIT_TEST_CMP=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_CMP)))'\' >>$@+ -endif -ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT - @echo GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease >>$@+ -endif -ifdef GIT_TEST_UTF8_LOCALE - @echo GIT_TEST_UTF8_LOCALE=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_UTF8_LOCALE)))'\' >>$@+ -endif - @echo NO_GETTEXT=\''$(subst ','\'',$(subst ','\'',$(NO_GETTEXT)))'\' >>$@+ -ifdef GIT_PERF_REPEAT_COUNT - @echo GIT_PERF_REPEAT_COUNT=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPEAT_COUNT)))'\' >>$@+ -endif -ifdef GIT_PERF_REPO - @echo GIT_PERF_REPO=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_REPO)))'\' >>$@+ -endif -ifdef GIT_PERF_LARGE_REPO - @echo GIT_PERF_LARGE_REPO=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_LARGE_REPO)))'\' >>$@+ -endif -ifdef GIT_PERF_MAKE_OPTS - @echo GIT_PERF_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_OPTS)))'\' >>$@+ -endif -ifdef GIT_PERF_MAKE_COMMAND - @echo GIT_PERF_MAKE_COMMAND=\''$(subst ','\'',$(subst ','\'',$(GIT_PERF_MAKE_COMMAND)))'\' >>$@+ -endif -ifdef GIT_INTEROP_MAKE_OPTS - @echo GIT_INTEROP_MAKE_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_INTEROP_MAKE_OPTS)))'\' >>$@+ -endif -ifdef GIT_TEST_INDEX_VERSION - @echo GIT_TEST_INDEX_VERSION=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_INDEX_VERSION)))'\' >>$@+ -endif -ifdef GIT_TEST_PERL_FATAL_WARNINGS - @echo GIT_TEST_PERL_FATAL_WARNINGS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_PERL_FATAL_WARNINGS)))'\' >>$@+ -endif -ifdef RUNTIME_PREFIX - @echo RUNTIME_PREFIX=\'true\' >>$@+ -else - @echo RUNTIME_PREFIX=\'false\' >>$@+ -endif + @sed \ + -e "s!@BROKEN_PATH_FIX@!\'$(BROKEN_PATH_FIX)\'!" \ + -e "s|@DIFF@|\'$(DIFF)\'|" \ + -e "s|@FSMONITOR_DAEMON_BACKEND@|\'$(FSMONITOR_DAEMON_BACKEND)\'|" \ + -e "s|@FSMONITOR_OS_SETTINGS@|\'$(FSMONITOR_OS_SETTINGS)\'|" \ + -e "s|@GITWEBDIR@|\'$(gitwebdir_SQ)\'|" \ + -e "s|@GIT_INTEROP_MAKE_OPTS@|\'$(GIT_INTEROP_MAKE_OPTS)\'|" \ + -e "s|@GIT_PERF_LARGE_REPO@|\'$(GIT_PERF_LARGE_REPO)\'|" \ + -e "s|@GIT_PERF_MAKE_COMMAND@|\'$(GIT_PERF_MAKE_COMMAND)\'|" \ + -e "s|@GIT_PERF_MAKE_OPTS@|\'$(GIT_PERF_MAKE_OPTS)\'|" \ + -e "s|@GIT_PERF_REPEAT_COUNT@|\'$(GIT_PERF_REPEAT_COUNT)\'|" \ + -e "s|@GIT_PERF_REPO@|\'$(GIT_PERF_REPO)\'|" \ + -e "s|@GIT_SOURCE_DIR@|\'$(shell pwd)\'|" \ + -e "s|@GIT_TEST_CMP@|\'$(GIT_TEST_CMP)\'|" \ + -e "s|@GIT_TEST_CMP_USE_COPIED_CONTEXT@|\'$(GIT_TEST_CMP_USE_COPIED_CONTEXT)\'|" \ + -e "s|@GIT_TEST_GITPERLLIB@|\'$(shell pwd)/perl/build/lib\'|" \ + -e "s|@GIT_TEST_INDEX_VERSION@|\'$(GIT_TEST_INDEX_VERSION)\'|" \ + -e "s|@GIT_TEST_OPTS@|\'$(GIT_TEST_OPTS)\'|" \ + -e "s|@GIT_TEST_PERL_FATAL_WARNINGS@|\'$(GIT_TEST_PERL_FATAL_WARNINGS)\'|" \ + -e "s|@GIT_TEST_TEMPLATE_DIR@|\'$(shell pwd)/templates/blt\'|" \ + -e "s|@GIT_TEST_TEXTDOMAINDIR@|\'$(shell pwd)/po/build/locale\'|" \ + -e "s|@GIT_TEST_UTF8_LOCALE@|\'$(GIT_TEST_UTF8_LOCALE)\'|" \ + -e "s|@LOCALEDIR@|\'$(localedir_SQ)\'|" \ + -e "s|@NO_CURL@|\'$(NO_CURL)\'|" \ + -e "s|@NO_EXPAT@|\'$(NO_EXPAT)\'|" \ + -e "s|@NO_GETTEXT@|\'$(NO_GETTEXT)\'|" \ + -e "s|@NO_GITWEB@|\'$(NO_GITWEB)\'|" \ + -e "s|@NO_ICONV@|\'$(NO_ICONV)\'|" \ + -e "s|@NO_PERL@|\'$(NO_PERL)\'|" \ + -e "s|@NO_PERL_CPAN_FALLBACKS@|\'$(NO_PERL_CPAN_FALLBACKS_SQ)\'|" \ + -e "s|@NO_PTHREADS@|\'$(NO_PTHREADS)\'|" \ + -e "s|@NO_PYTHON@|\'$(NO_PYTHON)\'|" \ + -e "s|@NO_REGEX@|\'$(NO_REGEX)\'|" \ + -e "s|@NO_UNIX_SOCKETS@|\'$(NO_UNIX_SOCKETS)\'|" \ + -e "s|@PAGER_ENV@|\'$(PAGER_ENV)\'|" \ + -e "s|@PERL_LOCALEDIR@|\'$(perl_localedir_SQ)\'|" \ + -e "s|@PERL_PATH@|\'$(PERL_PATH_SQ)\'|" \ + -e "s|@PYTHON_PATH@|\'$(PYTHON_PATH_SQ)\'|" \ + -e "s|@RUNTIME_PREFIX@|\'$(RUNTIME_PREFIX_OPTION)\'|" \ + -e "s|@SANITIZE_ADDRESS@|\'$(SANITIZE_ADDRESS)\'|" \ + -e "s|@SANITIZE_LEAK@|\'$(SANITIZE_LEAK)\'|" \ + -e "s|@SHELL_PATH@|\'$(SHELL_PATH_SQ)\'|" \ + -e "s|@TAR@|\'$(TAR)\'|" \ + -e "s|@TEST_OUTPUT_DIRECTORY@|\'$(TEST_OUTPUT_DIRECTORY)\'|" \ + -e "s|@TEST_SHELL_PATH@|\'$(TEST_SHELL_PATH_SQ)\'|" \ + -e "s|@USE_GETTEXT_SCHEME@|\'$(USE_GETTEXT_SCHEME)\'|" \ + -e "s|@USE_LIBPCRE2@|\'$(USE_LIBPCRE2)\'|" \ + -e "s|@WITH_BREAKING_CHANGES@|\'$(WITH_BREAKING_CHANGES)\'|" \ + -e "s|@X@|\'$(X)\'|" \ + GIT-BUILD-OPTIONS.in >$@+ + @if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi @if test -f GIT-BUILD-DIR; then rm GIT-BUILD-DIR; fi @@ -3228,11 +3252,14 @@ test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $( all:: $(TEST_PROGRAMS) $(test_bindir_programs) $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) -bin-wrappers/%: wrap-for-bin.sh - $(call mkdir_p_parent_template) +$(test_bindir_programs): bin-wrappers/%: bin-wrappers/wrap-for-bin.sh $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ - -e 's|@@BUILD_DIR@@|$(shell pwd)|' \ - -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))$(if $(filter-out $(BINDIR_PROGRAMS_NO_X),$(@F)),$(X),)|' < $< > $@ && \ + -e 's|@BUILD_DIR@|$(shell pwd)|' \ + -e 's|@GIT_TEXTDOMAINDIR@|$(shell pwd)/po/build/locale|' \ + -e 's|@GITPERLLIB@|$(shell pwd)/perl/build/lib|' \ + -e 's|@MERGE_TOOLS_DIR@|$(shell pwd)/mergetools|' \ + -e 's|@TEMPLATE_DIR@|$(shell pwd)/templates/blt|' \ + -e 's|@PROG@|$(shell pwd)/$(patsubst test-%,t/helper/test-%,$(@F))$(if $(filter-out $(BINDIR_PROGRAMS_NO_X),$(@F)),$(X),)|' < $< > $@ && \ chmod +x $@ # GNU make supports exporting all variables by "export" without parameters. @@ -3716,7 +3743,7 @@ clean: profile-clean coverage-clean cocciclean $(RM) -r .build $(UNIT_TEST_BIN) $(RM) GIT-TEST-SUITES $(RM) po/git.pot po/git-core.pot - $(RM) git.res + $(RM) git.rc git.res $(RM) $(OBJECTS) $(RM) headless-git.o $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) @@ -3725,7 +3752,9 @@ clean: profile-clean coverage-clean cocciclean $(RM) $(FUZZ_PROGRAMS) $(RM) $(SP_OBJ) $(RM) $(HCC) - $(RM) -r bin-wrappers $(dep_dirs) $(compdb_dir) compile_commands.json + $(RM) version-def.h + $(RM) -r $(dep_dirs) $(compdb_dir) compile_commands.json + $(RM) $(test_bindir_programs) $(RM) -r po/build/ $(RM) *.pyc *.pyo */*.pyc */*.pyo $(GENERATED_H) $(ETAGS_TARGET) tags cscope* $(RM) -r .dist-tmp-dir .doc-tmp-dir @@ -3733,6 +3762,10 @@ clean: profile-clean coverage-clean cocciclean $(RM) $(htmldocs).tar.gz $(manpages).tar.gz $(MAKE) -C Documentation/ clean $(RM) Documentation/GIT-EXCLUDED-PROGRAMS + $(RM) -r contrib/libgit-sys/target contrib/libgit-rs/target + $(RM) contrib/libgit-sys/partial_symbol_export.o + $(RM) contrib/libgit-sys/hidden_symbol_export.o + $(RM) contrib/libgit-sys/libgitpub.a ifndef NO_PERL $(RM) -r perl/build/ endif @@ -3879,12 +3912,11 @@ GIT-TEST-SUITES: FORCE echo "$$FLAGS" >GIT-TEST-SUITES; \ fi -$(UNIT_TEST_DIR)/clar-decls.h: $(patsubst %,$(UNIT_TEST_DIR)/%.c,$(CLAR_TEST_SUITES)) GIT-TEST-SUITES - $(QUIET_GEN)for suite in $(CLAR_TEST_SUITES); do \ - sed -ne "s/^\(void test_$${suite}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)$$\)/extern \1;/p" $(UNIT_TEST_DIR)/$$suite.c; \ - done >$@ -$(UNIT_TEST_DIR)/clar.suite: $(UNIT_TEST_DIR)/clar-decls.h - $(QUIET_GEN)awk -f $(UNIT_TEST_DIR)/clar-generate.awk $< >$(UNIT_TEST_DIR)/clar.suite +$(UNIT_TEST_DIR)/clar-decls.h: $(patsubst %,$(UNIT_TEST_DIR)/%.c,$(CLAR_TEST_SUITES)) $(UNIT_TEST_DIR)/generate-clar-decls.sh GIT-TEST-SUITES + $(QUIET_GEN)$(SHELL_PATH) $(UNIT_TEST_DIR)/generate-clar-decls.sh "$@" $(filter %.c,$^) +$(UNIT_TEST_DIR)/clar.suite: $(UNIT_TEST_DIR)/clar-decls.h $(UNIT_TEST_DIR)/generate-clar-suites.sh + $(QUIET_GEN)$(SHELL_PATH) $(UNIT_TEST_DIR)/generate-clar-suites.sh $< $(UNIT_TEST_DIR)/clar.suite +$(UNIT_TEST_DIR)/clar/clar.o: $(UNIT_TEST_DIR)/clar.suite $(CLAR_TEST_OBJS): $(UNIT_TEST_DIR)/clar-decls.h $(CLAR_TEST_OBJS): EXTRA_CPPFLAGS = -I$(UNIT_TEST_DIR) $(CLAR_TEST_PROG): $(UNIT_TEST_DIR)/clar.suite $(CLAR_TEST_OBJS) $(GITLIBS) GIT-LDFLAGS @@ -3895,3 +3927,31 @@ $(CLAR_TEST_PROG): $(UNIT_TEST_DIR)/clar.suite $(CLAR_TEST_OBJS) $(GITLIBS) GIT- build-unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X $(MAKE) -C t/ unit-tests + +.PHONY: libgit-sys libgit-rs +libgit-sys libgit-rs: + $(QUIET)(\ + cd contrib/$@ && \ + cargo build \ + ) +ifdef INCLUDE_LIBGIT_RS +all:: libgit-sys libgit-rs +endif + +LIBGIT_PUB_OBJS += contrib/libgit-sys/public_symbol_export.o +LIBGIT_PUB_OBJS += libgit.a +LIBGIT_PUB_OBJS += reftable/libreftable.a +LIBGIT_PUB_OBJS += xdiff/lib.a + +LIBGIT_PARTIAL_EXPORT = contrib/libgit-sys/partial_symbol_export.o + +LIBGIT_HIDDEN_EXPORT = contrib/libgit-sys/hidden_symbol_export.o + +$(LIBGIT_PARTIAL_EXPORT): $(LIBGIT_PUB_OBJS) + $(LD) -r $^ -o $@ + +$(LIBGIT_HIDDEN_EXPORT): $(LIBGIT_PARTIAL_EXPORT) + $(OBJCOPY) --localize-hidden $^ $@ + +contrib/libgit-sys/libgitpub.a: $(LIBGIT_HIDDEN_EXPORT) + $(AR) $(ARFLAGS) $@ $^ diff --git a/README.md b/README.md index 665ce5f5a83647..d87bca1b8c3ebf 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,15 @@ Please read the file [INSTALL][] for installation instructions. Many Git online resources are accessible from <https://git-scm.com/> including full documentation and Git related tools. -See [Documentation/gittutorial.txt][] to get started, then see -[Documentation/giteveryday.txt][] for a useful minimum set of commands, and -`Documentation/git-<commandname>.txt` for documentation of each command. +See [Documentation/gittutorial.adoc][] to get started, then see +[Documentation/giteveryday.adoc][] for a useful minimum set of commands, and +`Documentation/git-<commandname>.adoc` for documentation of each command. If git has been correctly installed, then the tutorial can also be read with `man gittutorial` or `git help tutorial`, and the documentation of each command with `man git-<commandname>` or `git help <commandname>`. -CVS users may also want to read [Documentation/gitcvs-migration.txt][] +CVS users may also want to read [Documentation/gitcvs-migration.adoc][] (`man gitcvs-migration` or `git help cvs-migration` if git is installed). @@ -66,9 +66,9 @@ and the name as (depending on your mood): - "goddamn idiotic truckload of sh*t": when it breaks [INSTALL]: INSTALL -[Documentation/gittutorial.txt]: Documentation/gittutorial.txt -[Documentation/giteveryday.txt]: Documentation/giteveryday.txt -[Documentation/gitcvs-migration.txt]: Documentation/gitcvs-migration.txt +[Documentation/gittutorial.adoc]: Documentation/gittutorial.adoc +[Documentation/giteveryday.adoc]: Documentation/giteveryday.adoc +[Documentation/gitcvs-migration.adoc]: Documentation/gitcvs-migration.adoc [Documentation/SubmittingPatches]: Documentation/SubmittingPatches [Documentation/CodingGuidelines]: Documentation/CodingGuidelines [po/README.md]: po/README.md diff --git a/RelNotes b/RelNotes index 0104513a31630e..ac72bdf04d129d 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.47.0.txt \ No newline at end of file +Documentation/RelNotes/2.49.0.adoc \ No newline at end of file diff --git a/add-interactive.c b/add-interactive.c index 49042b30261cc5..97ff35b6f12a32 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "add-interactive.h" @@ -71,14 +71,14 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) s->use_color ? GIT_COLOR_RESET : "", COLOR_MAXLEN); FREE_AND_NULL(s->interactive_diff_filter); - git_config_get_string("interactive.difffilter", - &s->interactive_diff_filter); + repo_config_get_string(r, "interactive.difffilter", + &s->interactive_diff_filter); FREE_AND_NULL(s->interactive_diff_algorithm); - git_config_get_string("diff.algorithm", - &s->interactive_diff_algorithm); + repo_config_get_string(r, "diff.algorithm", + &s->interactive_diff_algorithm); - git_config_get_bool("interactive.singlekey", &s->use_single_key); + repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key); if (s->use_single_key) setbuf(stdin, NULL); } @@ -534,7 +534,7 @@ static int get_modified_files(struct repository *r, size_t *binary_count) { struct object_id head_oid; - int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(r), "HEAD", RESOLVE_REF_READING, &head_oid, NULL); struct collection_status s = { 0 }; @@ -559,7 +559,7 @@ static int get_modified_files(struct repository *r, s.skip_unseen = filter && i; opt.def = is_initial ? - empty_tree_oid_hex(the_repository->hash_algo) : oid_to_hex(&head_oid); + empty_tree_oid_hex(r->hash_algo) : oid_to_hex(&head_oid); repo_init_revisions(r, &rev, NULL); setup_revisions(0, NULL, &rev, &opt); @@ -764,7 +764,7 @@ static int run_revert(struct add_i_state *s, const struct pathspec *ps, size_t count, i, j; struct object_id oid; - int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(s->r), "HEAD", RESOLVE_REF_READING, &oid, NULL); @@ -995,7 +995,7 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps, ssize_t count, i; struct object_id oid; - int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + int is_initial = !refs_resolve_ref_unsafe(get_main_ref_store(s->r), "HEAD", RESOLVE_REF_READING, &oid, NULL); diff --git a/add-patch.c b/add-patch.c index 557903310deb23..95c67d8c80c4f3 100644 --- a/add-patch.c +++ b/add-patch.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "add-interactive.h" @@ -1463,7 +1464,7 @@ static int patch_update_file(struct add_p_state *s, if (file_diff->hunk_nr) { if (rendered_hunk_index != hunk_index) { if (use_pager) { - setup_pager(); + setup_pager(the_repository); sigchain_push(SIGPIPE, SIG_IGN); } render_hunk(s, hunk, 0, colored, &s->buf); diff --git a/advice.c b/advice.c index 6b879d805c0304..1df43b7536fabe 100644 --- a/advice.c +++ b/advice.c @@ -53,6 +53,7 @@ static struct { [ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge" }, [ADVICE_DETACHED_HEAD] = { "detachedHead" }, [ADVICE_DIVERGING] = { "diverging" }, + [ADVICE_FETCH_SET_HEAD_WARN] = { "fetchRemoteHEADWarn" }, [ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates" }, [ADVICE_FORCE_DELETE_BRANCH] = { "forceDeleteBranch" }, [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated" }, @@ -93,7 +94,7 @@ static struct { static const char turn_off_instructions[] = N_("\n" - "Disable this message with \"git config advice.%s false\""); + "Disable this message with \"git config set advice.%s false\""); static void vadvise(const char *advice, int display_instructions, const char *key, va_list params) @@ -160,7 +161,6 @@ void advise_if_enabled(enum advice_type type, const char *advice, ...) int git_default_advice_config(const char *var, const char *value) { const char *k, *slot_name; - int i; if (!strcmp(var, "color.advice")) { advice_use_color = git_config_colorbool(var, value); @@ -179,7 +179,7 @@ int git_default_advice_config(const char *var, const char *value) if (!skip_prefix(var, "advice.", &k)) return 0; - for (i = 0; i < ARRAY_SIZE(advice_setting); i++) { + for (size_t i = 0; i < ARRAY_SIZE(advice_setting); i++) { if (strcasecmp(k, advice_setting[i].key)) continue; advice_setting[i].level = git_config_bool(var, value) @@ -193,9 +193,7 @@ int git_default_advice_config(const char *var, const char *value) void list_config_advices(struct string_list *list, const char *prefix) { - int i; - - for (i = 0; i < ARRAY_SIZE(advice_setting); i++) + for (size_t i = 0; i < ARRAY_SIZE(advice_setting); i++) list_config_item(list, prefix, advice_setting[i].key); } diff --git a/advice.h b/advice.h index d7466bc0ef2026..d233cfc693c726 100644 --- a/advice.h +++ b/advice.h @@ -7,7 +7,7 @@ struct string_list; * To add a new advice, you need to: * Define a new advice_type. * Add a new entry to advice_setting array. - * Add the new config variable to Documentation/config/advice.txt. + * Add the new config variable to Documentation/config/advice.adoc. * Call advise_if_enabled to print your advice. */ enum advice_type { @@ -20,6 +20,7 @@ enum advice_type { ADVICE_COMMIT_BEFORE_MERGE, ADVICE_DETACHED_HEAD, ADVICE_DIVERGING, + ADVICE_FETCH_SET_HEAD_WARN, ADVICE_FETCH_SHOW_FORCED_UPDATES, ADVICE_FORCE_DELETE_BRANCH, ADVICE_GRAFT_FILE_DEPRECATED, diff --git a/apply.c b/apply.c index a3fc2d5330f91c..f274a3794877dc 100644 --- a/apply.c +++ b/apply.c @@ -8,6 +8,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -81,7 +82,7 @@ static int parse_whitespace_option(struct apply_state *state, const char *option } /* * Please update $__git_whitespacelist in git-completion.bash, - * Documentation/git-apply.txt, and Documentation/git-am.txt + * Documentation/git-apply.adoc, and Documentation/git-am.adoc * when you add new options. */ return error(_("unrecognized whitespace option '%s'"), option); @@ -1422,7 +1423,10 @@ static int parse_num(const char *line, unsigned long *p) if (!isdigit(*line)) return 0; + errno = 0; *p = strtoul(line, &ptr, 10); + if (errno) + return 0; return ptr - line; } diff --git a/archive-tar.c b/archive-tar.c index e7b3489e1e6c82..0edf13fba7568b 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -473,9 +473,7 @@ static const char internal_gzip_command[] = "git archive gzip"; static int write_tar_filter_archive(const struct archiver *ar, struct archiver_args *args) { -#if ZLIB_VERNUM >= 0x1221 struct gz_header_s gzhead = { .os = 3 }; /* Unix, for reproducibility */ -#endif struct strbuf cmd = STRBUF_INIT; struct child_process filter = CHILD_PROCESS_INIT; int r; @@ -486,10 +484,8 @@ static int write_tar_filter_archive(const struct archiver *ar, if (!strcmp(ar->filter_command, internal_gzip_command)) { write_block = tgz_write_block; git_deflate_init_gzip(&gzstream, args->compression_level); -#if ZLIB_VERNUM >= 0x1221 if (deflateSetHeader(&gzstream.z, &gzhead) != Z_OK) BUG("deflateSetHeader() called too late"); -#endif gzstream.next_out = outbuf; gzstream.avail_out = sizeof(outbuf); diff --git a/archive.c b/archive.c index 58f86bf75cdc7c..8be4e7ac8db50c 100644 --- a/archive.c +++ b/archive.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -6,6 +7,7 @@ #include "convert.h" #include "environment.h" #include "gettext.h" +#include "git-zlib.h" #include "hex.h" #include "object-name.h" #include "path.h" @@ -536,7 +538,8 @@ static void parse_treeish_arg(const char **argv, opts.fn = oneway_merge; init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size); if (unpack_trees(1, &t, &opts)) - die(_("unable to checkout working tree")); + die(_("failed to unpack tree object %s"), + oid_to_hex(&tree->object.oid)); git_attr_set_direction(GIT_ATTR_INDEX); } diff --git a/attr.c b/attr.c index c605d2c1703808..0bd2750528fb84 100644 --- a/attr.c +++ b/attr.c @@ -7,6 +7,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -259,42 +260,6 @@ const struct git_attr *git_attr(const char *name) return git_attr_internal(name, strlen(name)); } -/* What does a matched pattern decide? */ -struct attr_state { - const struct git_attr *attr; - const char *setto; -}; - -struct pattern { - const char *pattern; - int patternlen; - int nowildcardlen; - unsigned flags; /* PATTERN_FLAG_* */ -}; - -/* - * One rule, as from a .gitattributes file. - * - * If is_macro is true, then u.attr is a pointer to the git_attr being - * defined. - * - * If is_macro is false, then u.pat is the filename pattern to which the - * rule applies. - * - * In either case, num_attr is the number of attributes affected by - * this rule, and state is an array listing them. The attributes are - * listed as they appear in the file (macros unexpanded). - */ -struct match_attr { - union { - struct pattern pat; - const struct git_attr *attr; - } u; - char is_macro; - size_t num_attr; - struct attr_state state[FLEX_ARRAY]; -}; - static const char blank[] = " \t\r\n"; /* Flags usable in read_attr() and parse_attr_line() family of functions. */ @@ -353,8 +318,8 @@ static const char *parse_attr(const char *src, int lineno, const char *cp, return ep + strspn(ep, blank); } -static struct match_attr *parse_attr_line(const char *line, const char *src, - int lineno, unsigned flags) +struct match_attr *parse_attr_line(const char *line, const char *src, + int lineno, unsigned flags) { size_t namelen, num_attr, i; const char *cp, *name, *states; diff --git a/attr.h b/attr.h index bb33b608805a0e..a04a5210921e22 100644 --- a/attr.h +++ b/attr.h @@ -240,4 +240,47 @@ int git_attr_system_is_enabled(void); extern char *git_attr_tree; +/* + * Exposed for fuzz-testing only. + */ + +/* What does a matched pattern decide? */ +struct attr_state { + const struct git_attr *attr; + const char *setto; +}; + +struct pattern { + const char *pattern; + int patternlen; + int nowildcardlen; + unsigned flags; /* PATTERN_FLAG_* */ +}; + +/* + * One rule, as from a .gitattributes file. + * + * If is_macro is true, then u.attr is a pointer to the git_attr being + * defined. + * + * If is_macro is false, then u.pat is the filename pattern to which the + * rule applies. + * + * In either case, num_attr is the number of attributes affected by + * this rule, and state is an array listing them. The attributes are + * listed as they appear in the file (macros unexpanded). + */ +struct match_attr { + union { + struct pattern pat; + const struct git_attr *attr; + } u; + char is_macro; + size_t num_attr; + struct attr_state state[FLEX_ARRAY]; +}; + +struct match_attr *parse_attr_line(const char *line, const char *src, + int lineno, unsigned flags); + #endif /* ATTR_H */ diff --git a/base85.c b/base85.c index bbacdca31b3bc3..80e899a2b1a20d 100644 --- a/base85.c +++ b/base85.c @@ -29,10 +29,9 @@ static const char en85[] = { static char de85[256]; static void prep_base85(void) { - int i; if (de85['Z']) return; - for (i = 0; i < ARRAY_SIZE(en85); i++) { + for (size_t i = 0; i < ARRAY_SIZE(en85); i++) { int ch = en85[i]; de85[ch] = i + 1; } diff --git a/bin-wrappers/.gitignore b/bin-wrappers/.gitignore new file mode 100644 index 00000000000000..1c6c90458b7586 --- /dev/null +++ b/bin-wrappers/.gitignore @@ -0,0 +1,9 @@ +/git +/git-cvsserver +/git-receive-pack +/git-shell +/git-upload-archive +/git-upload-pack +/scalar +/test-fake-ssh +/test-tool diff --git a/bin-wrappers/meson.build b/bin-wrappers/meson.build new file mode 100644 index 00000000000000..8a4e910c9be7da --- /dev/null +++ b/bin-wrappers/meson.build @@ -0,0 +1,28 @@ +bin_wrappers_config = configuration_data() +foreach key, value : { + 'BUILD_DIR': meson.project_build_root(), + 'MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools', + 'TEMPLATE_DIR': meson.project_build_root() / 'templates', + 'GIT_TEXTDOMAINDIR': meson.project_build_root() / 'po', + 'GITPERLLIB': meson.project_build_root() / 'perl/lib', +} + # Paths need to be Unix-style without drive prefixes as they get added to the + # PATH variable. And given that drive prefixes contain a colon we'd otherwise + # end up with a broken PATH if we didn't convert them. + if cygpath.found() + value = run_command(cygpath, value, check: true).stdout().strip() + endif + bin_wrappers_config.set(key, value) +endforeach + +foreach executable : bin_wrappers + executable_config = configuration_data() + executable_config.merge_from(bin_wrappers_config) + executable_config.set('PROG', executable.full_path()) + + configure_file( + input: 'wrap-for-bin.sh', + output: fs.stem(executable.full_path()), + configuration: executable_config, + ) +endforeach diff --git a/bin-wrappers/wrap-for-bin.sh b/bin-wrappers/wrap-for-bin.sh new file mode 100755 index 00000000000000..4b658ffd2d0960 --- /dev/null +++ b/bin-wrappers/wrap-for-bin.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# wrap-for-bin.sh: Template for git executable wrapper scripts +# to run test suite against sandbox, but with only bindir-installed +# executables in PATH. The Makefile copies this into various +# files in bin-wrappers, substituting +# @BUILD_DIR@, @TEMPLATE_DIR@ and @PROG@. + +GIT_EXEC_PATH='@BUILD_DIR@' +if test -n "$NO_SET_GIT_TEMPLATE_DIR" +then + unset GIT_TEMPLATE_DIR +else + GIT_TEMPLATE_DIR='@TEMPLATE_DIR@' + export GIT_TEMPLATE_DIR +fi +MERGE_TOOLS_DIR='@MERGE_TOOLS_DIR@' +GITPERLLIB='@GITPERLLIB@'"${GITPERLLIB:+:$GITPERLLIB}" +GIT_TEXTDOMAINDIR='@GIT_TEXTDOMAINDIR@' +PATH='@BUILD_DIR@/bin-wrappers:'"$PATH" + +export MERGE_TOOLS_DIR GIT_EXEC_PATH GITPERLLIB PATH GIT_TEXTDOMAINDIR + +case "$GIT_DEBUGGER" in +'') + exec "@PROG@" "$@" + ;; +1) + unset GIT_DEBUGGER + exec gdb --args "@PROG@" "$@" + ;; +*) + GIT_DEBUGGER_ARGS="$GIT_DEBUGGER" + unset GIT_DEBUGGER + exec ${GIT_DEBUGGER_ARGS} "@PROG@" "$@" + ;; +esac diff --git a/bisect.c b/bisect.c index 4713226fad4e16..269a98bf978de6 100644 --- a/bisect.c +++ b/bisect.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -28,8 +29,8 @@ static struct oid_array skipped_revs; static struct object_id *current_bad_oid; -static const char *term_bad; -static const char *term_good; +static char *term_bad; +static char *term_good; /* Remember to update object flag allocation in object.h */ #define COUNTED (1u<<16) @@ -443,8 +444,9 @@ void find_bisection(struct commit_list **commit_list, int *reaches, } *reaches = weight(best); } - free(weights); *commit_list = best; + + free(weights); clear_commit_weight(&commit_weight); } @@ -456,6 +458,7 @@ static int register_ref(const char *refname, const char *referent UNUSED, const strbuf_addstr(&good_prefix, "-"); if (!strcmp(refname, term_bad)) { + free(current_bad_oid); current_bad_oid = xmalloc(sizeof(*current_bad_oid)); oidcpy(current_bad_oid, oid); } else if (starts_with(refname, good_prefix.buf)) { @@ -556,8 +559,11 @@ struct commit_list *filter_skipped(struct commit_list *list, tried = &list->next; } else { if (!show_all) { - if (!skipped_first || !*skipped_first) + if (!skipped_first || !*skipped_first) { + free_commit_list(next); + free_commit_list(filtered); return list; + } } else if (skipped_first && !*skipped_first) { /* This means we know it's not skipped */ *skipped_first = -1; @@ -613,7 +619,7 @@ static int sqrti(int val) static struct commit_list *skip_away(struct commit_list *list, int count) { - struct commit_list *cur, *previous; + struct commit_list *cur, *previous, *result = list; int prn, index, i; prn = get_prn(count); @@ -625,15 +631,23 @@ static struct commit_list *skip_away(struct commit_list *list, int count) for (i = 0; cur; cur = cur->next, i++) { if (i == index) { if (!oideq(&cur->item->object.oid, current_bad_oid)) - return cur; - if (previous) - return previous; - return list; + result = cur; + else if (previous) + result = previous; + else + result = list; + break; } previous = cur; } - return list; + for (cur = list; cur != result; ) { + struct commit_list *next = cur->next; + free(cur); + cur = next; + } + + return result; } static struct commit_list *managed_skipped(struct commit_list *list, @@ -766,10 +780,10 @@ static struct commit *get_commit_reference(struct repository *r, } static struct commit **get_bad_and_good_commits(struct repository *r, - int *rev_nr) + size_t *rev_nr) { struct commit **rev; - int i, n = 0; + size_t i, n = 0; ALLOC_ARRAY(rev, 1 + good_revs.nr); rev[n++] = get_commit_reference(r, current_bad_oid); @@ -801,6 +815,8 @@ static enum bisect_error handle_bad_merge_base(void) "between %s and [%s].\n"), bad_hex, term_bad, term_good, bad_hex, good_hex); } + + free(good_hex); return BISECT_MERGE_BASE_CHECK; } @@ -839,7 +855,7 @@ static void handle_skipped_merge_base(const struct object_id *mb) * for early success, this will be converted back to 0 in * check_good_are_ancestors_of_bad(). */ -static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int no_checkout) +static enum bisect_error check_merge_bases(size_t rev_nr, struct commit **rev, int no_checkout) { enum bisect_error res = BISECT_OK; struct commit_list *result = NULL; @@ -848,8 +864,8 @@ static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int rev + 1, &result) < 0) exit(128); - for (; result; result = result->next) { - const struct object_id *mb = &result->item->object.oid; + for (struct commit_list *l = result; l; l = l->next) { + const struct object_id *mb = &l->item->object.oid; if (oideq(mb, current_bad_oid)) { res = handle_bad_merge_base(); break; @@ -871,7 +887,7 @@ static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int return res; } -static int check_ancestors(struct repository *r, int rev_nr, +static int check_ancestors(struct repository *r, size_t rev_nr, struct commit **rev, const char *prefix) { struct strvec rev_argv = STRVEC_INIT; @@ -906,14 +922,15 @@ static enum bisect_error check_good_are_ancestors_of_bad(struct repository *r, { char *filename; struct stat st; - int fd, rev_nr; + int fd; + size_t rev_nr; enum bisect_error res = BISECT_OK; struct commit **rev; if (!current_bad_oid) return error(_("a %s revision is needed"), term_bad); - filename = git_pathdup("BISECT_ANCESTORS_OK"); + filename = repo_git_path(the_repository, "BISECT_ANCESTORS_OK"); /* Check if file BISECT_ANCESTORS_OK exists. */ if (!stat(filename, &st) && S_ISREG(st.st_mode)) @@ -985,7 +1002,7 @@ static void show_commit(struct commit *commit) * We read them and store them to adapt the messages accordingly. * Default is bad/good. */ -void read_bisect_terms(const char **read_bad, const char **read_good) +void read_bisect_terms(char **read_bad, char **read_good) { struct strbuf str = STRBUF_INIT; const char *filename = git_path_bisect_terms(); @@ -993,16 +1010,20 @@ void read_bisect_terms(const char **read_bad, const char **read_good) if (!fp) { if (errno == ENOENT) { - *read_bad = "bad"; - *read_good = "good"; + free(*read_bad); + *read_bad = xstrdup("bad"); + free(*read_good); + *read_good = xstrdup("good"); return; } else { die_errno(_("could not read file '%s'"), filename); } } else { strbuf_getline_lf(&str, fp); + free(*read_bad); *read_bad = strbuf_detach(&str, NULL); strbuf_getline_lf(&str, fp); + free(*read_good); *read_good = strbuf_detach(&str, NULL); } strbuf_release(&str); @@ -1024,7 +1045,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) { struct strvec rev_argv = STRVEC_INIT; struct rev_info revs = REV_INFO_INIT; - struct commit_list *tried; + struct commit_list *tried = NULL; int reaches = 0, all = 0, nr, steps; enum bisect_error res = BISECT_OK; struct object_id *bisect_rev; @@ -1091,7 +1112,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) if (oideq(bisect_rev, current_bad_oid)) { res = error_if_skipped_commits(tried, current_bad_oid); if (res) - return res; + goto cleanup; printf("%s is the first %s commit\n", oid_to_hex(bisect_rev), term_bad); @@ -1125,6 +1146,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) res = bisect_checkout(bisect_rev, no_checkout); cleanup: + free_commit_list(tried); release_revisions(&revs); strvec_clear(&rev_argv); return res; diff --git a/bisect.h b/bisect.h index ee3fd65f3bdb89..944439bfac729c 100644 --- a/bisect.h +++ b/bisect.h @@ -75,7 +75,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix); int estimate_bisect_steps(int all); -void read_bisect_terms(const char **bad, const char **good); +void read_bisect_terms(char **bad, char **good); int bisect_clean_state(void); diff --git a/blame.c b/blame.c index 90633380cd583b..a15ddf933352b0 100644 --- a/blame.c +++ b/blame.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "refs.h" @@ -2931,6 +2932,7 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb) void cleanup_scoreboard(struct blame_scoreboard *sb) { free(sb->lineno); + free(sb->final_buf); clear_prio_queue(&sb->commits); oidset_clear(&sb->ignore_list); diff --git a/blame.h b/blame.h index 5b4e47d44c613e..3b34be0e5c6932 100644 --- a/blame.h +++ b/blame.h @@ -116,7 +116,7 @@ struct blame_scoreboard { * Used by many functions to obtain contents of the nth line, * indexed with scoreboard.lineno[blame_entry.lno]. */ - const char *final_buf; + char *final_buf; unsigned long final_buf_size; /* linked list of blames */ diff --git a/block-sha1/sha1.h b/block-sha1/sha1.h index 9fb0441b98849e..47bb9166368a70 100644 --- a/block-sha1/sha1.h +++ b/block-sha1/sha1.h @@ -16,7 +16,9 @@ void blk_SHA1_Init(blk_SHA_CTX *ctx); void blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, size_t len); void blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx); +#ifndef platform_SHA_CTX #define platform_SHA_CTX blk_SHA_CTX #define platform_SHA1_Init blk_SHA1_Init #define platform_SHA1_Update blk_SHA1_Update #define platform_SHA1_Final blk_SHA1_Final +#endif diff --git a/bloom.c b/bloom.c index c915f8b1ba8c4a..0c8d2cebf9c4ed 100644 --- a/bloom.c +++ b/bloom.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "bloom.h" #include "diff.h" @@ -476,8 +478,6 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r, *last_slash = '\0'; } while (*path); - - diff_free_filepair(diff_queued_diff.queue[i]); } if (hashmap_get_size(&pathmap) > settings->max_changed_paths) { @@ -508,8 +508,6 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r, cleanup: hashmap_clear_and_free(&pathmap, struct pathmap_hash_entry, entry); } else { - for (i = 0; i < diff_queued_diff.nr; i++) - diff_free_filepair(diff_queued_diff.queue[i]); init_truncated_large_filter(filter, settings->hash_version); if (computed) @@ -519,9 +517,7 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r, if (computed) *computed |= BLOOM_COMPUTED; - free(diff_queued_diff.queue); - DIFF_QUEUE_CLEAR(&diff_queued_diff); - + diff_queue_clear(&diff_queued_diff); return filter; } diff --git a/branch.c b/branch.c index 08fa4094d2bf1e..91297d55ac9f60 100644 --- a/branch.c +++ b/branch.c @@ -372,7 +372,7 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name) */ int validate_branchname(const char *name, struct strbuf *ref) { - if (strbuf_check_branch_ref(ref, name)) { + if (check_branch_ref(ref, name)) { int code = die_message(_("'%s' is not a valid branch name"), name); advise_if_enabled(ADVICE_REF_SYNTAX, _("See `man git check-ref-format`")); @@ -397,7 +397,7 @@ static void prepare_checked_out_branches(void) worktrees = get_worktrees(); while (worktrees[i]) { - char *old; + char *old, *wt_gitdir; struct wt_status_state state = { 0 }; struct worktree *wt = worktrees[i++]; struct string_list update_refs = STRING_LIST_INIT_DUP; @@ -437,7 +437,8 @@ static void prepare_checked_out_branches(void) } wt_status_state_free_buffers(&state); - if (!sequencer_get_update_refs_state(get_worktree_git_dir(wt), + wt_gitdir = get_worktree_git_dir(wt); + if (!sequencer_get_update_refs_state(wt_gitdir, &update_refs)) { struct string_list_item *item; for_each_string_list_item(item, &update_refs) { @@ -448,6 +449,8 @@ static void prepare_checked_out_branches(void) } string_list_clear(&update_refs, 1); } + + free(wt_gitdir); } free_worktrees(worktrees); @@ -627,7 +630,7 @@ void create_branch(struct repository *r, else msg = xstrfmt("branch: Created from %s", start_name); transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction || ref_transaction_update(transaction, ref.buf, &oid, forcing ? NULL : null_oid(), @@ -738,6 +741,7 @@ static int submodule_create_branch(struct repository *r, strbuf_release(&child_err); strbuf_release(&out_buf); + free(out_prefix); return ret; } @@ -794,7 +798,7 @@ void create_branches_recursively(struct repository *r, const char *name, create_branch(r, name, start_committish, force, 0, reflog, quiet, BRANCH_TRACK_NEVER, dry_run); if (dry_run) - return; + goto out; /* * NEEDSWORK If tracking was set up in the superproject but not the * submodule, users might expect "git branch --recurse-submodules" to @@ -815,8 +819,11 @@ void create_branches_recursively(struct repository *r, const char *name, die(_("submodule '%s': cannot create branch '%s'"), submodule_entry_list.entries[i].submodule->name, name); - repo_clear(submodule_entry_list.entries[i].repo); } + +out: + submodule_entry_list_release(&submodule_entry_list); + free(branch_point); } void remove_merge_branch_state(struct repository *r) diff --git a/builtin.h b/builtin.h index f7b166b33484d3..dd738bc9b7040d 100644 --- a/builtin.h +++ b/builtin.h @@ -63,7 +63,7 @@ * * . Add tests to `t/` directory. * - * . Write documentation in `Documentation/git-foo.txt`. + * . Write documentation in `Documentation/git-foo.adoc`. * * . Add an entry for `git-foo` to `command-list.txt`. * @@ -120,6 +120,7 @@ int cmd_am(int argc, const char **argv, const char *prefix, struct repository *r int cmd_annotate(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_apply(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_archive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_backfill(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_bisect(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_blame(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_branch(int argc, const char **argv, const char *prefix, struct repository *repo); @@ -231,6 +232,7 @@ int cmd_status(int argc, const char **argv, const char *prefix, struct repositor int cmd_stash(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_stripspace(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_submodule__helper(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_survey(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_switch(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_symbolic_ref(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_tag(int argc, const char **argv, const char *prefix, struct repository *repo); diff --git a/builtin/add.c b/builtin/add.c index 773b7224a4915d..78dfb265776724 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -3,6 +3,7 @@ * * Copyright (C) 2006 Linus Torvalds */ + #include "builtin.h" #include "advice.h" #include "config.h" @@ -39,9 +40,9 @@ static int chmod_pathspec(struct repository *repo, char flip, int show_only) { - int i, ret = 0; + int ret = 0; - for (i = 0; i < repo->index->cache_nr; i++) { + for (size_t i = 0; i < repo->index->cache_nr; i++) { struct cache_entry *ce = repo->index->cache[i]; int err; @@ -69,9 +70,9 @@ static int renormalize_tracked_files(struct repository *repo, const struct pathspec *pathspec, int flags) { - int i, retval = 0; + int retval = 0; - for (i = 0; i < repo->index->cache_nr; i++) { + for (size_t i = 0; i < repo->index->cache_nr; i++) { struct cache_entry *ce = repo->index->cache[i]; if (!include_sparse && @@ -385,7 +386,8 @@ int cmd_add(int argc, char *ps_matched = NULL; struct lock_file lock_file = LOCK_INIT; - repo_config(repo, add_config, NULL); + if (repo) + repo_config(repo, add_config, NULL); argc = parse_options(argc, argv, prefix, builtin_add_options, builtin_add_usage, PARSE_OPT_KEEP_ARGV0); diff --git a/builtin/am.c b/builtin/am.c index bfa95147cf403f..2921bb89ef16e6 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -5,6 +5,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" #include "advice.h" @@ -157,7 +158,7 @@ static void am_state_init(struct am_state *state) memset(state, 0, sizeof(*state)); - state->dir = git_pathdup("rebase-apply"); + state->dir = repo_git_path(the_repository, "rebase-apply"); state->prec = 4; @@ -1210,7 +1211,7 @@ static int parse_mail(struct am_state *state, const char *mail) int ret = 0; struct mailinfo mi; - setup_mailinfo(&mi); + setup_mailinfo(the_repository, &mi); if (state->utf8) mi.metainfo_charset = get_commit_output_encoding(); @@ -1785,7 +1786,7 @@ static int do_interactive(struct am_state *state) } strbuf_release(&msg); } else if (*reply == 'v' || *reply == 'V') { - const char *pager = git_pager(1); + const char *pager = git_pager(the_repository, 1); struct child_process cp = CHILD_PROCESS_INIT; if (!pager) @@ -2245,7 +2246,7 @@ static int show_patch(struct am_state *state, enum resume_type resume_mode) if (len < 0) die_errno(_("failed to read '%s'"), patch_path); - setup_pager(); + setup_pager(the_repository); write_in_full(1, sb.buf, sb.len); strbuf_release(&sb); return 0; @@ -2426,8 +2427,7 @@ int cmd_am(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(usage, options); + show_usage_with_options_if_asked(argc, argv, usage, options); git_config(git_default_config, NULL); diff --git a/builtin/annotate.c b/builtin/annotate.c index a99179fe4dd9ae..7f754f2309b662 100644 --- a/builtin/annotate.c +++ b/builtin/annotate.c @@ -4,7 +4,6 @@ * Copyright (C) 2006 Ryan Anderson */ -#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "builtin.h" #include "strvec.h" @@ -12,16 +11,26 @@ int cmd_annotate(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { struct strvec args = STRVEC_INIT; - int i; + const char **args_copy; + int ret; strvec_pushl(&args, "annotate", "-c", NULL); - - for (i = 1; i < argc; i++) { + for (int i = 1; i < argc; i++) strvec_push(&args, argv[i]); - } - return cmd_blame(args.nr, args.v, prefix, the_repository); + /* + * `cmd_blame()` ends up modifying the array, which causes memory leaks + * if we didn't copy the array here. + */ + CALLOC_ARRAY(args_copy, args.nr + 1); + COPY_ARRAY(args_copy, args.v, args.nr); + + ret = cmd_blame(args.nr, args_copy, prefix, repo); + + strvec_clear(&args); + free(args_copy); + return ret; } diff --git a/builtin/archive.c b/builtin/archive.c index dc926d1a3dfa90..13ea7308c8b8b9 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -2,7 +2,6 @@ * Copyright (c) 2006 Franck Bui-Huu * Copyright (c) 2006 Rene Scharfe */ -#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "archive.h" #include "gettext.h" @@ -79,7 +78,7 @@ static int run_remote_archiver(int argc, const char **argv, int cmd_archive(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { const char *exec = "git-upload-archive"; char *output = NULL; @@ -110,7 +109,7 @@ int cmd_archive(int argc, setvbuf(stderr, NULL, _IOLBF, BUFSIZ); - ret = write_archive(argc, argv, prefix, the_repository, output, 0); + ret = write_archive(argc, argv, prefix, repo, output, 0); out: free(output); diff --git a/builtin/backfill.c b/builtin/backfill.c new file mode 100644 index 00000000000000..33e1ea2f84ff6b --- /dev/null +++ b/builtin/backfill.c @@ -0,0 +1,147 @@ +/* We need this macro to access core_apply_sparse_checkout */ +#define USE_THE_REPOSITORY_VARIABLE + +#include "builtin.h" +#include "git-compat-util.h" +#include "config.h" +#include "parse-options.h" +#include "repository.h" +#include "commit.h" +#include "dir.h" +#include "environment.h" +#include "hex.h" +#include "tree.h" +#include "tree-walk.h" +#include "object.h" +#include "object-store-ll.h" +#include "oid-array.h" +#include "oidset.h" +#include "promisor-remote.h" +#include "strmap.h" +#include "string-list.h" +#include "revision.h" +#include "trace2.h" +#include "progress.h" +#include "packfile.h" +#include "path-walk.h" + +static const char * const builtin_backfill_usage[] = { + N_("git backfill [--min-batch-size=<n>] [--[no-]sparse]"), + NULL +}; + +struct backfill_context { + struct repository *repo; + struct oid_array current_batch; + size_t min_batch_size; + int sparse; +}; + +static void backfill_context_clear(struct backfill_context *ctx) +{ + oid_array_clear(&ctx->current_batch); +} + +static void download_batch(struct backfill_context *ctx) +{ + promisor_remote_get_direct(ctx->repo, + ctx->current_batch.oid, + ctx->current_batch.nr); + oid_array_clear(&ctx->current_batch); + + /* + * We likely have a new packfile. Add it to the packed list to + * avoid possible duplicate downloads of the same objects. + */ + reprepare_packed_git(ctx->repo); +} + +static int fill_missing_blobs(const char *path UNUSED, + struct oid_array *list, + enum object_type type, + void *data) +{ + struct backfill_context *ctx = data; + + if (type != OBJ_BLOB) + return 0; + + for (size_t i = 0; i < list->nr; i++) { + if (!has_object(ctx->repo, &list->oid[i], + OBJECT_INFO_FOR_PREFETCH)) + oid_array_append(&ctx->current_batch, &list->oid[i]); + } + + if (ctx->current_batch.nr >= ctx->min_batch_size) + download_batch(ctx); + + return 0; +} + +static int do_backfill(struct backfill_context *ctx) +{ + struct rev_info revs; + struct path_walk_info info = PATH_WALK_INFO_INIT; + int ret; + + if (ctx->sparse) { + CALLOC_ARRAY(info.pl, 1); + if (get_sparse_checkout_patterns(info.pl)) { + path_walk_info_clear(&info); + return error(_("problem loading sparse-checkout")); + } + } + + repo_init_revisions(ctx->repo, &revs, ""); + handle_revision_arg("HEAD", &revs, 0, 0); + + info.blobs = 1; + info.tags = info.commits = info.trees = 0; + + info.revs = &revs; + info.path_fn = fill_missing_blobs; + info.path_fn_data = ctx; + + ret = walk_objects_by_path(&info); + + /* Download the objects that did not fill a batch. */ + if (!ret) + download_batch(ctx); + + path_walk_info_clear(&info); + release_revisions(&revs); + return ret; +} + +int cmd_backfill(int argc, const char **argv, const char *prefix, struct repository *repo) +{ + int result; + struct backfill_context ctx = { + .repo = repo, + .current_batch = OID_ARRAY_INIT, + .min_batch_size = 50000, + .sparse = 0, + }; + struct option options[] = { + OPT_INTEGER(0, "min-batch-size", &ctx.min_batch_size, + N_("Minimum number of objects to request at a time")), + OPT_BOOL(0, "sparse", &ctx.sparse, + N_("Restrict the missing objects to the current sparse-checkout")), + OPT_END(), + }; + + show_usage_with_options_if_asked(argc, argv, + builtin_backfill_usage, options); + + argc = parse_options(argc, argv, prefix, options, builtin_backfill_usage, + 0); + + repo_config(repo, git_default_config, NULL); + + if (ctx.sparse < 0) + ctx.sparse = core_apply_sparse_checkout; + + result = do_backfill(&ctx); + backfill_context_clear(&ctx); + return result; +} diff --git a/builtin/bisect.c b/builtin/bisect.c index 21d17a6c1a83e5..8b8d870cd1ef08 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "copy.h" #include "environment.h" @@ -1312,7 +1314,8 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv) return res; } -static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { if (argc > 1) return error(_("'%s' requires either no argument or a commit"), @@ -1320,7 +1323,8 @@ static int cmd_bisect__reset(int argc, const char **argv, const char *prefix UNU return bisect_reset(argc ? argv[0] : NULL); } -static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1333,7 +1337,8 @@ static int cmd_bisect__terms(int argc, const char **argv, const char *prefix UNU return res; } -static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1344,7 +1349,8 @@ static int cmd_bisect__start(int argc, const char **argv, const char *prefix UNU return res; } -static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix) +static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *prefix, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1358,12 +1364,15 @@ static int cmd_bisect__next(int argc, const char **argv UNUSED, const char *pref return res; } -static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, const char *prefix UNUSED) +static int cmd_bisect__log(int argc UNUSED, const char **argv UNUSED, + const char *prefix UNUSED, + struct repository *repo UNUSED) { return bisect_log(); } -static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1376,7 +1385,8 @@ static int cmd_bisect__replay(int argc, const char **argv, const char *prefix UN return res; } -static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1388,7 +1398,8 @@ static int cmd_bisect__skip(int argc, const char **argv, const char *prefix UNUS return res; } -static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1399,7 +1410,8 @@ static int cmd_bisect__visualize(int argc, const char **argv, const char *prefix return res; } -static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED) +static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int res; struct bisect_terms terms = { 0 }; @@ -1415,7 +1427,7 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE int cmd_bisect(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { int res = 0; parse_opt_subcommand_fn *fn = NULL; @@ -1451,7 +1463,7 @@ int cmd_bisect(int argc, } else { argc--; argv++; - res = fn(argc, argv, prefix); + res = fn(argc, argv, prefix, repo); } return is_bisect_success(res) ? 0 : -res; diff --git a/builtin/blame.c b/builtin/blame.c index e407a22da3bacf..c470654c7ec2c3 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -4,7 +4,9 @@ * Copyright (c) 2006, 2014 by its authors * See COPYING for licensing conditions */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "color.h" @@ -465,9 +467,14 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int reset = GIT_COLOR_RESET; } + if (abbrev < MINIMUM_ABBREV) + BUG("abbreviation is smaller than minimum length: %d < %d", + abbrev, MINIMUM_ABBREV); + for (cnt = 0; cnt < ent->num_lines; cnt++) { char ch; - int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev; + size_t length = (opt & OUTPUT_LONG_OBJECT_NAME) ? + the_hash_algo->hexsz : (size_t) abbrev; if (opt & OUTPUT_COLOR_LINE) { if (cnt > 0) { @@ -482,9 +489,9 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int fputs(color, stdout); if (suspect->commit->object.flags & UNINTERESTING) { - if (blank_boundary) - memset(hex, ' ', length); - else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) { + if (blank_boundary) { + memset(hex, ' ', strlen(hex)); + } else if (!(opt & OUTPUT_ANNOTATE_COMPAT)) { length--; putchar('^'); } @@ -498,7 +505,8 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int length--; putchar('?'); } - printf("%.*s", length, hex); + + printf("%.*s", (int)(length < GIT_MAX_HEXSZ ? length : GIT_MAX_HEXSZ), hex); if (opt & OUTPUT_ANNOTATE_COMPAT) { const char *name; if (opt & OUTPUT_SHOW_EMAIL) @@ -1186,14 +1194,16 @@ int cmd_blame(int argc, sb.found_guilty_entry = &found_guilty_entry; sb.found_guilty_entry_data = π if (show_progress) - pi.progress = start_delayed_progress(_("Blaming lines"), num_lines); + pi.progress = start_delayed_progress(the_repository, + _("Blaming lines"), + num_lines); assign_blame(&sb, opt); stop_progress(&pi.progress); if (!incremental) - setup_pager(); + setup_pager(the_repository); else goto cleanup; @@ -1216,12 +1226,6 @@ int cmd_blame(int argc, output_option &= ~(OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR); output(&sb, output_option); - free((void *)sb.final_buf); - for (ent = sb.ent; ent; ) { - struct blame_entry *e = ent->next; - free(ent); - ent = e; - } if (show_stats) { printf("num read blob: %d\n", sb.num_read_blob); @@ -1230,6 +1234,12 @@ int cmd_blame(int argc, } cleanup: + for (ent = sb.ent; ent; ) { + struct blame_entry *e = ent->next; + free(ent); + ent = e; + } + free(path); cleanup_scoreboard(&sb); release_revisions(&revs); diff --git a/builtin/branch.c b/builtin/branch.c index fd1611ebf559f7..c150131bd9f122 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -4,7 +4,9 @@ * Copyright (c) 2006 Kristian Høgsberg <krh@redhat.com> * Based on git-branch.sh by Junio C Hamano. */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "color.h" @@ -257,7 +259,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, char *target = NULL; int flags = 0; - strbuf_branchname(&bname, argv[i], allowed_interpret); + copy_branchname(&bname, argv[i], allowed_interpret); free(name); name = mkpathdup(fmt, bname.buf); @@ -471,7 +473,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin if (verify_ref_format(format)) die(_("unable to parse format string")); - filter_ahead_behind(the_repository, format, &array); + filter_ahead_behind(the_repository, &array); ref_array_sort(sorting, &array); if (column_active(colopts)) { @@ -579,7 +581,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int int recovery = 0, oldref_usage = 0; struct worktree **worktrees = get_worktrees(); - if (strbuf_check_branch_ref(&oldref, oldname)) { + if (check_branch_ref(&oldref, oldname)) { /* * Bad name --- this could be an attempt to rename a * ref that we used to allow to be created by accident. @@ -722,6 +724,7 @@ int cmd_branch(int argc, static struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; struct ref_format format = REF_FORMAT_INIT; + int ret; struct option options[] = { OPT_GROUP(N_("Generic options")), @@ -781,8 +784,8 @@ int cmd_branch(int argc, filter.kind = FILTER_REFS_BRANCHES; filter.abbrev = -1; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_branch_usage, options); + show_usage_with_options_if_asked(argc, argv, + builtin_branch_usage, options); /* * Try to set sort keys from config. If config does not set any, @@ -851,15 +854,15 @@ int cmd_branch(int argc, if (list) setup_auto_pager("branch", 1); - UNLEAK(sorting_options); - if (delete) { if (!argc) die(_("branch name required")); - return delete_branches(argc, argv, delete > 1, filter.kind, quiet); + ret = delete_branches(argc, argv, delete > 1, filter.kind, quiet); + goto out; } else if (show_current) { print_current_branch_name(); - return 0; + ret = 0; + goto out; } else if (list) { /* git branch --list also shows HEAD when it is detached */ if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached) @@ -881,38 +884,42 @@ int cmd_branch(int argc, string_list_clear(&output, 0); ref_sorting_release(sorting); ref_filter_clear(&filter); - ref_format_clear(&format); - return 0; + + ret = 0; + goto out; } else if (edit_description) { const char *branch_name; struct strbuf branch_ref = STRBUF_INIT; struct strbuf buf = STRBUF_INIT; - int ret = 1; /* assume failure */ if (!argc) { if (filter.detached) die(_("cannot give description to detached HEAD")); branch_name = head; } else if (argc == 1) { - strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL); + copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL); branch_name = buf.buf; } else { die(_("cannot edit description of more than one branch")); } strbuf_addf(&branch_ref, "refs/heads/%s", branch_name); - if (!refs_ref_exists(get_main_ref_store(the_repository), branch_ref.buf)) + if (!refs_ref_exists(get_main_ref_store(the_repository), branch_ref.buf)) { error((!argc || branch_checked_out(branch_ref.buf)) ? _("no commit on branch '%s' yet") : _("no branch named '%s'"), branch_name); - else if (!edit_branch_description(branch_name)) + ret = 1; + } else if (!edit_branch_description(branch_name)) { ret = 0; /* happy */ + } else { + ret = 1; + } strbuf_release(&branch_ref); strbuf_release(&buf); - return ret; + goto out; } else if (copy || rename) { if (!argc) die(_("branch name required")); @@ -933,7 +940,7 @@ int cmd_branch(int argc, if (!argc) branch = branch_get(NULL); else if (argc == 1) { - strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL); + copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL); branch = branch_get(buf.buf); } else die(_("too many arguments to set new upstream")); @@ -963,7 +970,7 @@ int cmd_branch(int argc, if (!argc) branch = branch_get(NULL); else if (argc == 1) { - strbuf_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL); + copy_branchname(&buf, argv[0], INTERPRET_BRANCH_LOCAL); branch = branch_get(buf.buf); } else die(_("too many arguments to unset upstream")); @@ -1000,12 +1007,17 @@ int cmd_branch(int argc, create_branches_recursively(the_repository, branch_name, start_name, NULL, force, reflog, quiet, track, 0); - return 0; + ret = 0; + goto out; } create_branch(the_repository, branch_name, start_name, force, 0, reflog, quiet, track, 0); } else usage_with_options(builtin_branch_usage, options); - return 0; + ret = 0; + +out: + string_list_clear(&sorting_options, 0); + return ret; } diff --git a/builtin/bugreport.c b/builtin/bugreport.c index 7c2df035c9cff0..66d64bfd5aec25 100644 --- a/builtin/bugreport.c +++ b/builtin/bugreport.c @@ -12,10 +12,10 @@ #include "diagnose.h" #include "object-file.h" #include "setup.h" +#include "version.h" static void get_system_info(struct strbuf *sys_info) { - struct utsname uname_info; char *shell = NULL; /* get git version from native cmd */ @@ -24,16 +24,7 @@ static void get_system_info(struct strbuf *sys_info) /* system call for other version info */ strbuf_addstr(sys_info, "uname: "); - if (uname(&uname_info)) - strbuf_addf(sys_info, _("uname() failed with error '%s' (%d)\n"), - strerror(errno), - errno); - else - strbuf_addf(sys_info, "%s %s %s %s\n", - uname_info.sysname, - uname_info.release, - uname_info.version, - uname_info.machine); + get_uname_info(sys_info, 1); strbuf_addstr(sys_info, _("compiler info: ")); get_compiler_info(sys_info); @@ -167,7 +158,7 @@ int cmd_bugreport(int argc, strbuf_addftime(&zip_path, option_suffix, localtime_r(&now, &tm), 0, 0); strbuf_addstr(&zip_path, ".zip"); - if (create_diagnostics_archive(&zip_path, diagnose)) + if (create_diagnostics_archive(the_repository, &zip_path, diagnose)) die_errno(_("unable to create diagnostics archive %s"), zip_path.buf); strbuf_release(&zip_path); diff --git a/builtin/bundle.c b/builtin/bundle.c index 127518c2a8d3c4..1e170e92780ed4 100644 --- a/builtin/bundle.c +++ b/builtin/bundle.c @@ -67,7 +67,8 @@ static int parse_options_cmd_bundle(int argc, return argc; } -static int cmd_bundle_create(int argc, const char **argv, const char *prefix) { +static int cmd_bundle_create(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct strvec pack_opts = STRVEC_INIT; int version = -1; int ret; @@ -123,7 +124,8 @@ static int open_bundle(const char *path, struct bundle_header *header, return read_bundle_header(path, header); } -static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) { +static int cmd_bundle_verify(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct bundle_header header = BUNDLE_HEADER_INIT; int bundle_fd = -1; int quiet = 0; @@ -164,7 +166,8 @@ static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) { return ret; } -static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) { +static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct bundle_header header = BUNDLE_HEADER_INIT; int bundle_fd = -1; int ret; @@ -189,7 +192,8 @@ static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix return ret; } -static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) { +static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct bundle_header header = BUNDLE_HEADER_INIT; int bundle_fd = -1; int ret; @@ -218,7 +222,7 @@ static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) strvec_pushl(&extra_index_pack_args, "-v", "--progress-title", _("Unbundling objects"), NULL); ret = !!unbundle(the_repository, &header, bundle_fd, - &extra_index_pack_args, 0) || + &extra_index_pack_args, NULL) || list_bundle_refs(&header, argc, argv); bundle_header_release(&header); @@ -231,7 +235,7 @@ static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) int cmd_bundle(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -247,5 +251,5 @@ int cmd_bundle(int argc, packet_trace_identity("bundle"); - return !!fn(argc, argv, prefix); + return !!fn(argc, argv, prefix, repo); } diff --git a/builtin/cat-file.c b/builtin/cat-file.c index bfdfb51c7cb7b3..b13561cf73b11b 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -3,7 +3,10 @@ * * Copyright (C) Linus Torvalds, 2005 */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "convert.h" @@ -827,15 +830,16 @@ static int batch_objects(struct batch_options *opt) cb.seen = &seen; for_each_loose_object(batch_unordered_loose, &cb, 0); - for_each_packed_object(batch_unordered_packed, &cb, - FOR_EACH_OBJECT_PACK_ORDER); + for_each_packed_object(the_repository, batch_unordered_packed, + &cb, FOR_EACH_OBJECT_PACK_ORDER); oidset_clear(&seen); } else { struct oid_array sa = OID_ARRAY_INIT; for_each_loose_object(collect_loose_object, &sa, 0); - for_each_packed_object(collect_packed_object, &sa, 0); + for_each_packed_object(the_repository, collect_packed_object, + &sa, 0); oid_array_for_each_unique(&sa, batch_object_cb, &cb); diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index df00b5ee13adb8..be2cebe12152e3 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -35,7 +35,7 @@ static void check_mailmap(struct string_list *mailmap, const char *contact) mail = ident.mail_begin; maillen = ident.mail_end - ident.mail_begin; } else { - name = NULL; + name = ""; namelen = 0; mail = contact; maillen = strlen(contact); diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index e86d8ef980bd3b..5d80afeec05e3d 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -42,7 +42,7 @@ static int check_ref_format_branch(const char *arg) int nongit; setup_git_directory_gently(&nongit); - if (strbuf_check_branch_ref(&sb, arg) || + if (check_branch_ref(&sb, arg) || !skip_prefix(sb.buf, "refs/heads/", &name)) die("'%s' is not a valid branch name", arg); printf("%s\n", name); @@ -64,8 +64,8 @@ int cmd_check_ref_format(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(builtin_check_ref_format_usage); + show_usage_if_asked(argc, argv, + builtin_check_ref_format_usage); if (argc == 3 && !strcmp(argv[1], "--branch")) return check_ref_format_branch(argv[2]); diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index ff6cdccc21dfd2..da9345a44b84de 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "entry.h" @@ -126,9 +128,9 @@ int cmd_checkout__worker(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(checkout_worker_usage, - checkout_worker_options); + show_usage_with_options_if_asked(argc, argv, + checkout_worker_usage, + checkout_worker_options); git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, checkout_worker_options, diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 6dd38eb05d49d6..e30086c7d47189 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -4,7 +4,10 @@ * Copyright (C) 2005 Linus Torvalds * */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "gettext.h" @@ -247,9 +250,9 @@ int cmd_checkout_index(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_checkout_index_usage, - builtin_checkout_index_options); + show_usage_with_options_if_asked(argc, argv, + builtin_checkout_index_usage, + builtin_checkout_index_options); git_config(git_default_config, NULL); prefix_length = prefix ? strlen(prefix) : 0; diff --git a/builtin/checkout.c b/builtin/checkout.c index 9c30000d3afe28..01ea9ff8b28022 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "advice.h" #include "branch.h" @@ -742,7 +744,7 @@ static void setup_branch_path(struct branch_info *branch) &branch->oid, &branch->refname, 0)) repo_get_oid_committish(the_repository, branch->name, &branch->oid); - strbuf_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL); + copy_branchname(&buf, branch->name, INTERPRET_BRANCH_LOCAL); if (strcmp(buf.buf, branch->name)) { free(branch->name); branch->name = xstrdup(buf.buf); @@ -1716,7 +1718,7 @@ static struct option *add_common_switch_branch_options( N_("update ignored files (default)"), PARSE_OPT_NOCOMPLETE), OPT_BOOL(0, "ignore-other-worktrees", &opts->ignore_other_worktrees, - N_("do not check if another worktree is holding the given ref")), + N_("do not check if another worktree is using this branch")), OPT_END() }; struct option *newopts = parse_options_concat(prevopts, options); diff --git a/builtin/clean.c b/builtin/clean.c index 9c48dd02711c6e..053c94fc6bd12a 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -5,7 +5,10 @@ * * Based on git-clean.sh by Pavel Roskin */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "config.h" diff --git a/builtin/clone.c b/builtin/clone.c index e77339c84720f2..f14229abf450c0 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -7,7 +7,10 @@ * * Clone a repository into a different directory that does not yet exist. */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" @@ -53,42 +56,30 @@ * - dropping use-separate-remote and no-separate-remote compatibility * */ -static const char * const builtin_clone_usage[] = { - N_("git clone [<options>] [--] <repo> [<dir>]"), - NULL + +struct clone_opts { + int wants_head; + int detach; }; +#define CLONE_OPTS_INIT { \ + .wants_head = 1 /* default enabled */ \ +} static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1; static int option_local = -1, option_no_hardlinks, option_shared; -static int option_no_tags; +static int option_tags = 1; /* default enabled */ static int option_shallow_submodules; -static int option_reject_shallow = -1; /* unspecified */ static int config_reject_shallow = -1; /* unspecified */ -static int deepen; -static char *option_template, *option_depth, *option_since; -static char *option_origin = NULL; 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 const char *option_upload_pack = "git-upload-pack"; static int option_verbosity; -static int option_progress = -1; -static int option_sparse_checkout; -static enum transport_family family; -static struct string_list option_config = STRING_LIST_INIT_NODUP; static struct string_list option_required_reference = STRING_LIST_INIT_NODUP; static struct string_list option_optional_reference = STRING_LIST_INIT_NODUP; -static int option_dissociate; static int max_jobs = -1; static struct string_list option_recurse_submodules = STRING_LIST_INIT_NODUP; static struct list_objects_filter_options filter_options = LIST_OBJECTS_FILTER_INIT; -static int option_filter_submodules = -1; /* unspecified */ static int config_filter_submodules = -1; /* unspecified */ -static struct string_list server_options = STRING_LIST_INIT_NODUP; static int option_remote_submodules; -static const char *bundle_uri; static int recurse_submodules_cb(const struct option *opt, const char *arg, int unset) @@ -104,78 +95,6 @@ static int recurse_submodules_cb(const struct option *opt, return 0; } -static struct option builtin_clone_options[] = { - OPT__VERBOSITY(&option_verbosity), - OPT_BOOL(0, "progress", &option_progress, - N_("force progress reporting")), - OPT_BOOL(0, "reject-shallow", &option_reject_shallow, - N_("don't clone shallow repository")), - OPT_BOOL('n', "no-checkout", &option_no_checkout, - N_("don't create a checkout")), - OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")), - OPT_HIDDEN_BOOL(0, "naked", &option_bare, - N_("create a bare repository")), - OPT_BOOL(0, "mirror", &option_mirror, - N_("create a mirror repository (implies --bare)")), - OPT_BOOL('l', "local", &option_local, - N_("to clone from a local repository")), - OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, - N_("don't use local hardlinks, always copy")), - OPT_BOOL('s', "shared", &option_shared, - N_("setup as shared repository")), - { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules, - N_("pathspec"), N_("initialize submodules in the clone"), - PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." }, - OPT_ALIAS(0, "recursive", "recurse-submodules"), - OPT_INTEGER('j', "jobs", &max_jobs, - N_("number of submodules cloned in parallel")), - OPT_STRING(0, "template", &option_template, N_("template-directory"), - N_("directory from which templates will be used")), - OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"), - N_("reference repository")), - OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference, - N_("repo"), N_("reference repository")), - OPT_BOOL(0, "dissociate", &option_dissociate, - N_("use --reference only while cloning")), - OPT_STRING('o', "origin", &option_origin, N_("name"), - N_("use <name> instead of 'origin' to track upstream")), - OPT_STRING('b', "branch", &option_branch, N_("branch"), - N_("checkout <branch> instead of the remote's HEAD")), - OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), - N_("path to git-upload-pack on the remote")), - OPT_STRING(0, "depth", &option_depth, N_("depth"), - N_("create a shallow clone of that depth")), - OPT_STRING(0, "shallow-since", &option_since, N_("time"), - N_("create a shallow clone since a specific time")), - OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("revision"), - N_("deepen history of shallow clone, excluding rev")), - OPT_BOOL(0, "single-branch", &option_single_branch, - N_("clone only one branch, HEAD or --branch")), - OPT_BOOL(0, "no-tags", &option_no_tags, - N_("don't clone any tags, and make later fetches not to follow them")), - OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules, - 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, - N_("server-specific"), N_("option to transmit")), - OPT_IPVERSION(&family), - OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), - OPT_BOOL(0, "also-filter-submodules", &option_filter_submodules, - N_("apply partial clone filters to submodules")), - OPT_BOOL(0, "remote-submodules", &option_remote_submodules, - N_("any cloned submodules will use their remote-tracking branch")), - OPT_BOOL(0, "sparse", &option_sparse_checkout, - N_("initialize sparse-checkout file to include only files at root")), - OPT_STRING(0, "bundle-uri", &bundle_uri, - N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")), - OPT_END() -}; - static const char *get_repo_path_1(struct strbuf *path, int *is_bundle) { static const char *suffix[] = { "/.git", "", ".git/.git", ".git" }; @@ -518,51 +437,31 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch return ref; } -static struct ref *wanted_peer_refs(const struct ref *refs, - struct refspec *refspec) +static struct ref *wanted_peer_refs(struct clone_opts *opts, + const struct ref *refs, + struct refspec *refspec) { - struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD")); - struct ref *local_refs = head; - struct ref **tail = head ? &head->next : &local_refs; - struct refspec_item tag_refspec; - - refspec_item_init(&tag_refspec, TAG_REFSPEC, 0); - - if (option_single_branch) { - struct ref *remote_head = NULL; - - if (!option_branch) - remote_head = guess_remote_head(head, refs, 0); - else { - free_one_ref(head); - local_refs = head = NULL; - tail = &local_refs; - remote_head = copy_ref(find_remote_branch(refs, option_branch)); - } - - if (!remote_head && option_branch) - warning(_("Could not find remote branch %s to clone."), - option_branch); - else { - int i; - for (i = 0; i < refspec->nr; i++) - get_fetch_map(remote_head, &refspec->items[i], - &tail, 0); - - /* if --branch=tag, pull the requested tag explicitly */ - get_fetch_map(remote_head, &tag_refspec, &tail, 0); - } - free_refs(remote_head); - } else { - int i; - for (i = 0; i < refspec->nr; i++) - get_fetch_map(refs, &refspec->items[i], &tail, 0); + struct ref *local_refs = NULL; + struct ref **tail = &local_refs; + struct ref *to_free = NULL; + + if (opts->wants_head) { + struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD")); + if (head) + tail_link_ref(head, &tail); + if (option_single_branch) + refs = to_free = guess_remote_head(head, refs, 0); + } else if (option_single_branch) { + local_refs = NULL; + tail = &local_refs; + refs = to_free = copy_ref(find_remote_branch(refs, option_branch)); } - if (!option_mirror && !option_single_branch && !option_no_tags) - get_fetch_map(refs, &tag_refspec, &tail, 0); + for (size_t i = 0; i < refspec->nr; i++) + get_fetch_map(refs, &refspec->items[i], &tail, 0); + + free_one_ref(to_free); - refspec_item_clear(&tag_refspec); return local_refs; } @@ -574,7 +473,7 @@ static void write_remote_refs(const struct ref *local_refs) struct strbuf err = STRBUF_INIT; t = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + REF_TRANSACTION_FLAG_INITIAL, &err); if (!t) die("%s", err.buf); @@ -586,7 +485,7 @@ static void write_remote_refs(const struct ref *local_refs) die("%s", err.buf); } - if (initial_ref_transaction_commit(t, &err)) + if (ref_transaction_commit(t, &err)) die("%s", err.buf); strbuf_release(&err); @@ -651,7 +550,7 @@ static void update_remote_refs(const struct ref *refs, if (refs) { write_remote_refs(mapped_refs); - if (option_single_branch && !option_no_tags) + if (option_single_branch && option_tags) write_followtags(refs, msg); } @@ -667,11 +566,11 @@ static void update_remote_refs(const struct ref *refs, } } -static void update_head(const struct ref *our, const struct ref *remote, +static void update_head(struct clone_opts *opts, const struct ref *our, const struct ref *remote, const char *unborn, const char *msg) { const char *head; - if (our && skip_prefix(our->name, "refs/heads/", &head)) { + if (our && !opts->detach && skip_prefix(our->name, "refs/heads/", &head)) { /* Local default branch link */ if (refs_update_symref(get_main_ref_store(the_repository), "HEAD", our->name, NULL) < 0) die(_("unable to update HEAD")); @@ -682,8 +581,9 @@ static void update_head(const struct ref *our, const struct ref *remote, install_branch_config(0, head, remote_name, our->name); } } else if (our) { - struct commit *c = lookup_commit_reference(the_repository, - &our->old_oid); + struct commit *c = lookup_commit_or_die(&our->old_oid, + our->name); + /* --branch specifies a non-branch (i.e. tags), detach HEAD */ refs_update_ref(get_main_ref_store(the_repository), msg, "HEAD", &c->object.oid, NULL, REF_NO_DEREF, @@ -935,7 +835,7 @@ static void write_refspec_config(const char *src_ref_prefix, static void dissociate_from_references(void) { - char *alternates = git_pathdup("objects/info/alternates"); + char *alternates = repo_git_path(the_repository, "objects/info/alternates"); if (!access(alternates, F_OK)) { struct child_process cmd = CHILD_PROCESS_INIT; @@ -986,10 +886,108 @@ int cmd_clone(int argc, int hash_algo; enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN; const int do_not_override_repo_unix_permissions = -1; + int option_reject_shallow = -1; /* unspecified */ + int deepen = 0; + char *option_template = NULL, *option_depth = NULL, *option_since = NULL; + char *option_origin = NULL; + struct string_list option_not = STRING_LIST_INIT_NODUP; + const char *real_git_dir = NULL; + const char *ref_format = NULL; + const char *option_upload_pack = "git-upload-pack"; + int option_progress = -1; + int option_sparse_checkout = 0; + enum transport_family family = TRANSPORT_FAMILY_ALL; + struct string_list option_config = STRING_LIST_INIT_DUP; + int option_dissociate = 0; + int option_filter_submodules = -1; /* unspecified */ + struct string_list server_options = STRING_LIST_INIT_NODUP; + const char *bundle_uri = NULL; + char *option_rev = NULL; + + struct clone_opts opts = CLONE_OPTS_INIT; struct transport_ls_refs_options transport_ls_refs_options = TRANSPORT_LS_REFS_OPTIONS_INIT; + struct option builtin_clone_options[] = { + OPT__VERBOSITY(&option_verbosity), + OPT_BOOL(0, "progress", &option_progress, + N_("force progress reporting")), + OPT_BOOL(0, "reject-shallow", &option_reject_shallow, + N_("don't clone shallow repository")), + OPT_BOOL('n', "no-checkout", &option_no_checkout, + N_("don't create a checkout")), + OPT_BOOL(0, "bare", &option_bare, N_("create a bare repository")), + OPT_HIDDEN_BOOL(0, "naked", &option_bare, + N_("create a bare repository")), + OPT_BOOL(0, "mirror", &option_mirror, + N_("create a mirror repository (implies --bare)")), + OPT_BOOL('l', "local", &option_local, + N_("to clone from a local repository")), + OPT_BOOL(0, "no-hardlinks", &option_no_hardlinks, + N_("don't use local hardlinks, always copy")), + OPT_BOOL('s', "shared", &option_shared, + N_("setup as shared repository")), + { OPTION_CALLBACK, 0, "recurse-submodules", &option_recurse_submodules, + N_("pathspec"), N_("initialize submodules in the clone"), + PARSE_OPT_OPTARG, recurse_submodules_cb, (intptr_t)"." }, + OPT_ALIAS(0, "recursive", "recurse-submodules"), + OPT_INTEGER('j', "jobs", &max_jobs, + N_("number of submodules cloned in parallel")), + OPT_STRING(0, "template", &option_template, N_("template-directory"), + N_("directory from which templates will be used")), + OPT_STRING_LIST(0, "reference", &option_required_reference, N_("repo"), + N_("reference repository")), + OPT_STRING_LIST(0, "reference-if-able", &option_optional_reference, + N_("repo"), N_("reference repository")), + OPT_BOOL(0, "dissociate", &option_dissociate, + N_("use --reference only while cloning")), + OPT_STRING('o', "origin", &option_origin, N_("name"), + N_("use <name> instead of 'origin' to track upstream")), + OPT_STRING('b', "branch", &option_branch, N_("branch"), + N_("checkout <branch> instead of the remote's HEAD")), + OPT_STRING(0, "revision", &option_rev, N_("rev"), + N_("clone single revision <rev> and check out")), + OPT_STRING('u', "upload-pack", &option_upload_pack, N_("path"), + N_("path to git-upload-pack on the remote")), + OPT_STRING(0, "depth", &option_depth, N_("depth"), + N_("create a shallow clone of that depth")), + OPT_STRING(0, "shallow-since", &option_since, N_("time"), + N_("create a shallow clone since a specific time")), + OPT_STRING_LIST(0, "shallow-exclude", &option_not, N_("ref"), + N_("deepen history of shallow clone, excluding ref")), + OPT_BOOL(0, "single-branch", &option_single_branch, + N_("clone only one branch, HEAD or --branch")), + OPT_BOOL(0, "tags", &option_tags, + N_("clone tags, and make later fetches not to follow them")), + OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules, + 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, + N_("server-specific"), N_("option to transmit")), + OPT_IPVERSION(&family), + OPT_PARSE_LIST_OBJECTS_FILTER(&filter_options), + OPT_BOOL(0, "also-filter-submodules", &option_filter_submodules, + N_("apply partial clone filters to submodules")), + OPT_BOOL(0, "remote-submodules", &option_remote_submodules, + N_("any cloned submodules will use their remote-tracking branch")), + OPT_BOOL(0, "sparse", &option_sparse_checkout, + N_("initialize sparse-checkout file to include only files at root")), + OPT_STRING(0, "bundle-uri", &bundle_uri, + N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")), + OPT_END() + }; + + const char * const builtin_clone_usage[] = { + N_("git clone [<options>] [--] <repo> [<dir>]"), + NULL + }; + packet_trace_identity("clone"); git_config(git_clone_config, NULL); @@ -1016,8 +1014,10 @@ int cmd_clone(int argc, die(_("unknown ref storage format '%s'"), ref_format); } - if (option_mirror) + if (option_mirror) { option_bare = 1; + option_tags = 0; + } if (option_bare) { if (real_git_dir) @@ -1135,8 +1135,8 @@ int cmd_clone(int argc, for_each_string_list_item(item, &option_recurse_submodules) { strbuf_addf(&sb, "submodule.active=%s", item->string); - string_list_append(&option_config, - strbuf_detach(&sb, NULL)); + string_list_append(&option_config, sb.buf); + strbuf_reset(&sb); } if (!git_config_get_bool("submodule.stickyRecursiveClone", &val) && @@ -1158,6 +1158,8 @@ int cmd_clone(int argc, string_list_append(&option_config, "submodule.alternateErrorStrategy=info"); } + + strbuf_release(&sb); } /* @@ -1217,7 +1219,7 @@ int cmd_clone(int argc, strbuf_reset(&buf); strbuf_addf(&buf, "%s/refs", git_dir); - safe_create_dir(buf.buf, 1); + safe_create_dir(the_repository, buf.buf, 1); /* * additional config can be injected with -c, make sure it's included @@ -1282,7 +1284,7 @@ int cmd_clone(int argc, strbuf_addstr(&branch_top, src_ref_prefix); git_config_set("core.bare", "true"); - } else { + } else if (!option_rev) { strbuf_addf(&branch_top, "refs/remotes/%s/", remote_name); } @@ -1290,7 +1292,7 @@ int cmd_clone(int argc, git_config_set(key.buf, repo); strbuf_reset(&key); - if (option_no_tags) { + if (!option_tags) { strbuf_addf(&key, "remote.%s.tagOpt", remote_name); git_config_set(key.buf, "--no-tags"); strbuf_reset(&key); @@ -1301,8 +1303,9 @@ int cmd_clone(int argc, remote = remote_get_early(remote_name); - refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix, - branch_top.buf); + if (!option_rev) + refspec_appendf(&remote->fetch, "+%s*:%s*", src_ref_prefix, + branch_top.buf); path = get_repo_path(remote->url.v[0], &is_bundle); is_local = option_local != 0 && path && !is_bundle; @@ -1345,6 +1348,11 @@ int cmd_clone(int argc, transport_set_option(transport, TRANS_OPT_KEEP, "yes"); + die_for_incompatible_opt2(!!option_rev, "--revision", + !!option_branch, "--branch"); + die_for_incompatible_opt2(!!option_rev, "--revision", + option_mirror, "--mirror"); + if (reject_shallow) transport_set_option(transport, TRANS_OPT_REJECT_SHALLOW, "1"); if (option_depth) @@ -1356,9 +1364,13 @@ int cmd_clone(int argc, if (option_not.nr) transport_set_option(transport, TRANS_OPT_DEEPEN_NOT, (const char *)&option_not); - if (option_single_branch) + if (option_single_branch) { transport_set_option(transport, TRANS_OPT_FOLLOWTAGS, "1"); + if (option_branch) + opts.wants_head = 0; + } + if (option_upload_pack) transport_set_option(transport, TRANS_OPT_UPLOADPACK, option_upload_pack); @@ -1377,15 +1389,38 @@ int cmd_clone(int argc, 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"); + if (option_rev) { + option_tags = 0; + option_single_branch = 0; + opts.wants_head = 0; + opts.detach = 1; + + refspec_append(&remote->fetch, option_rev); + } + + if (option_tags || option_branch) + /* + * Add tags refspec when user asked for tags (implicitly) or + * specified --branch, whose argument might be a tag. + */ + refspec_append(&remote->fetch, TAG_REFSPEC); + 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/"); + + /* + * As part of transport_get_remote_refs() the server tells us the hash + * algorithm, which we require to initialize the repo. But calling that + * function without any ref prefix, will cause the server to announce + * all known refs. If the argument passed to --revision was a hex oid, + * ref_prefixes will be empty so we fall back to asking about HEAD to + * reduce traffic from the server. + */ + if (opts.wants_head || transport_ls_refs_options.ref_prefixes.nr == 0) + strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); refs = transport_get_remote_refs(transport, &transport_ls_refs_options); @@ -1403,8 +1438,17 @@ int cmd_clone(int argc, * data from the --bundle-uri option. */ if (bundle_uri) { + struct remote_state *state; int has_heuristic = 0; + /* + * We need to save the remote state as our remote's lifetime is + * tied to it. + */ + state = the_repository->remote_state; + the_repository->remote_state = NULL; + repo_clear(the_repository); + /* At this point, we need the_repository to match the cloned repo. */ if (repo_init(the_repository, git_dir, work_tree)) warning(_("failed to initialize the repo, skipping bundle URI")); @@ -1413,6 +1457,10 @@ int cmd_clone(int argc, bundle_uri); else if (has_heuristic) git_config_set_gently("fetch.bundleuri", bundle_uri); + + remote_state_clear(the_repository->remote_state); + free(the_repository->remote_state); + the_repository->remote_state = state; } else { /* * Populate transport->got_remote_bundle_uri and @@ -1422,12 +1470,26 @@ int cmd_clone(int argc, if (transport->bundles && hashmap_get_size(&transport->bundles->bundles)) { + struct remote_state *state; + + /* + * We need to save the remote state as our remote's + * lifetime is tied to it. + */ + state = the_repository->remote_state; + the_repository->remote_state = NULL; + repo_clear(the_repository); + /* At this point, we need the_repository to match the cloned repo. */ if (repo_init(the_repository, git_dir, work_tree)) warning(_("failed to initialize the repo, skipping bundle URI")); else if (fetch_bundle_list(the_repository, transport->bundles)) warning(_("failed to fetch advertised bundles")); + + remote_state_clear(the_repository->remote_state); + free(the_repository->remote_state); + the_repository->remote_state = state; } else { clear_bundle_list(transport->bundles); FREE_AND_NULL(transport->bundles); @@ -1435,7 +1497,7 @@ int cmd_clone(int argc, } if (refs) - mapped_refs = wanted_peer_refs(refs, &remote->fetch); + mapped_refs = wanted_peer_refs(&opts, refs, &remote->fetch); if (mapped_refs) { /* @@ -1468,6 +1530,11 @@ int cmd_clone(int argc, if (!our_head_points_at) die(_("Remote branch %s not found in upstream %s"), option_branch, remote_name); + } else if (option_rev) { + our_head_points_at = mapped_refs; + if (!our_head_points_at) + die(_("Remote revision %s not found in upstream %s"), + option_rev, remote_name); } else if (remote_head_points_at) { our_head_points_at = remote_head_points_at; } else if (remote_head) { @@ -1506,8 +1573,9 @@ int cmd_clone(int argc, free(to_free); } - write_refspec_config(src_ref_prefix, our_head_points_at, - remote_head_points_at, &branch_top); + if (!option_rev) + write_refspec_config(src_ref_prefix, our_head_points_at, + remote_head_points_at, &branch_top); if (filter_options.choice) partial_clone_register(remote_name, &filter_options); @@ -1523,7 +1591,7 @@ int cmd_clone(int argc, branch_top.buf, reflog_msg.buf, transport, !is_local); - update_head(our_head_points_at, remote_head, unborn_head, reflog_msg.buf); + update_head(&opts, our_head_points_at, remote_head, unborn_head, reflog_msg.buf); /* * We want to show progress for recursive submodule clones iff @@ -1548,6 +1616,10 @@ int cmd_clone(int argc, err = checkout(submodule_progress, filter_submodules, ref_storage_format); + string_list_clear(&option_not, 0); + string_list_clear(&option_config, 0); + string_list_clear(&server_options, 0); + free(remote_name); strbuf_release(&reflog_msg); strbuf_release(&branch_top); @@ -1559,7 +1631,6 @@ int cmd_clone(int argc, free(dir); free(path); free(repo_to_free); - UNLEAK(repo); junk_mode = JUNK_LEAVE_ALL; transport_ls_refs_options_release(&transport_ls_refs_options); diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 7c991db6eb48ad..8ca75262c59c48 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -62,7 +62,8 @@ static struct option *add_common_options(struct option *to) return parse_options_concat(common_opts, to); } -static int graph_verify(int argc, const char **argv, const char *prefix) +static int graph_verify(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct commit_graph *graph = NULL; struct object_directory *odb = NULL; @@ -214,7 +215,8 @@ static int git_commit_graph_write_config(const char *var, const char *value, return 0; } -static int graph_write(int argc, const char **argv, const char *prefix) +static int graph_write(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct string_list pack_indexes = STRING_LIST_INIT_DUP; struct strbuf buf = STRBUF_INIT; @@ -303,6 +305,7 @@ static int graph_write(int argc, const char **argv, const char *prefix) oidset_init(&commits, 0); if (opts.progress) progress = start_delayed_progress( + the_repository, _("Collecting commits from input"), 0); while (strbuf_getline(&buf, stdin) != EOF) { @@ -333,7 +336,7 @@ static int graph_write(int argc, const char **argv, const char *prefix) int cmd_commit_graph(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_commit_graph_options[] = { @@ -352,5 +355,5 @@ int cmd_commit_graph(int argc, builtin_commit_graph_usage, 0); FREE_AND_NULL(options); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 2ca1a57ebbb230..38457600a4e422 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -119,8 +119,8 @@ int cmd_commit_tree(int argc, git_config(git_default_config, NULL); - if (argc < 2 || !strcmp(argv[1], "-h")) - usage_with_options(commit_tree_usage, options); + show_usage_with_options_if_asked(argc, argv, + commit_tree_usage, options); argc = parse_options(argc, argv, prefix, options, commit_tree_usage, 0); diff --git a/builtin/commit.c b/builtin/commit.c index 8db4e9df0c9944..2f459682221d6a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -4,7 +4,10 @@ * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com> * Based on git-commit.sh by Junio C Hamano and Linus Torvalds */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "advice.h" #include "config.h" @@ -41,7 +44,7 @@ #include "trailer.h" static const char * const builtin_commit_usage[] = { - N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" + N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" @@ -135,7 +138,7 @@ static struct strvec trailer_args = STRVEC_INIT; * is specified explicitly. */ static enum commit_msg_cleanup_mode cleanup_mode; -static char *cleanup_arg; +static char *cleanup_config; static enum commit_whence whence; static int use_editor = 1, include_status = 1; @@ -349,6 +352,7 @@ static const char *prepare_index(const char **argv, const char *prefix, struct pathspec pathspec; int refresh_flags = REFRESH_QUIET; const char *ret; + char *path = NULL; if (is_status) refresh_flags |= REFRESH_UNMERGED; @@ -521,9 +525,9 @@ static const char *prepare_index(const char **argv, const char *prefix, if (write_locked_index(the_repository->index, &index_lock, 0)) die(_("unable to write new index file")); - hold_lock_file_for_update(&false_lock, - git_path("next-index-%"PRIuMAX, - (uintmax_t) getpid()), + path = repo_git_path(the_repository, "next-index-%"PRIuMAX, + (uintmax_t) getpid()); + hold_lock_file_for_update(&false_lock, path, LOCK_DIE_ON_ERROR); create_base_index(current_head); @@ -539,6 +543,7 @@ static const char *prepare_index(const char **argv, const char *prefix, out: string_list_clear(&partial, 0); clear_pathspec(&pathspec); + free(path); return ret; } @@ -728,6 +733,13 @@ static void prepare_amend_commit(struct commit *commit, struct strbuf *sb, repo_unuse_commit_buffer(the_repository, commit, buffer); } +static void change_data_free(void *util, const char *str UNUSED) +{ + struct wt_status_change_data *d = util; + free(d->rename_source); + free(d); +} + static int prepare_to_commit(const char *index_file, const char *prefix, struct commit *current_head, struct wt_status *s, @@ -991,7 +1003,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, s->use_color = 0; committable = run_status(s->fp, index_file, prefix, 1, s); s->use_color = saved_color_setting; - string_list_clear(&s->change, 1); + string_list_clear_func(&s->change, change_data_free); } else { struct object_id oid; const char *parent = "HEAD"; @@ -1380,8 +1392,6 @@ static int parse_and_validate_options(int argc, const char *argv[], if (0 <= edit_flag) use_editor = edit_flag; - cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor); - handle_untracked_files_arg(s); if (all && argc > 0) @@ -1551,8 +1561,8 @@ struct repository *repo UNUSED) OPT_END(), }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_status_usage, builtin_status_options); + show_usage_with_options_if_asked(argc, argv, + builtin_status_usage, builtin_status_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -1629,8 +1639,10 @@ static int git_commit_config(const char *k, const char *v, include_status = git_config_bool(k, v); return 0; } - if (!strcmp(k, "commit.cleanup")) - return git_config_string(&cleanup_arg, k, v); + if (!strcmp(k, "commit.cleanup")) { + FREE_AND_NULL(cleanup_config); + return git_config_string(&cleanup_config, k, v); + } if (!strcmp(k, "commit.gpgsign")) { sign_commit = git_config_bool(k, v) ? "" : NULL; return 0; @@ -1651,6 +1663,7 @@ int cmd_commit(int argc, struct repository *repo UNUSED) { static struct wt_status s; + static const char *cleanup_arg = NULL; static struct option builtin_commit_options[] = { OPT__QUIET(&quiet, N_("suppress summary after successful commit")), OPT__VERBOSE(&verbose, N_("show diff in commit message template")), @@ -1725,8 +1738,8 @@ int cmd_commit(int argc, struct strbuf err = STRBUF_INIT; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_commit_usage, builtin_commit_options); + show_usage_with_options_if_asked(argc, argv, + builtin_commit_usage, builtin_commit_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -1750,6 +1763,12 @@ int cmd_commit(int argc, if (verbose == -1) verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose; + if (cleanup_arg) { + free(cleanup_config); + cleanup_config = xstrdup(cleanup_arg); + } + cleanup_mode = get_cleanup_mode(cleanup_config, use_editor); + if (dry_run) return dry_run_commit(argv, prefix, current_head, &s); index_file = prepare_index(argv, prefix, current_head, 0); diff --git a/builtin/config.c b/builtin/config.c index d8fd3def0efdae..53a90094e31454 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -19,7 +19,7 @@ static const char *const builtin_config_usage[] = { N_("git config list [<file-option>] [<display-option>] [--includes]"), N_("git config get [<file-option>] [<display-option>] [--includes] [--all] [--regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>"), N_("git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), - N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), + N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name>"), N_("git config rename-section [<file-option>] <old-name> <new-name>"), N_("git config remove-section [<file-option>] <name>"), N_("git config edit [<file-option>]"), @@ -43,7 +43,7 @@ static const char *const builtin_config_set_usage[] = { }; static const char *const builtin_config_unset_usage[] = { - N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name> <value>"), + N_("git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] <name>"), NULL }; @@ -775,13 +775,13 @@ static void location_options_init(struct config_location_options *opts, opts->source.file = opts->file_to_free = git_system_config(); opts->source.scope = CONFIG_SCOPE_SYSTEM; } else if (opts->use_local_config) { - opts->source.file = opts->file_to_free = git_pathdup("config"); + opts->source.file = opts->file_to_free = repo_git_path(the_repository, "config"); opts->source.scope = CONFIG_SCOPE_LOCAL; } else if (opts->use_worktree_config) { struct worktree **worktrees = get_worktrees(); if (the_repository->repository_format_worktree_config) opts->source.file = opts->file_to_free = - git_pathdup("config.worktree"); + repo_git_path(the_repository, "config.worktree"); else if (worktrees[0] && worktrees[1]) die(_("--worktree cannot be used with multiple " "working trees unless the config\n" @@ -790,7 +790,7 @@ static void location_options_init(struct config_location_options *opts, "section in \"git help worktree\" for details")); else opts->source.file = opts->file_to_free = - git_pathdup("config"); + repo_git_path(the_repository, "config"); opts->source.scope = CONFIG_SCOPE_LOCAL; free_worktrees(worktrees); } else if (opts->source.file) { @@ -826,7 +826,8 @@ static void display_options_init(struct config_display_options *opts) } } -static int cmd_config_list(int argc, const char **argv, const char *prefix) +static int cmd_config_list(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT; @@ -861,7 +862,8 @@ static int cmd_config_list(int argc, const char **argv, const char *prefix) return 0; } -static int cmd_config_get(int argc, const char **argv, const char *prefix) +static int cmd_config_get(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; struct config_display_options display_opts = CONFIG_DISPLAY_OPTIONS_INIT; @@ -915,7 +917,8 @@ static int cmd_config_get(int argc, const char **argv, const char *prefix) return ret; } -static int cmd_config_set(int argc, const char **argv, const char *prefix) +static int cmd_config_set(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; const char *value_pattern = NULL, *comment_arg = NULL; @@ -973,7 +976,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix) return ret; } -static int cmd_config_unset(int argc, const char **argv, const char *prefix) +static int cmd_config_unset(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; const char *value_pattern = NULL; @@ -1010,7 +1014,8 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix) return ret; } -static int cmd_config_rename_section(int argc, const char **argv, const char *prefix) +static int cmd_config_rename_section(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; struct option opts[] = { @@ -1039,7 +1044,8 @@ static int cmd_config_rename_section(int argc, const char **argv, const char *pr return ret; } -static int cmd_config_remove_section(int argc, const char **argv, const char *prefix) +static int cmd_config_remove_section(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; struct option opts[] = { @@ -1081,7 +1087,7 @@ static int show_editor(struct config_location_options *opts) git_config(git_default_config, NULL); config_file = opts->source.file ? xstrdup(opts->source.file) : - git_pathdup("config"); + repo_git_path(the_repository, "config"); if (opts->use_global_config) { int fd = open(config_file, O_CREAT | O_EXCL | O_WRONLY, 0666); if (fd >= 0) { @@ -1099,7 +1105,8 @@ static int show_editor(struct config_location_options *opts) return 0; } -static int cmd_config_edit(int argc, const char **argv, const char *prefix) +static int cmd_config_edit(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct config_location_options location_opts = CONFIG_LOCATION_OPTIONS_INIT; struct option opts[] = { @@ -1395,7 +1402,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) int cmd_config(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *subcommand = NULL; struct option subcommand_opts[] = { @@ -1422,7 +1429,7 @@ int cmd_config(int argc, if (subcommand) { argc = parse_options(argc, argv, prefix, subcommand_opts, builtin_config_usage, PARSE_OPT_SUBCOMMAND_OPTIONAL|PARSE_OPT_KEEP_UNKNOWN_OPT); - return subcommand(argc, argv, prefix); + return subcommand(argc, argv, prefix, repo); } return cmd_config_actions(argc, argv, prefix); diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 04d80887e0eb98..1e89148ed742a8 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -67,7 +67,7 @@ static int count_loose(const struct object_id *oid, const char *path, else { loose_size += on_disk_bytes(st); loose++; - if (verbose && has_object_pack(oid)) + if (verbose && has_object_pack(the_repository, oid)) packed_loose++; } return 0; diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index bc22f5c6d2413d..e707618e743942 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -142,9 +142,9 @@ static void serve_one_client(FILE *in, FILE *out) fprintf(out, "username=%s\n", e->item.username); if (e->item.password) fprintf(out, "password=%s\n", e->item.password); - if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.authtype) + if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_RESPONSE) && e->item.authtype) fprintf(out, "authtype=%s\n", e->item.authtype); - if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.credential) + if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_RESPONSE) && e->item.credential) fprintf(out, "credential=%s\n", e->item.credential); if (e->item.password_expiry_utc != TIME_MAX) fprintf(out, "password_expiry_utc=%"PRItime"\n", diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c index 5de8b9123bf07c..7f733cb756e03c 100644 --- a/builtin/credential-cache.c +++ b/builtin/credential-cache.c @@ -30,7 +30,7 @@ static int connection_fatally_broken(int error) static int connection_closed(int error) { - return (error == ECONNRESET); + return error == ECONNRESET || error == ECONNABORTED; } static int connection_fatally_broken(int error) @@ -189,7 +189,8 @@ int cmd_credential_cache(int argc, #else -int cmd_credential_cache(int argc, const char **argv, const char *prefix) +int cmd_credential_cache(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { const char * const usage[] = { "git credential-cache [options] <action>", diff --git a/builtin/credential.c b/builtin/credential.c index 14c8c6608b2fbd..2e11b15dde3e85 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -18,7 +18,8 @@ int cmd_credential(int argc, git_config(git_default_config, NULL); - if (argc != 2 || !strcmp(argv[1], "-h")) + show_usage_if_asked(argc, argv, usage_msg); + if (argc != 2) usage(usage_msg); op = argv[1]; @@ -32,15 +33,15 @@ int cmd_credential(int argc, die("unable to read credential from stdin"); if (!strcmp(op, "fill")) { - credential_fill(&c, 0); + credential_fill(the_repository, &c, 0); credential_next_state(&c); credential_write(&c, stdout, CREDENTIAL_OP_RESPONSE); } else if (!strcmp(op, "approve")) { credential_set_all_capabilities(&c, CREDENTIAL_OP_HELPER); - credential_approve(&c); + credential_approve(the_repository, &c); } else if (!strcmp(op, "reject")) { credential_set_all_capabilities(&c, CREDENTIAL_OP_HELPER); - credential_reject(&c); + credential_reject(the_repository, &c); } else { usage(usage_msg); } diff --git a/builtin/describe.c b/builtin/describe.c index 7330a77b38ea7e..e2e73f3d757cab 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "environment.h" @@ -366,6 +368,13 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) struct commit_name **slot; seen_commits++; + + if (match_cnt == max_candidates || + match_cnt == hashmap_get_size(&names)) { + gave_up_on = c; + break; + } + slot = commit_names_peek(&commit_names, c); n = slot ? *slot : NULL; if (n) { @@ -381,10 +390,6 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) if (n->prio == 2) annotated_cnt++; } - else { - gave_up_on = c; - break; - } } for (cur_match = 0; cur_match < match_cnt; cur_match++) { struct possible_tag *t = &all_matches[cur_match]; @@ -470,9 +475,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) fprintf(stderr, _("traversed %lu commits\n"), seen_commits); if (gave_up_on) { fprintf(stderr, - _("more than %i tags found; listed %i most recent\n" - "gave up search at %s\n"), - max_candidates, max_candidates, + _("found %i tags; gave up search at %s\n"), + max_candidates, oid_to_hex(&gave_up_on->object.oid)); } } diff --git a/builtin/diagnose.c b/builtin/diagnose.c index 66a22d918e68a4..33c39bd5981f22 100644 --- a/builtin/diagnose.c +++ b/builtin/diagnose.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -58,7 +60,7 @@ int cmd_diagnose(int argc, } /* Prepare diagnostics */ - if (create_diagnostics_archive(&zip_path, mode)) + if (create_diagnostics_archive(the_repository, &zip_path, mode)) die_errno(_("unable to create diagnostics archive %s"), zip_path.buf); diff --git a/builtin/diff-files.c b/builtin/diff-files.c index e0e0ccec2343a2..99b1749723bc67 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -3,7 +3,10 @@ * * Copyright (C) Linus Torvalds, 2005 */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "diff.h" @@ -26,8 +29,7 @@ int cmd_diff_files(int argc, int result; unsigned options = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(diff_files_usage); + show_usage_if_asked(argc, argv, diff_files_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ diff --git a/builtin/diff-index.c b/builtin/diff-index.c index ad503624c027df..81c0bc8ed7c6be 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "diff.h" @@ -24,8 +26,7 @@ int cmd_diff_index(int argc, int i; int result; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(diff_cache_usage); + show_usage_if_asked(argc, argv, diff_cache_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 4b6656bb9f79a6..e31cc797fe1e6e 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "diff.h" @@ -121,8 +122,7 @@ int cmd_diff_tree(int argc, int read_stdin = 0; int merge_base = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(diff_tree_usage); + show_usage_if_asked(argc, argv, diff_tree_usage); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ diff --git a/builtin/diff.c b/builtin/diff.c index dca52d4221ed19..a4fffee42c6c8c 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -3,7 +3,10 @@ * * Copyright (c) 2006 Junio C Hamano */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "ewah/ewok.h" @@ -628,6 +631,5 @@ int cmd_diff(int argc, release_revisions(&rev); object_array_clear(&ent); symdiff_release(&sdiff); - UNLEAK(blob); return result; } diff --git a/builtin/difftool.c b/builtin/difftool.c index 4b416743ffd040..41cd00066cc58a 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -11,7 +11,7 @@ * * Copyright (C) 2016 Johannes Schindelin */ -#define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" @@ -34,18 +34,27 @@ #include "entry.h" #include "setup.h" -static int trust_exit_code; - static const char *const builtin_difftool_usage[] = { N_("git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]"), NULL }; +struct difftool_options { + int has_symlinks; + int symlinks; + int trust_exit_code; +}; + static int difftool_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { + struct difftool_options *dt_options = (struct difftool_options *)cb; if (!strcmp(var, "difftool.trustexitcode")) { - trust_exit_code = git_config_bool(var, value); + dt_options->trust_exit_code = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.symlinks")) { + dt_options->has_symlinks = git_config_bool(var, value); return 0; } @@ -61,7 +70,8 @@ static int print_tool_help(void) return run_command(&cmd); } -static int parse_index_info(char *p, int *mode1, int *mode2, +static int parse_index_info(struct repository *repo, + char *p, int *mode1, int *mode2, struct object_id *oid1, struct object_id *oid2, char *status) { @@ -73,11 +83,11 @@ static int parse_index_info(char *p, int *mode1, int *mode2, *mode2 = (int)strtol(p + 1, &p, 8); if (*p != ' ') return error("expected ' ', got '%c'", *p); - if (parse_oid_hex(++p, oid1, (const char **)&p)) + if (parse_oid_hex_algop(++p, oid1, (const char **)&p, repo->hash_algo)) return error("expected object ID, got '%s'", p); if (*p != ' ') return error("expected ' ', got '%c'", *p); - if (parse_oid_hex(++p, oid2, (const char **)&p)) + if (parse_oid_hex_algop(++p, oid2, (const char **)&p, repo->hash_algo)) return error("expected object ID, got '%s'", p); if (*p != ' ') return error("expected ' ', got '%c'", *p); @@ -104,7 +114,8 @@ static void add_path(struct strbuf *buf, size_t base_len, const char *path) /* * Determine whether we can simply reuse the file in the worktree. */ -static int use_wt_file(const char *workdir, const char *name, +static int use_wt_file(struct repository *repo, + const char *workdir, const char *name, struct object_id *oid) { struct strbuf buf = STRBUF_INIT; @@ -119,7 +130,7 @@ static int use_wt_file(const char *workdir, const char *name, int fd = open(buf.buf, O_RDONLY); if (fd >= 0 && - !index_fd(the_repository->index, &wt_oid, fd, &st, OBJ_BLOB, name, 0)) { + !index_fd(repo->index, &wt_oid, fd, &st, OBJ_BLOB, name, 0)) { if (is_null_oid(oid)) { oidcpy(oid, &wt_oid); use = 1; @@ -210,13 +221,14 @@ static int path_entry_cmp(const void *cmp_data UNUSED, return strcmp(a->path, key ? key : b->path); } -static void changed_files(struct hashmap *result, const char *index_path, +static void changed_files(struct repository *repo, + struct hashmap *result, const char *index_path, const char *workdir) { struct child_process update_index = CHILD_PROCESS_INIT; struct child_process diff_files = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; - const char *git_dir = absolute_path(repo_get_git_dir(the_repository)); + const char *git_dir = absolute_path(repo_get_git_dir(repo)); FILE *fp; strvec_pushl(&update_index.args, @@ -289,13 +301,15 @@ static int ensure_leading_directories(char *path) * to compare the readlink(2) result as text, even on a filesystem that is * capable of doing a symbolic link. */ -static char *get_symlink(const struct object_id *oid, const char *path) +static char *get_symlink(struct repository *repo, + struct difftool_options *dt_options, + const struct object_id *oid, const char *path) { char *data; if (is_null_oid(oid)) { /* The symlink is unknown to Git so read from the filesystem */ struct strbuf link = STRBUF_INIT; - if (has_symlinks) { + if (dt_options->has_symlinks) { if (strbuf_readlink(&link, path, strlen(path))) die(_("could not read symlink %s"), path); } else if (strbuf_read_file(&link, path, 128)) @@ -305,8 +319,7 @@ static char *get_symlink(const struct object_id *oid, const char *path) } else { enum object_type type; unsigned long size; - data = repo_read_object_file(the_repository, oid, &type, - &size); + data = repo_read_object_file(repo, oid, &type, &size); if (!data) die(_("could not read object %s for symlink %s"), oid_to_hex(oid), path); @@ -340,7 +353,7 @@ static void write_file_in_directory(struct strbuf *dir, size_t dir_len, /* Write the file contents for the left and right sides of the difftool * dir-diff representation for submodules and symlinks. Symlinks and submodules * are written as regular text files so that external diff tools can diff them - * as text files, resulting in behavior that is analogous to to what "git diff" + * as text files, resulting in behavior that is analogous to what "git diff" * displays for symlink and submodule diffs. */ static void write_standin_files(struct pair_entry *entry, @@ -353,7 +366,9 @@ static void write_standin_files(struct pair_entry *entry, write_file_in_directory(rdir, rdir_len, entry->path, entry->right); } -static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, +static int run_dir_diff(struct repository *repo, + struct difftool_options *dt_options, + const char *extcmd, const char *prefix, struct child_process *child) { struct strbuf info = STRBUF_INIT, lpath = STRBUF_INIT; @@ -364,7 +379,8 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, char *lbase_dir = NULL, *rbase_dir = NULL; size_t ldir_len, rdir_len, wtdir_len; const char *workdir, *tmp; - int ret = 0, i; + int ret = 0; + size_t i; FILE *fp = NULL; struct hashmap working_tree_dups = HASHMAP_INIT(working_tree_entry_cmp, NULL); @@ -372,14 +388,15 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, struct hashmap symlinks2 = HASHMAP_INIT(pair_cmp, NULL); struct hashmap_iter iter; struct pair_entry *entry; - struct index_state wtindex = INDEX_STATE_INIT(the_repository); + struct index_state wtindex = INDEX_STATE_INIT(repo); struct checkout lstate, rstate; int err = 0; struct child_process cmd = CHILD_PROCESS_INIT; - struct hashmap wt_modified, tmp_modified; + struct hashmap wt_modified = HASHMAP_INIT(path_entry_cmp, NULL); + struct hashmap tmp_modified = HASHMAP_INIT(path_entry_cmp, NULL); int indices_loaded = 0; - workdir = repo_get_work_tree(the_repository); + workdir = repo_get_work_tree(repo); /* Setup temp directories */ tmp = getenv("TMPDIR"); @@ -434,8 +451,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, "not supported in\n" "directory diff mode ('-d' and '--dir-diff').")); - if (parse_index_info(info.buf, &lmode, &rmode, &loid, &roid, - &status)) + if (parse_index_info(repo, info.buf, &lmode, &rmode, &loid, &roid, &status)) break; if (strbuf_getline_nul(&lpath, fp)) break; @@ -465,13 +481,13 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, } if (S_ISLNK(lmode)) { - char *content = get_symlink(&loid, src_path); + char *content = get_symlink(repo, dt_options, &loid, src_path); add_left_or_right(&symlinks2, src_path, content, 0); free(content); } if (S_ISLNK(rmode)) { - char *content = get_symlink(&roid, dst_path); + char *content = get_symlink(repo, dt_options, &roid, dst_path); add_left_or_right(&symlinks2, dst_path, content, 1); free(content); } @@ -496,7 +512,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, } hashmap_add(&working_tree_dups, &entry->entry); - if (!use_wt_file(workdir, dst_path, &roid)) { + if (!use_wt_file(repo, workdir, dst_path, &roid)) { if (checkout_path(rmode, &roid, dst_path, &rstate)) { ret = error("could not write '%s'", @@ -524,7 +540,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, goto finish; } add_path(&wtdir, wtdir_len, dst_path); - if (symlinks) { + if (dt_options->symlinks) { if (symlink(wtdir.buf, rdir.buf)) { ret = error_errno("could not symlink '%s' to '%s'", wtdir.buf, rdir.buf); goto finish; @@ -601,9 +617,6 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, * in the common case of --symlinks and the difftool updating * files through the symlink. */ - hashmap_init(&wt_modified, path_entry_cmp, NULL, wtindex.cache_nr); - hashmap_init(&tmp_modified, path_entry_cmp, NULL, wtindex.cache_nr); - for (i = 0; i < wtindex.cache_nr; i++) { struct hashmap_entry dummy; const char *name = wtindex.cache[i]->name; @@ -613,7 +626,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, if (lstat(rdir.buf, &st)) continue; - if ((symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode)) + if ((dt_options->symlinks && S_ISLNK(st.st_mode)) || !S_ISREG(st.st_mode)) continue; if (!indices_loaded) { @@ -625,9 +638,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, ret = error("could not write %s", buf.buf); goto finish; } - changed_files(&wt_modified, buf.buf, workdir); + changed_files(repo, &wt_modified, buf.buf, workdir); strbuf_setlen(&rdir, rdir_len); - changed_files(&tmp_modified, buf.buf, rdir.buf); + changed_files(repo, &tmp_modified, buf.buf, rdir.buf); add_path(&rdir, rdir_len, name); indices_loaded = 1; } @@ -662,6 +675,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, if (fp) fclose(fp); + hashmap_clear_and_free(&working_tree_dups, struct working_tree_entry, entry); + hashmap_clear_and_free(&wt_modified, struct path_entry, entry); + hashmap_clear_and_free(&tmp_modified, struct path_entry, entry); + hashmap_clear_and_free(&submodules, struct pair_entry, entry); + hashmap_clear_and_free(&symlinks2, struct pair_entry, entry); + release_index(&wtindex); free(lbase_dir); free(rbase_dir); strbuf_release(&info); @@ -695,11 +714,15 @@ static int run_file_diff(int prompt, const char *prefix, int cmd_difftool(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { - int use_gui_tool = -1, dir_diff = 0, prompt = -1, symlinks = 0, - tool_help = 0, no_index = 0; + int use_gui_tool = -1, dir_diff = 0, prompt = -1, tool_help = 0, no_index = 0; static char *difftool_cmd = NULL, *extcmd = NULL; + struct difftool_options dt_options = { + .has_symlinks = 1, + .symlinks = 1, + .trust_exit_code = 0 + }; struct option builtin_difftool_options[] = { OPT_BOOL('g', "gui", &use_gui_tool, N_("use `diff.guitool` instead of `diff.tool`")), @@ -710,14 +733,14 @@ int cmd_difftool(int argc, 0, PARSE_OPT_NONEG), OPT_SET_INT_F(0, "prompt", &prompt, NULL, 1, PARSE_OPT_NONEG | PARSE_OPT_HIDDEN), - OPT_BOOL(0, "symlinks", &symlinks, + OPT_BOOL(0, "symlinks", &dt_options.symlinks, N_("use symlinks in dir-diff mode")), OPT_STRING('t', "tool", &difftool_cmd, N_("tool"), N_("use the specified diff tool")), OPT_BOOL(0, "tool-help", &tool_help, N_("print a list of diff tools that may be used with " "`--tool`")), - OPT_BOOL(0, "trust-exit-code", &trust_exit_code, + OPT_BOOL(0, "trust-exit-code", &dt_options.trust_exit_code, N_("make 'git-difftool' exit when an invoked diff " "tool returns a non-zero exit code")), OPT_STRING('x', "extcmd", &extcmd, N_("command"), @@ -727,8 +750,9 @@ int cmd_difftool(int argc, }; struct child_process child = CHILD_PROCESS_INIT; - git_config(difftool_config, NULL); - symlinks = has_symlinks; + if (repo) + repo_config(repo, difftool_config, &dt_options); + dt_options.symlinks = dt_options.has_symlinks; argc = parse_options(argc, argv, prefix, builtin_difftool_options, builtin_difftool_usage, PARSE_OPT_KEEP_UNKNOWN_OPT | @@ -742,8 +766,8 @@ int cmd_difftool(int argc, if (!no_index){ setup_work_tree(); - setenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(the_repository)), 1); - setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(the_repository)), 1); + setenv(GIT_DIR_ENVIRONMENT, absolute_path(repo_get_git_dir(repo)), 1); + setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(repo_get_work_tree(repo)), 1); } else if (dir_diff) die(_("options '%s' and '%s' cannot be used together"), "--dir-diff", "--no-index"); @@ -776,7 +800,7 @@ int cmd_difftool(int argc, } setenv("GIT_DIFFTOOL_TRUST_EXIT_CODE", - trust_exit_code ? "true" : "false", 1); + dt_options.trust_exit_code ? "true" : "false", 1); /* * In directory diff mode, 'git-difftool--helper' is called once @@ -792,6 +816,6 @@ int cmd_difftool(int argc, strvec_pushv(&child.args, argv); if (dir_diff) - return run_dir_diff(extcmd, symlinks, prefix, &child); + return run_dir_diff(repo, &dt_options, extcmd, prefix, &child); return run_file_diff(prompt, prefix, &child); } diff --git a/builtin/fast-export.c b/builtin/fast-export.c index e17f262e8e4d1c..a5c82eef1ded4d 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -3,7 +3,10 @@ * * Copyright (C) 2007 Johannes E. Schindelin */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "gettext.h" diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 1e7ab67f6e5f13..397a6f46ad85d5 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "environment.h" @@ -13,6 +15,7 @@ #include "delta.h" #include "pack.h" #include "path.h" +#include "read-cache-ll.h" #include "refs.h" #include "csum-file.h" #include "quote.h" @@ -179,6 +182,7 @@ static unsigned long branch_load_count; static int failure; static FILE *pack_edges; static unsigned int show_stats = 1; +static unsigned int quiet; static int global_argc; static const char **global_argv; static const char *global_prefix; @@ -324,7 +328,7 @@ static void write_branch_report(FILE *rpt, struct branch *b) static void write_crash_report(const char *err) { - char *loc = git_pathdup("fast_import_crash_%"PRIuMAX, (uintmax_t) getpid()); + char *loc = repo_git_path(the_repository, "fast_import_crash_%"PRIuMAX, (uintmax_t) getpid()); FILE *rpt = fopen(loc, "w"); struct branch *b; unsigned long lu; @@ -765,6 +769,7 @@ static void start_packfile(void) p->pack_fd = pack_fd; p->do_not_close = 1; + p->repo = the_repository; pack_file = hashfd(pack_fd, p->pack_name); pack_data = p; @@ -793,8 +798,8 @@ static const char *create_index(void) if (c != last) die("internal consistency error creating the index"); - tmpfile = write_idx_file(NULL, idx, object_count, &pack_idx_opts, - pack_data->hash); + tmpfile = write_idx_file(the_hash_algo, NULL, idx, object_count, + &pack_idx_opts, pack_data->hash); free(idx); return tmpfile; } @@ -805,7 +810,7 @@ static char *keep_pack(const char *curr_index_name) struct strbuf name = STRBUF_INIT; int keep_fd; - odb_pack_name(&name, pack_data->hash, "keep"); + odb_pack_name(pack_data->repo, &name, pack_data->hash, "keep"); keep_fd = odb_pack_keep(name.buf); if (keep_fd < 0) die_errno("cannot create keep file"); @@ -813,11 +818,11 @@ static char *keep_pack(const char *curr_index_name) if (close(keep_fd)) die_errno("failed to write keep file"); - odb_pack_name(&name, pack_data->hash, "pack"); + odb_pack_name(pack_data->repo, &name, pack_data->hash, "pack"); if (finalize_object_file(pack_data->pack_name, name.buf)) die("cannot store pack file"); - odb_pack_name(&name, pack_data->hash, "idx"); + odb_pack_name(pack_data->repo, &name, pack_data->hash, "idx"); if (finalize_object_file(curr_index_name, name.buf)) die("cannot store index file"); free((void *)curr_index_name); @@ -831,7 +836,7 @@ static void unkeep_all_packs(void) for (k = 0; k < pack_id; k++) { struct packed_git *p = all_packs[k]; - odb_pack_name(&name, p->hash, "keep"); + odb_pack_name(p->repo, &name, p->hash, "keep"); unlink_or_warn(name.buf); } strbuf_release(&name); @@ -873,9 +878,10 @@ static void end_packfile(void) close_pack_windows(pack_data); finalize_hashfile(pack_file, cur_pack_oid.hash, FSYNC_COMPONENT_PACK, 0); - fixup_pack_header_footer(pack_data->pack_fd, pack_data->hash, - pack_data->pack_name, object_count, - cur_pack_oid.hash, pack_size); + fixup_pack_header_footer(the_hash_algo, pack_data->pack_fd, + pack_data->hash, pack_data->pack_name, + object_count, cur_pack_oid.hash, + pack_size); if (object_count <= unpack_limit) { if (!loosen_small_pack(pack_data)) { @@ -888,7 +894,7 @@ static void end_packfile(void) idx_name = keep_pack(create_index()); /* Register the packfile with core git's machinery. */ - new_p = add_packed_git(idx_name, strlen(idx_name), 1); + new_p = add_packed_git(pack_data->repo, idx_name, strlen(idx_name), 1); if (!new_p) die("core git rejected index %s", idx_name); all_packs[pack_id] = new_p; @@ -948,15 +954,15 @@ static int store_object( unsigned char hdr[96]; struct object_id oid; unsigned long hdrlen, deltalen; - git_hash_ctx c; + struct git_hash_ctx c; git_zstream s; hdrlen = format_object_header((char *)hdr, sizeof(hdr), type, dat->len); the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, hdr, hdrlen); - the_hash_algo->update_fn(&c, dat->buf, dat->len); - the_hash_algo->final_oid_fn(&oid, &c); + git_hash_update(&c, hdr, hdrlen); + git_hash_update(&c, dat->buf, dat->len); + git_hash_final_oid(&oid, &c); if (oidout) oidcpy(oidout, &oid); @@ -966,8 +972,7 @@ static int store_object( if (e->idx.offset) { duplicate_count_by_type[type]++; return 1; - } else if (find_sha1_pack(oid.hash, - get_all_packs(the_repository))) { + } else if (find_oid_pack(&oid, get_all_packs(the_repository))) { e->type = type; e->pack_id = MAX_PACK_ID; e->idx.offset = 1; /* just not zero! */ @@ -1091,7 +1096,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) struct object_id oid; unsigned long hdrlen; off_t offset; - git_hash_ctx c; + struct git_hash_ctx c; git_zstream s; struct hashfile_checkpoint checkpoint; int status = Z_OK; @@ -1102,14 +1107,14 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) || (pack_size + PACK_SIZE_THRESHOLD + len) < pack_size) cycle_packfile(); - the_hash_algo->init_fn(&checkpoint.ctx); + hashfile_checkpoint_init(pack_file, &checkpoint); hashfile_checkpoint(pack_file, &checkpoint); offset = checkpoint.offset; hdrlen = format_object_header((char *)out_buf, out_sz, OBJ_BLOB, len); the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, out_buf, hdrlen); + git_hash_update(&c, out_buf, hdrlen); crc32_begin(pack_file); @@ -1127,7 +1132,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) if (!n && feof(stdin)) die("EOF in data (%" PRIuMAX " bytes remaining)", len); - the_hash_algo->update_fn(&c, in_buf, n); + git_hash_update(&c, in_buf, n); s.next_in = in_buf; s.avail_in = n; len -= n; @@ -1153,7 +1158,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) } } git_deflate_end(&s); - the_hash_algo->final_oid_fn(&oid, &c); + git_hash_final_oid(&oid, &c); if (oidout) oidcpy(oidout, &oid); @@ -1167,8 +1172,7 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark) duplicate_count_by_type[OBJ_BLOB]++; truncate_pack(&checkpoint); - } else if (find_sha1_pack(oid.hash, - get_all_packs(the_repository))) { + } else if (find_oid_pack(&oid, get_all_packs(the_repository))) { e->type = OBJ_BLOB; e->pack_id = MAX_PACK_ID; e->idx.offset = 1; /* just not zero! */ @@ -1604,7 +1608,19 @@ static int update_branch(struct branch *b) struct ref_transaction *transaction; struct object_id old_oid; struct strbuf err = STRBUF_INIT; - + static const char *replace_prefix = "refs/replace/"; + + if (starts_with(b->name, replace_prefix) && + !strcmp(b->name + strlen(replace_prefix), + oid_to_hex(&b->oid))) { + if (!quiet) + warning("Dropping %s since it would point to " + "itself (i.e. to %s)", + b->name, oid_to_hex(&b->oid)); + refs_delete_ref(get_main_ref_store(the_repository), + NULL, b->name, NULL, 0); + return 0; + } if (is_null_oid(&b->oid)) { if (b->delete) refs_delete_ref(get_main_ref_store(the_repository), @@ -1636,7 +1652,7 @@ static int update_branch(struct branch *b) } } transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction || ref_transaction_update(transaction, b->name, &b->oid, &old_oid, NULL, NULL, 0, msg, &err) || @@ -1671,7 +1687,7 @@ static void dump_tags(void) struct ref_transaction *transaction; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) { failure |= error("%s", err.buf); goto cleanup; @@ -2414,6 +2430,9 @@ static void file_change_m(const char *p, struct branch *b) tree_content_replace(&b->branch_tree, &oid, mode, NULL); return; } + + if (!verify_path(path.buf, mode)) + die("invalid path '%s'", path.buf); tree_content_set(&b->branch_tree, path.buf, &oid, mode, NULL); } @@ -2451,6 +2470,8 @@ static void file_change_cr(const char *p, struct branch *b, int rename) leaf.tree); return; } + if (!verify_path(dest.buf, leaf.versions[1].mode)) + die("invalid path '%s'", dest.buf); tree_content_set(&b->branch_tree, dest.buf, &leaf.versions[1].oid, leaf.versions[1].mode, @@ -3259,7 +3280,7 @@ static char* make_fast_import_path(const char *path) { if (!relative_marks_paths || is_absolute_path(path)) return prefix_filename(global_prefix, path); - return git_pathdup("info/fast-import/%s", path); + return repo_git_path(the_repository, "info/fast-import/%s", path); } static void option_import_marks(const char *marks, @@ -3390,6 +3411,7 @@ static int parse_one_option(const char *option) option_export_pack_edges(option); } else if (!strcmp(option, "quiet")) { show_stats = 0; + quiet = 1; } else if (!strcmp(option, "stats")) { show_stats = 1; } else if (!strcmp(option, "allow-unsafe-features")) { @@ -3540,12 +3562,11 @@ static void parse_argv(void) int cmd_fast_import(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { unsigned int i; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(fast_import_usage); + show_usage_if_asked(argc, argv, fast_import_usage); reset_pack_idx_option(&pack_idx_opts); git_pack_config(); @@ -3661,7 +3682,7 @@ int cmd_fast_import(int argc, fprintf(stderr, " pools: %10lu KiB\n", (unsigned long)((tree_entry_allocd + fi_mem_pool.pool_alloc) /1024)); fprintf(stderr, " objects: %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024); fprintf(stderr, "---------------------------------------------------------------------\n"); - pack_report(); + pack_report(repo); fprintf(stderr, "---------------------------------------------------------------------\n"); fprintf(stderr, "\n"); } diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 49222a36fa6f29..d07eec9e5550ab 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -53,6 +55,7 @@ int cmd_fetch_pack(int argc, struct ref *fetched_refs = NULL, *remote_refs = NULL; const char *dest = NULL; struct ref **sought = NULL; + struct ref **sought_to_free = NULL; int nr_sought = 0, alloc_sought = 0; int fd[2]; struct string_list pack_lockfiles = STRING_LIST_INIT_DUP; @@ -72,6 +75,8 @@ int cmd_fetch_pack(int argc, list_objects_filter_init(&args.filter_options); args.uploadpack = "git-upload-pack"; + show_usage_if_asked(argc, argv, fetch_pack_usage); + for (i = 1; i < argc && *argv[i] == '-'; i++) { const char *arg = argv[i]; @@ -243,6 +248,13 @@ int cmd_fetch_pack(int argc, BUG("unknown protocol version"); } + /* + * Create a shallow copy of `sought` so that we can free all of its entries. + * This is because `fetch_pack()` will modify the array to evict some + * entries, but won't free those. + */ + DUP_ARRAY(sought_to_free, sought, nr_sought); + fetched_refs = fetch_pack(&args, fd, remote_refs, sought, nr_sought, &shallow, pack_lockfiles_ptr, version); @@ -280,9 +292,13 @@ int cmd_fetch_pack(int argc, oid_to_hex(&ref->old_oid), ref->name); for (size_t i = 0; i < nr_sought; i++) - free_one_ref(sought[i]); + free_one_ref(sought_to_free[i]); + free(sought_to_free); free(sought); free_refs(fetched_refs); free_refs(remote_refs); + list_objects_filter_release(&args.filter_options); + oid_array_clear(&shallow); + string_list_clear(&pack_lockfiles, 0); return ret; } diff --git a/builtin/fetch.c b/builtin/fetch.c index c900f577219109..95fd0018b981fb 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1,7 +1,10 @@ /* * "git fetch" */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "advice.h" #include "config.h" @@ -454,13 +457,10 @@ static void filter_prefetch_refspec(struct refspec *rs) ref_namespace[NAMESPACE_TAGS].ref))) { int j; - free(rs->items[i].src); - free(rs->items[i].dst); + refspec_item_clear(&rs->items[i]); - for (j = i + 1; j < rs->nr; j++) { + for (j = i + 1; j < rs->nr; j++) rs->items[j - 1] = rs->items[j]; - rs->raw[j - 1] = rs->raw[j]; - } rs->nr--; i--; continue; @@ -668,7 +668,7 @@ static int s_update_ref(const char *action, */ if (!transaction) { transaction = our_transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) { ret = STORE_REF_ERROR_OTHER; goto out; @@ -1577,6 +1577,135 @@ static int backfill_tags(struct display_state *display_state, return retcode; } +static const char *strip_refshead(const char *name){ + skip_prefix(name, "refs/heads/", &name); + return name; +} + +static void set_head_advice_msg(const char *remote, const char *head_name) +{ + const char message_advice_set_head[] = + N_("Run 'git remote set-head %s %s' to follow the change, or set\n" + "'remote.%s.followRemoteHEAD' configuration option to a different value\n" + "if you do not want to see this message. Specifically running\n" + "'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" + "will disable the warning until the remote changes HEAD to something else."); + + advise_if_enabled(ADVICE_FETCH_SET_HEAD_WARN, _(message_advice_set_head), + remote, head_name, remote, remote, head_name); +} + +static void report_set_head(const char *remote, const char *head_name, + struct strbuf *buf_prev, int updateres) { + struct strbuf buf_prefix = STRBUF_INIT; + const char *prev_head = NULL; + + strbuf_addf(&buf_prefix, "refs/remotes/%s/", remote); + skip_prefix(buf_prev->buf, buf_prefix.buf, &prev_head); + + if (prev_head && strcmp(prev_head, head_name)) { + printf("'HEAD' at '%s' is '%s', but we have '%s' locally.\n", + remote, head_name, prev_head); + set_head_advice_msg(remote, head_name); + } + else if (updateres && buf_prev->len) { + printf("'HEAD' at '%s' is '%s', " + "but we have a detached HEAD pointing to '%s' locally.\n", + remote, head_name, buf_prev->buf); + set_head_advice_msg(remote, head_name); + } + strbuf_release(&buf_prefix); +} + +static int set_head(const struct ref *remote_refs, struct remote *remote) +{ + int result = 0, create_only, baremirror, was_detached; + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, + b_local_head = STRBUF_INIT; + int follow_remote_head = remote->follow_remote_head; + const char *no_warn_branch = remote->no_warn_branch; + char *head_name = NULL; + struct ref *ref, *matches; + struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map; + struct refspec_item refspec = { + .force = 0, + .pattern = 1, + .src = (char *) "refs/heads/*", + .dst = (char *) "refs/heads/*", + }; + struct string_list heads = STRING_LIST_INIT_DUP; + struct ref_store *refs = get_main_ref_store(the_repository); + + get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0); + matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"), + fetch_map, 1); + for (ref = matches; ref; ref = ref->next) { + string_list_append(&heads, strip_refshead(ref->name)); + } + + if (follow_remote_head == FOLLOW_REMOTE_NEVER) + goto cleanup; + + if (!heads.nr) + result = 1; + else if (heads.nr > 1) + result = 1; + else + head_name = xstrdup(heads.items[0].string); + + if (!head_name) + goto cleanup; + baremirror = is_bare_repository() && remote->mirror; + create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !baremirror; + if (baremirror) { + strbuf_addstr(&b_head, "HEAD"); + strbuf_addf(&b_remote_head, "refs/heads/%s", head_name); + } else { + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote->name); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote->name, head_name); + } + /* make sure it's valid */ + if (!baremirror && !refs_ref_exists(refs, b_remote_head.buf)) { + result = 1; + goto cleanup; + } + was_detached = refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf, + "fetch", &b_local_head, create_only); + if (was_detached == -1) { + result = 1; + goto cleanup; + } + if (verbosity >= 0 && + follow_remote_head == FOLLOW_REMOTE_WARN && + (!no_warn_branch || strcmp(no_warn_branch, head_name))) + report_set_head(remote->name, head_name, &b_local_head, was_detached); + +cleanup: + free(head_name); + free_refs(fetch_map); + free_refs(matches); + string_list_clear(&heads, 0); + strbuf_release(&b_head); + strbuf_release(&b_local_head); + strbuf_release(&b_remote_head); + return result; +} + +static int uses_remote_tracking(struct transport *transport, struct refspec *rs) +{ + if (!remote_is_configured(transport->remote, 0)) + return 0; + + if (!rs->nr) + rs = &transport->remote->fetch; + + for (int i = 0; i < rs->nr; i++) + if (rs->items[i].dst) + return 1; + + return 0; +} + static int do_fetch(struct transport *transport, struct refspec *rs, const struct fetch_config *config) @@ -1646,6 +1775,13 @@ static int do_fetch(struct transport *transport, "refs/tags/"); } + if (uses_remote_tracking(transport, rs)) { + must_list_refs = 1; + if (transport_ls_refs_options.ref_prefixes.nr) + strvec_push(&transport_ls_refs_options.ref_prefixes, + "HEAD"); + } + if (must_list_refs) { trace2_region_enter("fetch", "remote_refs", the_repository); remote_refs = transport_get_remote_refs(transport, @@ -1670,7 +1806,7 @@ static int do_fetch(struct transport *transport, if (atomic_fetch) { transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) { retcode = -1; goto cleanup; @@ -1790,6 +1926,12 @@ static int do_fetch(struct transport *transport, "you need to specify exactly one branch with the --set-upstream option")); } } + if (set_head(remote_refs, transport->remote)) + ; + /* + * Way too many cases where this can go wrong + * so let's just fail silently for now. + */ cleanup: if (retcode) { @@ -1980,6 +2122,8 @@ static int fetch_multiple(struct string_list *list, int max_children, strvec_pushl(&argv, "-c", "fetch.bundleURI=", "fetch", "--append", "--no-auto-gc", "--no-write-commit-graph", NULL); + for (i = 0; i < server_options.nr; i++) + strvec_pushf(&argv, "--server-option=%s", server_options.items[i].string); add_options_to_argv(&argv, config); if (max_children != 1 && list->nr != 1) { @@ -2213,8 +2357,8 @@ int cmd_fetch(int argc, N_("deepen history of shallow clone")), OPT_STRING(0, "shallow-since", &deepen_since, N_("time"), N_("deepen history of shallow repository based on time")), - OPT_STRING_LIST(0, "shallow-exclude", &deepen_not, N_("revision"), - N_("deepen history of shallow clone, excluding rev")), + OPT_STRING_LIST(0, "shallow-exclude", &deepen_not, N_("ref"), + N_("deepen history of shallow clone, excluding ref")), OPT_INTEGER(0, "deepen", &deepen_relative, N_("deepen history of shallow clone")), OPT_SET_INT_F(0, "unshallow", &unshallow, diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 715745a262aa35..8085ebd8fe97b5 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -108,7 +108,6 @@ int cmd_for_each_ref(int argc, filter_and_format_refs(&filter, flags, sorting, &format); ref_filter_clear(&filter); - ref_format_clear(&format); ref_sorting_release(sorting); strvec_clear(&vec); return 0; diff --git a/builtin/for-each-repo.c b/builtin/for-each-repo.c index fae7f91cf15f7e..325a7925f1fdb5 100644 --- a/builtin/for-each-repo.c +++ b/builtin/for-each-repo.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "gettext.h" @@ -36,7 +37,7 @@ int cmd_for_each_repo(int argc, { static const char *config_key = NULL; int keep_going = 0; - int i, result = 0; + int result = 0; const struct string_list *values; int err; @@ -61,7 +62,7 @@ int cmd_for_each_repo(int argc, else if (err) return 0; - for (i = 0; i < values->nr; i++) { + for (size_t i = 0; i < values->nr; i++) { int ret = run_command_on_repo(values->items[i].string, argc, argv); if (ret) { if (!keep_going) diff --git a/builtin/fsck.c b/builtin/fsck.c index 7f4e2f04143271..eea1d43647f224 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -150,7 +150,7 @@ static int mark_object(struct object *obj, enum object_type type, return 0; obj->flags |= REACHABLE; - if (is_promisor_object(&obj->oid)) + if (is_promisor_object(the_repository, &obj->oid)) /* * Further recursion does not need to be performed on this * object since it is a promisor object (so it does not need to @@ -197,7 +197,8 @@ static int traverse_reachable(void) unsigned int nr = 0; int result = 0; if (show_progress) - progress = start_delayed_progress(_("Checking connectivity"), 0); + progress = start_delayed_progress(the_repository, + _("Checking connectivity"), 0); while (pending.nr) { result |= traverse_one_object(object_array_pop(&pending)); display_progress(progress, ++nr); @@ -270,9 +271,9 @@ static void check_reachable_object(struct object *obj) * do a full fsck */ if (!(obj->flags & HAS_OBJ)) { - if (is_promisor_object(&obj->oid)) + if (is_promisor_object(the_repository, &obj->oid)) return; - if (has_object_pack(&obj->oid)) + if (has_object_pack(the_repository, &obj->oid)) return; /* it is in pack - forget about it */ printf_ln(_("missing %s %s"), printable_type(&obj->oid, obj->type), @@ -325,7 +326,7 @@ static void check_unreachable_object(struct object *obj) printable_type(&obj->oid, obj->type), describe_object(&obj->oid)); if (write_lost_and_found) { - char *filename = git_pathdup("lost-found/%s/%s", + char *filename = repo_git_path(the_repository, "lost-found/%s/%s", obj->type == OBJ_COMMIT ? "commit" : "other", describe_object(&obj->oid)); FILE *f; @@ -391,7 +392,10 @@ static void check_connectivity(void) * traversal. */ for_each_loose_object(mark_loose_unreachable_referents, NULL, 0); - for_each_packed_object(mark_packed_unreachable_referents, NULL, 0); + for_each_packed_object(the_repository, + mark_packed_unreachable_referents, + NULL, + 0); } /* Look up all the requirements, warn about missing objects.. */ @@ -488,7 +492,7 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid, refname, timestamp); obj->flags |= USED; mark_object_reachable(obj); - } else if (!is_promisor_object(oid)) { + } else if (!is_promisor_object(the_repository, oid)) { error(_("%s: invalid reflog entry %s"), refname, oid_to_hex(oid)); errors_found |= ERROR_REACHABLE; @@ -531,7 +535,7 @@ static int fsck_handle_ref(const char *refname, const char *referent UNUSED, con obj = parse_object(the_repository, oid); if (!obj) { - if (is_promisor_object(oid)) { + if (is_promisor_object(the_repository, oid)) { /* * Increment default_refs anyway, because this is a * valid ref. @@ -700,7 +704,8 @@ static void fsck_object_dir(const char *path) fprintf_ln(stderr, _("Checking object directory")); if (show_progress) - progress = start_progress(_("Checking object directories"), 256); + progress = start_progress(the_repository, + _("Checking object directories"), 256); for_each_loose_file_in_objdir(path, fsck_loose, fsck_cruft, fsck_subdir, &cb_data); @@ -876,7 +881,8 @@ static int check_pack_rev_indexes(struct repository *r, int show_progress) if (show_progress) { for (struct packed_git *p = get_all_packs(r); p; p = p->next) pack_count++; - progress = start_delayed_progress("Verifying reverse pack-indexes", pack_count); + progress = start_delayed_progress(the_repository, + "Verifying reverse pack-indexes", pack_count); pack_count = 0; } @@ -966,7 +972,8 @@ int cmd_fsck(int argc, if (connectivity_only) { for_each_loose_object(mark_loose_for_connectivity, NULL, 0); - for_each_packed_object(mark_packed_for_connectivity, NULL, 0); + for_each_packed_object(the_repository, + mark_packed_for_connectivity, NULL, 0); } else { prepare_alt_odb(the_repository); for (odb = the_repository->objects->odb; odb; odb = odb->next) @@ -985,7 +992,8 @@ int cmd_fsck(int argc, total += p->num_objects; } - progress = start_progress(_("Checking objects"), total); + progress = start_progress(the_repository, + _("Checking objects"), total); } for (p = get_all_packs(the_repository); p; p = p->next) { @@ -1011,7 +1019,7 @@ int cmd_fsck(int argc, &oid); if (!obj || !(obj->flags & HAS_OBJ)) { - if (is_promisor_object(&oid)) + if (is_promisor_object(the_repository, &oid)) continue; error(_("%s: object missing"), oid_to_hex(&oid)); errors_found |= ERROR_OBJECT; @@ -1049,7 +1057,7 @@ int cmd_fsck(int argc, struct worktree *wt = *p; struct index_state istate = INDEX_STATE_INIT(the_repository); - char *path; + char *path, *wt_gitdir; /* * Make a copy since the buffer is reusable @@ -1057,9 +1065,13 @@ int cmd_fsck(int argc, * while we're examining the index. */ path = xstrdup(worktree_git_path(the_repository, wt, "index")); - read_index_from(&istate, path, get_worktree_git_dir(wt)); + wt_gitdir = get_worktree_git_dir(wt); + + read_index_from(&istate, path, wt_gitdir); fsck_index(&istate, path, wt->is_current); + discard_index(&istate); + free(wt_gitdir); free(path); } free_worktrees(worktrees); diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index dce8a3b248291d..0820e524f1a517 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "config.h" @@ -1208,9 +1210,9 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) * system event listener thread so that we have the IPC handle * before we need it. */ - if (ipc_server_run_async(&state->ipc_server_data, - state->path_ipc.buf, &ipc_opts, - handle_client, state)) + if (ipc_server_init_async(&state->ipc_server_data, + state->path_ipc.buf, &ipc_opts, + handle_client, state)) return error_errno( _("could not start IPC thread pool on '%s'"), state->path_ipc.buf); @@ -1314,6 +1316,7 @@ static int fsmonitor_run_daemon(void) strbuf_reset(&state.path_gitdir_watch); strbuf_addstr(&state.path_gitdir_watch, absolute_path(repo_get_git_dir(the_repository))); + strbuf_strip_suffix(&state.path_gitdir_watch, "/."); state.nr_paths_watching = 2; } @@ -1595,8 +1598,8 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_fsmonitor__daemon_usage, options); + show_usage_with_options_if_asked(argc, argv, + builtin_fsmonitor__daemon_usage, options); die(_("fsmonitor--daemon not supported on this platform")); } diff --git a/builtin/gc.c b/builtin/gc.c index 7da6d1966b1b50..99431fd46744cd 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -9,7 +9,10 @@ * * Copyright (c) 2006 Shawn O. Pearce */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "date.h" @@ -96,9 +99,11 @@ static void process_log_file(void) /* There was some error recorded in the lock file */ commit_lock_file(&log_lock); } else { + char *path = repo_git_path(the_repository, "gc.log"); /* No error, clean up any old gc.log */ - unlink(git_path("gc.log")); + unlink(path); rollback_lock_file(&log_lock); + free(path); } } @@ -136,8 +141,14 @@ struct gc_config { char *prune_worktrees_expire; char *repack_filter; char *repack_filter_to; + char *repack_expire_to; unsigned long big_pack_threshold; unsigned long max_delta_cache_size; + /* + * Remove this member from gc_config once repo_settings is passed + * through the callchain. + */ + size_t delta_base_cache_limit; }; #define GC_CONFIG_INIT { \ @@ -153,6 +164,7 @@ struct gc_config { .prune_expire = xstrdup("2.weeks.ago"), \ .prune_worktrees_expire = xstrdup("3.months.ago"), \ .max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE, \ + .delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT, \ } static void gc_config_release(struct gc_config *cfg) @@ -168,6 +180,7 @@ static void gc_config(struct gc_config *cfg) { const char *value; char *owned = NULL; + unsigned long ulongval; if (!git_config_get_value("gc.packrefs", &value)) { if (value && !strcmp(value, "notbare")) @@ -206,6 +219,9 @@ static void gc_config(struct gc_config *cfg) git_config_get_ulong("gc.bigpackthreshold", &cfg->big_pack_threshold); git_config_get_ulong("pack.deltacachesize", &cfg->max_delta_cache_size); + if (!git_config_get_ulong("core.deltabasecachelimit", &ulongval)) + cfg->delta_base_cache_limit = ulongval; + if (!git_config_get_string("gc.repackfilter", &owned)) { free(cfg->repack_filter); cfg->repack_filter = owned; @@ -286,8 +302,11 @@ static int too_many_loose_objects(struct gc_config *cfg) int num_loose = 0; int needed = 0; const unsigned hexsz_loose = the_hash_algo->hexsz - 2; + char *path; - dir = opendir(git_path("objects/17")); + path = repo_git_path(the_repository, "objects/17"); + dir = opendir(path); + free(path); if (!dir) return 0; @@ -416,7 +435,7 @@ static uint64_t estimate_repack_memory(struct gc_config *cfg, * read_sha1_file() (either at delta calculation phase, or * writing phase) also fills up the delta base cache */ - heap += delta_base_cache_limit; + heap += cfg->delta_base_cache_limit; /* and of course pack-objects has its own delta cache */ heap += cfg->max_delta_cache_size; @@ -432,7 +451,8 @@ static int keep_one_pack(struct string_list_item *item, void *data UNUSED) static void add_repack_all_option(struct gc_config *cfg, struct string_list *keep_pack) { - if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now")) + if (cfg->prune_expire && !strcmp(cfg->prune_expire, "now") + && !(cfg->cruft_packs && cfg->repack_expire_to)) strvec_push(&repack, "-a"); else if (cfg->cruft_packs) { strvec_push(&repack, "--cruft"); @@ -441,6 +461,8 @@ static void add_repack_all_option(struct gc_config *cfg, if (cfg->max_cruft_size) strvec_pushf(&repack, "--max-cruft-size=%lu", cfg->max_cruft_size); + if (cfg->repack_expire_to) + strvec_pushf(&repack, "--expire-to=%s", cfg->repack_expire_to); } else { strvec_push(&repack, "-A"); if (cfg->prune_expire) @@ -533,7 +555,7 @@ static const char *lock_repo_for_gc(int force, pid_t* ret_pid) if (xgethostname(my_host, sizeof(my_host))) xsnprintf(my_host, sizeof(my_host), "unknown"); - pidfile_path = git_pathdup("gc.pid"); + pidfile_path = repo_git_path(the_repository, "gc.pid"); fd = hold_lock_file_for_update(&lock, pidfile_path, LOCK_DIE_ON_ERROR); if (!force) { @@ -594,7 +616,7 @@ static int report_last_gc_error(void) int ret = 0; ssize_t len; struct stat st; - char *gc_log_path = git_pathdup("gc.log"); + char *gc_log_path = repo_git_path(the_repository, "gc.log"); if (stat(gc_log_path, &st)) { if (errno == ENOENT) @@ -675,7 +697,6 @@ struct repository *repo UNUSED) const char *prune_expire_sentinel = "sentinel"; const char *prune_expire_arg = prune_expire_sentinel; int ret; - struct option builtin_gc_options[] = { OPT__QUIET(&quiet, N_("suppress progress reporting")), { OPTION_STRING, 0, "prune", &prune_expire_arg, N_("date"), @@ -694,11 +715,13 @@ struct repository *repo UNUSED) PARSE_OPT_NOCOMPLETE), OPT_BOOL(0, "keep-largest-pack", &keep_largest_pack, N_("repack all other packs except the largest pack")), + OPT_STRING(0, "expire-to", &cfg.repack_expire_to, N_("dir"), + N_("pack prefix to store a pack containing pruned objects")), OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_gc_usage, builtin_gc_options); + show_usage_with_options_if_asked(argc, argv, + builtin_gc_usage, builtin_gc_options); strvec_pushl(&reflog, "reflog", "expire", "--all", NULL); strvec_pushl(&repack, "repack", "-d", "-l", NULL); @@ -808,11 +831,12 @@ struct repository *repo UNUSED) } if (daemonized) { - hold_lock_file_for_update(&log_lock, - git_path("gc.log"), + char *path = repo_git_path(the_repository, "gc.log"); + hold_lock_file_for_update(&log_lock, path, LOCK_DIE_ON_ERROR); dup2(get_lock_file_fd(&log_lock), 2); atexit(process_log_file_at_exit); + free(path); } gc_before_repack(&opts, &cfg); @@ -874,8 +898,11 @@ struct repository *repo UNUSED) warning(_("There are too many unreachable loose objects; " "run 'git prune' to remove them.")); - if (!daemonized) - unlink(git_path("gc.log")); + if (!daemonized) { + char *path = repo_git_path(the_repository, "gc.log"); + unlink(path); + free(path); + } out: gc_config_release(&cfg); @@ -1478,9 +1505,9 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts, static void initialize_maintenance_strategy(void) { - char *config_str; + const char *config_str; - if (git_config_get_string("maintenance.strategy", &config_str)) + if (git_config_get_string_tmp("maintenance.strategy", &config_str)) return; if (!strcasecmp(config_str, "incremental")) { @@ -1561,7 +1588,8 @@ static int task_option_parse(const struct option *opt UNUSED, return 0; } -static int maintenance_run(int argc, const char **argv, const char *prefix) +static int maintenance_run(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i; struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT; @@ -1623,7 +1651,8 @@ static char const * const builtin_maintenance_register_usage[] = { NULL }; -static int maintenance_register(int argc, const char **argv, const char *prefix) +static int maintenance_register(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { char *config_file = NULL; struct option options[] = { @@ -1687,7 +1716,8 @@ static char const * const builtin_maintenance_unregister_usage[] = { NULL }; -static int maintenance_unregister(int argc, const char **argv, const char *prefix) +static int maintenance_unregister(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int force = 0; char *config_file = NULL; @@ -1818,39 +1848,43 @@ static const char *get_extra_launchctl_strings(void) { * * If $GIT_TEST_MAINT_SCHEDULER is set, return true. * In this case, the *cmd value is read as input. * - * * if the input value *cmd is the key of one of the comma-separated list - * item, then *is_available is set to true and *cmd is modified and becomes + * * if the input value cmd is the key of one of the comma-separated list + * item, then *is_available is set to true and *out is set to * the mock command. * * * if the input value *cmd isn’t the key of any of the comma-separated list - * item, then *is_available is set to false. + * item, then *is_available is set to false and *out is set to the original + * command. * * Ex.: * GIT_TEST_MAINT_SCHEDULER not set * +-------+-------------------------------------------------+ * | Input | Output | - * | *cmd | return code | *cmd | *is_available | + * | *cmd | return code | *out | *is_available | * +-------+-------------+-------------------+---------------+ - * | "foo" | false | "foo" (unchanged) | (unchanged) | + * | "foo" | false | "foo" (allocated) | (unchanged) | * +-------+-------------+-------------------+---------------+ * * GIT_TEST_MAINT_SCHEDULER set to “foo:./mock_foo.sh,bar:./mock_bar.sh” * +-------+-------------------------------------------------+ * | Input | Output | - * | *cmd | return code | *cmd | *is_available | + * | *cmd | return code | *out | *is_available | * +-------+-------------+-------------------+---------------+ * | "foo" | true | "./mock.foo.sh" | true | - * | "qux" | true | "qux" (unchanged) | false | + * | "qux" | true | "qux" (allocated) | false | * +-------+-------------+-------------------+---------------+ */ -static int get_schedule_cmd(const char **cmd, int *is_available) +static int get_schedule_cmd(const char *cmd, int *is_available, char **out) { char *testing = xstrdup_or_null(getenv("GIT_TEST_MAINT_SCHEDULER")); struct string_list_item *item; struct string_list list = STRING_LIST_INIT_NODUP; - if (!testing) + if (!testing) { + if (out) + *out = xstrdup(cmd); return 0; + } if (is_available) *is_available = 0; @@ -1862,16 +1896,22 @@ static int get_schedule_cmd(const char **cmd, int *is_available) if (string_list_split_in_place(&pair, item->string, ":", 2) != 2) continue; - if (!strcmp(*cmd, pair.items[0].string)) { - *cmd = pair.items[1].string; + if (!strcmp(cmd, pair.items[0].string)) { + if (out) + *out = xstrdup(pair.items[1].string); if (is_available) *is_available = 1; - string_list_clear(&list, 0); - UNLEAK(testing); - return 1; + string_list_clear(&pair, 0); + goto out; } + + string_list_clear(&pair, 0); } + if (out) + *out = xstrdup(cmd); + +out: string_list_clear(&list, 0); free(testing); return 1; @@ -1883,14 +1923,13 @@ static int get_random_minute(void) if (getenv("GIT_TEST_MAINT_SCHEDULER")) return 13; - return git_rand() % 60; + return git_rand(0) % 60; } static int is_launchctl_available(void) { - const char *cmd = "launchctl"; int is_available; - if (get_schedule_cmd(&cmd, &is_available)) + if (get_schedule_cmd("launchctl", &is_available, NULL)) return is_available; #ifdef __APPLE__ @@ -1928,12 +1967,12 @@ static char *launchctl_get_uid(void) static int launchctl_boot_plist(int enable, const char *filename) { - const char *cmd = "launchctl"; + char *cmd; int result; struct child_process child = CHILD_PROCESS_INIT; char *uid = launchctl_get_uid(); - get_schedule_cmd(&cmd, NULL); + get_schedule_cmd("launchctl", NULL, &cmd); strvec_split(&child.args, cmd); strvec_pushl(&child.args, enable ? "bootstrap" : "bootout", uid, filename, NULL); @@ -1946,6 +1985,7 @@ static int launchctl_boot_plist(int enable, const char *filename) result = finish_command(&child); + free(cmd); free(uid); return result; } @@ -1997,10 +2037,10 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit static unsigned long lock_file_timeout_ms = ULONG_MAX; struct strbuf plist = STRBUF_INIT, plist2 = STRBUF_INIT; struct stat st; - const char *cmd = "launchctl"; + char *cmd; int minute = get_random_minute(); - get_schedule_cmd(&cmd, NULL); + get_schedule_cmd("launchctl", NULL, &cmd); preamble = "<?xml version=\"1.0\"?>\n" "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" "<plist version=\"1.0\">" @@ -2092,6 +2132,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit free(filename); free(name); + free(cmd); strbuf_release(&plist); strbuf_release(&plist2); return 0; @@ -2116,9 +2157,8 @@ static int launchctl_update_schedule(int run_maintenance, int fd UNUSED) static int is_schtasks_available(void) { - const char *cmd = "schtasks"; int is_available; - if (get_schedule_cmd(&cmd, &is_available)) + if (get_schedule_cmd("schtasks", &is_available, NULL)) return is_available; #ifdef GIT_WINDOWS_NATIVE @@ -2137,15 +2177,16 @@ static char *schtasks_task_name(const char *frequency) static int schtasks_remove_task(enum schedule_priority schedule) { - const char *cmd = "schtasks"; + char *cmd; struct child_process child = CHILD_PROCESS_INIT; const char *frequency = get_frequency(schedule); char *name = schtasks_task_name(frequency); - get_schedule_cmd(&cmd, NULL); + get_schedule_cmd("schtasks", NULL, &cmd); strvec_split(&child.args, cmd); strvec_pushl(&child.args, "/delete", "/tn", name, "/f", NULL); free(name); + free(cmd); return run_command(&child); } @@ -2159,7 +2200,7 @@ static int schtasks_remove_tasks(void) static int schtasks_schedule_task(const char *exec_path, enum schedule_priority schedule) { - const char *cmd = "schtasks"; + char *cmd; int result; struct child_process child = CHILD_PROCESS_INIT; const char *xml; @@ -2169,7 +2210,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority struct strbuf tfilename = STRBUF_INIT; int minute = get_random_minute(); - get_schedule_cmd(&cmd, NULL); + get_schedule_cmd("schtasks", NULL, &cmd); strbuf_addf(&tfilename, "%s/schedule_%s_XXXXXX", repo_get_common_dir(the_repository), frequency); @@ -2276,6 +2317,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority delete_tempfile(&tfile); free(name); + free(cmd); return result; } @@ -2317,21 +2359,28 @@ static int check_crontab_process(const char *cmd) static int is_crontab_available(void) { - const char *cmd = "crontab"; + char *cmd; int is_available; + int ret; - if (get_schedule_cmd(&cmd, &is_available)) - return is_available; + if (get_schedule_cmd("crontab", &is_available, &cmd)) { + ret = is_available; + goto out; + } #ifdef __APPLE__ /* * macOS has cron, but it requires special permissions and will * create a UI alert when attempting to run this command. */ - return 0; + ret = 0; #else - return check_crontab_process(cmd); + ret = check_crontab_process(cmd); #endif + +out: + free(cmd); + return ret; } #define BEGIN_LINE "# BEGIN GIT MAINTENANCE SCHEDULE" @@ -2339,7 +2388,7 @@ static int is_crontab_available(void) static int crontab_update_schedule(int run_maintenance, int fd) { - const char *cmd = "crontab"; + char *cmd; int result = 0; int in_old_region = 0; struct child_process crontab_list = CHILD_PROCESS_INIT; @@ -2349,15 +2398,17 @@ static int crontab_update_schedule(int run_maintenance, int fd) struct tempfile *tmpedit = NULL; int minute = get_random_minute(); - get_schedule_cmd(&cmd, NULL); + get_schedule_cmd("crontab", NULL, &cmd); strvec_split(&crontab_list.args, cmd); strvec_push(&crontab_list.args, "-l"); crontab_list.in = -1; crontab_list.out = dup(fd); crontab_list.git_cmd = 0; - if (start_command(&crontab_list)) - return error(_("failed to run 'crontab -l'; your system might not support 'cron'")); + if (start_command(&crontab_list)) { + result = error(_("failed to run 'crontab -l'; your system might not support 'cron'")); + goto out; + } /* Ignore exit code, as an empty crontab will return error. */ finish_command(&crontab_list); @@ -2427,8 +2478,10 @@ static int crontab_update_schedule(int run_maintenance, int fd) result = error(_("'crontab' died")); else fclose(cron_list); + out: delete_tempfile(&tmpedit); + free(cmd); return result; } @@ -2451,10 +2504,9 @@ static int real_is_systemd_timer_available(void) static int is_systemd_timer_available(void) { - const char *cmd = "systemctl"; int is_available; - if (get_schedule_cmd(&cmd, &is_available)) + if (get_schedule_cmd("systemctl", &is_available, NULL)) return is_available; return real_is_systemd_timer_available(); @@ -2635,9 +2687,10 @@ static int systemd_timer_enable_unit(int enable, enum schedule_priority schedule, int minute) { - const char *cmd = "systemctl"; + char *cmd = NULL; struct child_process child = CHILD_PROCESS_INIT; const char *frequency = get_frequency(schedule); + int ret; /* * Disabling the systemd unit while it is already disabled makes @@ -2648,20 +2701,25 @@ static int systemd_timer_enable_unit(int enable, * On the other hand, enabling a systemd unit which is already enabled * produces no error. */ - if (!enable) + if (!enable) { child.no_stderr = 1; - else if (systemd_timer_write_timer_file(schedule, minute)) - return -1; + } else if (systemd_timer_write_timer_file(schedule, minute)) { + ret = -1; + goto out; + } - get_schedule_cmd(&cmd, NULL); + get_schedule_cmd("systemctl", NULL, &cmd); strvec_split(&child.args, cmd); strvec_pushl(&child.args, "--user", enable ? "enable" : "disable", "--now", NULL); strvec_pushf(&child.args, SYSTEMD_UNIT_FORMAT, frequency, "timer"); - if (start_command(&child)) - return error(_("failed to start systemctl")); - if (finish_command(&child)) + if (start_command(&child)) { + ret = error(_("failed to start systemctl")); + goto out; + } + + if (finish_command(&child)) { /* * Disabling an already disabled systemd unit makes * systemctl fail. @@ -2669,9 +2727,17 @@ static int systemd_timer_enable_unit(int enable, * * Enabling an enabled systemd unit doesn't fail. */ - if (enable) - return error(_("failed to run systemctl")); - return 0; + if (enable) { + ret = error(_("failed to run systemctl")); + goto out; + } + } + + ret = 0; + +out: + free(cmd); + return ret; } /* @@ -2854,8 +2920,17 @@ static int update_background_schedule(const struct maintenance_start_opts *opts, char *lock_path = xstrfmt("%s/schedule", the_repository->objects->odb->path); if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0) { + if (errno == EEXIST) + error(_("unable to create '%s.lock': %s.\n\n" + "Another scheduled git-maintenance(1) process seems to be running in this\n" + "repository. Please make sure no other maintenance processes are running and\n" + "then try again. If it still fails, a git-maintenance(1) process may have\n" + "crashed in this repository earlier: remove the file manually to continue."), + absolute_path(lock_path), strerror(errno)); + else + error_errno(_("cannot acquire lock for scheduled background maintenance")); free(lock_path); - return error(_("another process is scheduling background maintenance")); + return -1; } for (i = 1; i < ARRAY_SIZE(scheduler_fn); i++) { @@ -2881,7 +2956,8 @@ static const char *const builtin_maintenance_start_usage[] = { NULL }; -static int maintenance_start(int argc, const char **argv, const char *prefix) +static int maintenance_start(int argc, const char **argv, const char *prefix, + struct repository *repo) { struct maintenance_start_opts opts = { 0 }; struct option options[] = { @@ -2904,7 +2980,7 @@ static int maintenance_start(int argc, const char **argv, const char *prefix) if (update_background_schedule(&opts, 1)) die(_("failed to set up maintenance schedule")); - if (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL)) + if (maintenance_register(ARRAY_SIZE(register_args)-1, register_args, NULL, repo)) warning(_("failed to add repo to global config")); return 0; } @@ -2914,7 +2990,8 @@ static const char *const builtin_maintenance_stop_usage[] = { NULL }; -static int maintenance_stop(int argc, const char **argv, const char *prefix) +static int maintenance_stop(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() @@ -2934,7 +3011,7 @@ static const char * const builtin_maintenance_usage[] = { int cmd_maintenance(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_maintenance_options[] = { @@ -2948,5 +3025,5 @@ int cmd_maintenance(int argc, argc = parse_options(argc, argv, prefix, builtin_maintenance_options, builtin_maintenance_usage, 0); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/get-tar-commit-id.c b/builtin/get-tar-commit-id.c index 6bec0d1854c03e..e4cd1627b44bcc 100644 --- a/builtin/get-tar-commit-id.c +++ b/builtin/get-tar-commit-id.c @@ -13,7 +13,7 @@ static const char builtin_get_tar_commit_id_usage[] = #define HEADERSIZE (2 * RECORDSIZE) int cmd_get_tar_commit_id(int argc, - const char **argv UNUSED, + const char **argv, const char *prefix, struct repository *repo UNUSED) { @@ -27,6 +27,8 @@ int cmd_get_tar_commit_id(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, builtin_get_tar_commit_id_usage); + if (argc != 1) usage(builtin_get_tar_commit_id_usage); diff --git a/builtin/grep.c b/builtin/grep.c index f17d46a06e46ba..d1427290f773b6 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -3,7 +3,10 @@ * * Copyright (c) 2006 Junio C Hamano */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -906,6 +909,7 @@ int cmd_grep(int argc, int dummy; int use_index = 1; int allow_revs; + int ret; struct option options[] = { OPT_BOOL(0, "cached", &cached, @@ -1080,7 +1084,7 @@ int cmd_grep(int argc, } if (show_in_pager == default_pager) - show_in_pager = git_pager(1); + show_in_pager = git_pager(the_repository, 1); if (show_in_pager) { opt.color = 0; opt.name_only = 1; @@ -1172,8 +1176,10 @@ int cmd_grep(int argc, * Optimize out the case where the amount of matches is limited to zero. * We do this to keep results consistent with GNU grep(1). */ - if (opt.max_count == 0) - return 1; + if (opt.max_count == 0) { + ret = 1; + goto out; + } if (show_in_pager) { if (num_threads > 1) @@ -1240,7 +1246,7 @@ int cmd_grep(int argc, } if (!show_in_pager && !opt.status_only) - setup_pager(); + setup_pager(the_repository); die_for_incompatible_opt3(!use_index, "--no-index", untracked, "--untracked", @@ -1267,10 +1273,14 @@ int cmd_grep(int argc, hit |= wait_all(); if (hit && show_in_pager) run_pager(&opt, prefix); + + ret = !hit; + +out: clear_pathspec(&pathspec); string_list_clear(&path_list, 0); free_grep_patterns(&opt); object_array_clear(&list); free_repos(); - return !hit; + return ret; } diff --git a/builtin/help.c b/builtin/help.c index a509241a80fc0c..c257079cebc3c0 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -1,8 +1,9 @@ - /* * Builtin help command */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "exec-cmd.h" @@ -54,7 +55,7 @@ static enum help_action { HELP_ACTION_CONFIG_SECTIONS_FOR_COMPLETION, } cmd_mode; -static const char *html_path; +static char *html_path; static int verbose = 1; static enum help_format help_format = HELP_FORMAT_NONE; static int exclude_guides; @@ -129,7 +130,6 @@ static void list_config_help(enum show_config_type type) struct string_list keys = STRING_LIST_INIT_DUP; struct string_list keys_uniq = STRING_LIST_INIT_DUP; struct string_list_item *item; - int i; for (p = config_name_list; *p; p++) { const char *var = *p; @@ -156,7 +156,7 @@ static void list_config_help(enum show_config_type type) e->prefix, e->placeholder); string_list_sort(&keys); - for (i = 0; i < keys.nr; i++) { + for (size_t i = 0; i < keys.nr; i++) { const char *var = keys.items[i].string; const char *wildcard, *tag, *cut; const char *dot = NULL; @@ -411,6 +411,7 @@ static int git_help_config(const char *var, const char *value, if (!strcmp(var, "help.htmlpath")) { if (!value) return config_error_nonbool(var); + free(html_path); html_path = xstrdup(value); return 0; } @@ -515,23 +516,24 @@ static void show_info_page(const char *page) static void get_html_page_path(struct strbuf *page_path, const char *page) { struct stat st; + const char *path = html_path; char *to_free = NULL; - if (!html_path) - html_path = to_free = system_path(GIT_HTML_PATH); + if (!path) + path = to_free = system_path(GIT_HTML_PATH); /* * Check that the page we're looking for exists. */ - if (!strstr(html_path, "://")) { - if (stat(mkpath("%s/%s.html", html_path, page), &st) + if (!strstr(path, "://")) { + if (stat(mkpath("%s/%s.html", path, page), &st) || !S_ISREG(st.st_mode)) die("'%s/%s.html': documentation file not found.", - html_path, page); + path, page); } strbuf_init(page_path, 0); - strbuf_addf(page_path, "%s/%s.html", html_path, page); + strbuf_addf(page_path, "%s/%s.html", path, page); free(to_free); } @@ -549,12 +551,12 @@ static void show_html_page(const char *page) open_html(page_path.buf); } -static const char *check_git_cmd(const char* cmd) +static char *check_git_cmd(const char *cmd) { char *alias; if (is_git_command(cmd)) - return cmd; + return xstrdup(cmd); alias = alias_lookup(cmd); if (alias) { @@ -587,14 +589,13 @@ static const char *check_git_cmd(const char* cmd) die(_("bad alias.%s string: %s"), cmd, split_cmdline_strerror(count)); free(argv); - UNLEAK(alias); return alias; } if (exclude_guides) return help_unknown_cmd(cmd); - return cmd; + return xstrdup(cmd); } static void no_help_format(const char *opt_mode, enum help_format fmt) @@ -640,6 +641,7 @@ int cmd_help(int argc, { int nongit; enum help_format parsed_help_format; + char *command = NULL; const char *page; argc = parse_options(argc, argv, prefix, builtin_help_options, @@ -656,7 +658,7 @@ int cmd_help(int argc, case HELP_ACTION_ALL: opt_mode_usage(argc, "--all", help_format); if (verbose) { - setup_pager(); + setup_pager(the_repository); list_all_cmds_help(show_external_commands, show_aliases); return 0; @@ -690,7 +692,7 @@ int cmd_help(int argc, return 0; case HELP_ACTION_CONFIG: opt_mode_usage(argc, "--config", help_format); - setup_pager(); + setup_pager(the_repository); list_config_help(SHOW_CONFIG_HUMAN); printf("\n%s\n", _("'git help config' for more information")); return 0; @@ -711,9 +713,9 @@ int cmd_help(int argc, if (help_format == HELP_FORMAT_NONE) help_format = parse_help_format(DEFAULT_HELP_FORMAT); - argv[0] = check_git_cmd(argv[0]); + command = check_git_cmd(argv[0]); - page = cmd_to_page(argv[0]); + page = cmd_to_page(command); switch (help_format) { case HELP_FORMAT_NONE: case HELP_FORMAT_MAN: @@ -727,5 +729,6 @@ int cmd_help(int argc, break; } + free(command); return 0; } diff --git a/builtin/hook.c b/builtin/hook.c index 367ef3e0b893fa..672d2e37e845a2 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -19,7 +19,8 @@ static const char * const builtin_hook_run_usage[] = { NULL }; -static int run(int argc, const char **argv, const char *prefix) +static int run(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i; struct run_hooks_opt opt = RUN_HOOKS_OPT_INIT; @@ -70,7 +71,7 @@ static int run(int argc, const char **argv, const char *prefix) int cmd_hook(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_hook_options[] = { @@ -81,5 +82,5 @@ int cmd_hook(int argc, argc = parse_options(argc, argv, NULL, builtin_hook_options, builtin_hook_usage, 0); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/index-pack.c b/builtin/index-pack.c index e228c56ff2701b..52cc97d52cb674 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "delta.h" @@ -9,6 +11,7 @@ #include "csum-file.h" #include "blob.h" #include "commit.h" +#include "tag.h" #include "tree.h" #include "progress.h" #include "fsck.h" @@ -20,9 +23,14 @@ #include "object-file.h" #include "object-store-ll.h" #include "oid-array.h" +#include "oidset.h" +#include "path.h" #include "replace-object.h" +#include "tree-walk.h" #include "promisor-remote.h" +#include "run-command.h" #include "setup.h" +#include "strvec.h" static const char index_pack_usage[] = "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>])"; @@ -94,7 +102,7 @@ static LIST_HEAD(done_head); static size_t base_cache_used; static size_t base_cache_limit; -struct thread_local { +struct thread_local_data { pthread_t thread; int pack_fd; }; @@ -117,7 +125,7 @@ static struct object_entry *objects; static struct object_stat *obj_stat; static struct ofs_delta_entry *ofs_deltas; static struct ref_delta_entry *ref_deltas; -static struct thread_local nothread_data; +static struct thread_local_data nothread_data; static int nr_objects; static int nr_ofs_deltas; static int nr_ref_deltas; @@ -143,12 +151,19 @@ static unsigned int input_offset, input_len; static off_t consumed_bytes; static off_t max_input_size; static unsigned deepest_delta; -static git_hash_ctx input_ctx; +static struct git_hash_ctx input_ctx; static uint32_t input_crc32; static int input_fd, output_fd; static const char *curr_pack; -static struct thread_local *thread_data; +/* + * outgoing_links is guarded by read_mutex, and record_outgoing_links is + * read-only in a thread. + */ +static struct oidset outgoing_links = OIDSET_INIT; +static int record_outgoing_links; + +static struct thread_local_data *thread_data; static int nr_dispatched; static int threads_active; @@ -267,7 +282,8 @@ static unsigned check_objects(void) max = get_max_object_index(); if (verbose) - progress = start_delayed_progress(_("Checking objects"), max); + progress = start_delayed_progress(the_repository, + _("Checking objects"), max); for (i = 0; i < max; i++) { foreign_nr += check_object(get_indexed_object(i)); @@ -285,7 +301,7 @@ static void flush(void) if (input_offset) { if (output_fd >= 0) write_or_die(output_fd, input_buffer, input_offset); - the_hash_algo->update_fn(&input_ctx, input_buffer, input_offset); + git_hash_update(&input_ctx, input_buffer, input_offset); memmove(input_buffer, input_buffer + input_offset, input_len); input_offset = 0; } @@ -364,16 +380,18 @@ static const char *open_pack_file(const char *pack_name) static void parse_pack_header(void) { - struct pack_header *hdr = fill(sizeof(struct pack_header)); + unsigned char *hdr = fill(sizeof(struct pack_header)); /* Header consistency check */ - if (hdr->hdr_signature != htonl(PACK_SIGNATURE)) + if (get_be32(hdr) != PACK_SIGNATURE) die(_("pack signature mismatch")); - if (!pack_version_ok(hdr->hdr_version)) + hdr += 4; + if (!pack_version_ok_native(get_be32(hdr))) die(_("pack version %"PRIu32" unsupported"), - ntohl(hdr->hdr_version)); + get_be32(hdr)); + hdr += 4; - nr_objects = ntohl(hdr->hdr_entries); + nr_objects = get_be32(hdr); use(sizeof(struct pack_header)); } @@ -390,7 +408,7 @@ static NORETURN void bad_object(off_t offset, const char *format, ...) (uintmax_t)offset, buf); } -static inline struct thread_local *get_thread_data(void) +static inline struct thread_local_data *get_thread_data(void) { if (HAVE_THREADS) { if (threads_active) @@ -401,7 +419,7 @@ static inline struct thread_local *get_thread_data(void) return ¬hread_data; } -static void set_thread_data(struct thread_local *data) +static void set_thread_data(struct thread_local_data *data) { if (threads_active) pthread_setspecific(key, data); @@ -457,14 +475,14 @@ static void *unpack_entry_data(off_t offset, unsigned long size, int status; git_zstream stream; void *buf; - git_hash_ctx c; + struct git_hash_ctx c; char hdr[32]; int hdrlen; if (!is_delta_type(type)) { hdrlen = format_object_header(hdr, sizeof(hdr), type, size); the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, hdr, hdrlen); + git_hash_update(&c, hdr, hdrlen); } else oid = NULL; if (type == OBJ_BLOB && size > big_file_threshold) @@ -484,7 +502,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size, status = git_inflate(&stream, 0); use(input_len - stream.avail_in); if (oid) - the_hash_algo->update_fn(&c, last_out, stream.next_out - last_out); + git_hash_update(&c, last_out, stream.next_out - last_out); if (buf == fixed_buf) { stream.next_out = buf; stream.avail_out = sizeof(fixed_buf); @@ -494,7 +512,7 @@ static void *unpack_entry_data(off_t offset, unsigned long size, bad_object(offset, _("inflate returned %d"), status); git_inflate_end(&stream); if (oid) - the_hash_algo->final_oid_fn(oid, &c); + git_hash_final_oid(oid, &c); return buf == fixed_buf ? NULL : buf; } @@ -799,6 +817,68 @@ static int check_collison(struct object_entry *entry) return 0; } +static void record_outgoing_link(const struct object_id *oid) +{ + oidset_insert(&outgoing_links, oid); +} + +static void maybe_record_name_entry(const struct name_entry *entry) +{ + /* + * Checking only trees here results in a significantly faster packfile + * indexing, but the drawback is that if the packfile to be indexed + * references a local blob only directly (that is, never through a + * local tree), that local blob is in danger of being garbage + * collected. Such a situation may arise if we push local commits, + * including one with a change to a blob in the root tree, and then the + * server incorporates them into its main branch through a "rebase" or + * "squash" merge strategy, and then we fetch the new main branch from + * the server. + * + * This situation has not been observed yet - we have only noticed + * missing commits, not missing trees or blobs. (In fact, if it were + * believed that only missing commits are problematic, one could argue + * that we should also exclude trees during the outgoing link check; + * but it is safer to include them.) + * + * Due to the rarity of the situation (it has not been observed to + * happen in real life), and because the "penalty" in such a situation + * is merely to refetch the missing blob when it's needed (and this + * happens only once - when refetched, the blob goes into a promisor + * pack, so it won't be GC-ed, the tradeoff seems worth it. + */ + if (S_ISDIR(entry->mode)) + record_outgoing_link(&entry->oid); +} + +static void do_record_outgoing_links(struct object *obj) +{ + if (obj->type == OBJ_TREE) { + struct tree *tree = (struct tree *)obj; + struct tree_desc desc; + struct name_entry entry; + if (init_tree_desc_gently(&desc, &tree->object.oid, + tree->buffer, tree->size, 0)) + /* + * Error messages are given when packs are + * verified, so do not print any here. + */ + return; + while (tree_entry_gently(&desc, &entry)) + maybe_record_name_entry(&entry); + } else if (obj->type == OBJ_COMMIT) { + struct commit *commit = (struct commit *) obj; + struct commit_list *parents = commit->parents; + + record_outgoing_link(get_commit_tree_oid(commit)); + for (; parents; parents = parents->next) + record_outgoing_link(&parents->item->object.oid); + } else if (obj->type == OBJ_TAG) { + struct tag *tag = (struct tag *) obj; + record_outgoing_link(get_tagged_oid(tag)); + } +} + static void sha1_object(const void *data, struct object_entry *obj_entry, unsigned long size, enum object_type type, const struct object_id *oid) @@ -845,7 +925,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry, free(has_data); } - if (strict || do_fsck_object) { + if (strict || do_fsck_object || record_outgoing_links) { read_lock(); if (type == OBJ_BLOB) { struct blob *blob = lookup_blob(the_repository, oid); @@ -877,6 +957,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry, die(_("fsck error in packed object")); if (strict && fsck_walk(obj, NULL, &fsck_options)) die(_("Not all child objects of %s are reachable"), oid_to_hex(&obj->oid)); + if (record_outgoing_links) + do_record_outgoing_links(obj); if (obj->type == OBJ_TREE) { struct tree *item = (struct tree *) obj; @@ -1166,10 +1248,11 @@ static void parse_pack_objects(unsigned char *hash) struct ofs_delta_entry *ofs_delta = ofs_deltas; struct object_id ref_delta_oid; struct stat st; - git_hash_ctx tmp_ctx; + struct git_hash_ctx tmp_ctx; if (verbose) progress = start_progress( + the_repository, progress_title ? progress_title : from_stdin ? _("Receiving objects") : _("Indexing objects"), nr_objects); @@ -1203,9 +1286,8 @@ static void parse_pack_objects(unsigned char *hash) /* Check pack integrity */ flush(); - the_hash_algo->init_fn(&tmp_ctx); - the_hash_algo->clone_fn(&tmp_ctx, &input_ctx); - the_hash_algo->final_fn(hash, &tmp_ctx); + git_hash_clone(&tmp_ctx, &input_ctx); + git_hash_final(hash, &tmp_ctx); if (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo)) die(_("pack is corrupted (SHA1 mismatch)")); use(the_hash_algo->rawsz); @@ -1238,7 +1320,7 @@ static void parse_pack_objects(unsigned char *hash) * recursively checking if the resulting object is used as a base * for some more deltas. */ -static void resolve_deltas(void) +static void resolve_deltas(struct pack_idx_option *opts) { int i; @@ -1250,14 +1332,14 @@ static void resolve_deltas(void) QSORT(ref_deltas, nr_ref_deltas, compare_ref_delta_entry); if (verbose || show_resolving_progress) - progress = start_progress(_("Resolving deltas"), + progress = start_progress(the_repository, + _("Resolving deltas"), nr_ref_deltas + nr_ofs_deltas); nr_dispatched = 0; - base_cache_limit = delta_base_cache_limit * nr_threads; + base_cache_limit = opts->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); @@ -1265,7 +1347,6 @@ 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(); @@ -1310,7 +1391,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha strbuf_release(&msg); finalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0); hashcpy(read_hash, pack_hash, the_repository->hash_algo); - fixup_pack_header_footer(output_fd, pack_hash, + fixup_pack_header_footer(the_hash_algo, output_fd, pack_hash, curr_pack, nr_objects, read_hash, consumed_bytes-the_hash_algo->rawsz); if (!hasheq(read_hash, tail_hash, the_repository->hash_algo)) @@ -1479,7 +1560,7 @@ static void write_special_file(const char *suffix, const char *msg, if (pack_name) filename = derive_filename(pack_name, "pack", suffix, &name_buf); else - filename = odb_pack_name(&name_buf, hash, suffix); + filename = odb_pack_name(the_repository, &name_buf, hash, suffix); fd = odb_pack_keep(filename); if (fd < 0) { @@ -1505,9 +1586,9 @@ static void rename_tmp_packfile(const char **final_name, struct strbuf *name, unsigned char *hash, const char *ext, int make_read_only_if_same) { - if (*final_name != curr_name) { + if (!*final_name || strcmp(*final_name, curr_name)) { if (!*final_name) - *final_name = odb_pack_name(name, hash, ext); + *final_name = odb_pack_name(the_repository, name, hash, ext); if (finalize_object_file(curr_name, *final_name)) die(_("unable to rename temporary '*.%s' file to '%s'"), ext, *final_name); @@ -1552,7 +1633,8 @@ static void final(const char *final_pack_name, const char *curr_pack_name, if (do_fsck_object) { struct packed_git *p; - p = add_packed_git(final_index_name, strlen(final_index_name), 0); + p = add_packed_git(the_repository, final_index_name, + strlen(final_index_name), 0); if (p) install_packed_git(the_repository, p); } @@ -1603,6 +1685,10 @@ static int git_index_pack_config(const char *k, const char *v, else opts->flags &= ~WRITE_REV; } + if (!strcmp(k, "core.deltabasecachelimit")) { + opts->delta_base_cache_limit = git_config_ulong(k, v, ctx->kvi); + return 0; + } return git_default_config(k, v, ctx, cb); } @@ -1650,7 +1736,8 @@ static void read_v2_anomalous_offsets(struct packed_git *p, static void read_idx_option(struct pack_idx_option *opts, const char *pack_name) { - struct packed_git *p = add_packed_git(pack_name, strlen(pack_name), 1); + struct packed_git *p = add_packed_git(the_repository, pack_name, + strlen(pack_name), 1); if (!p) die(_("Cannot open existing pack file '%s'"), pack_name); @@ -1719,6 +1806,73 @@ static void show_pack_info(int stat_only) free(chain_histogram); } +static void repack_local_links(void) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + FILE *out; + struct strbuf line = STRBUF_INIT; + struct oidset_iter iter; + struct object_id *oid; + char *base_name = NULL; + + if (!oidset_size(&outgoing_links)) + return; + + oidset_iter_init(&outgoing_links, &iter); + while ((oid = oidset_iter_next(&iter))) { + struct object_info info = OBJECT_INFO_INIT; + if (oid_object_info_extended(the_repository, oid, &info, 0)) + /* Missing; assume it is a promisor object */ + continue; + if (info.whence == OI_PACKED && info.u.packed.pack->pack_promisor) + continue; + + if (!cmd.args.nr) { + base_name = mkpathdup( + "%s/pack/pack", + repo_get_object_directory(the_repository)); + strvec_push(&cmd.args, "pack-objects"); + strvec_push(&cmd.args, + "--exclude-promisor-objects-best-effort"); + strvec_push(&cmd.args, base_name); + cmd.git_cmd = 1; + cmd.in = -1; + cmd.out = -1; + if (start_command(&cmd)) + die(_("could not start pack-objects to repack local links")); + } + + if (write_in_full(cmd.in, oid_to_hex(oid), the_hash_algo->hexsz) < 0 || + write_in_full(cmd.in, "\n", 1) < 0) + die(_("failed to feed local object to pack-objects")); + } + + if (!cmd.args.nr) + return; + + close(cmd.in); + + out = xfdopen(cmd.out, "r"); + while (strbuf_getline_lf(&line, out) != EOF) { + unsigned char binary[GIT_MAX_RAWSZ]; + if (line.len != the_hash_algo->hexsz || + !hex_to_bytes(binary, line.buf, line.len)) + die(_("index-pack: Expecting full hex object ID lines only from pack-objects.")); + + /* + * pack-objects creates the .pack and .idx files, but not the + * .promisor file. Create the .promisor file, which is empty. + */ + write_special_file("promisor", "", NULL, binary, NULL); + } + + fclose(out); + if (finish_command(&cmd)) + die(_("could not finish pack-objects to repack local links")); + strbuf_release(&line); + free(base_name); +} + int cmd_index_pack(int argc, const char **argv, const char *prefix, @@ -1726,7 +1880,7 @@ int cmd_index_pack(int argc, { int i, fix_thin_pack = 0, verify = 0, stat_only = 0, rev_index; const char *curr_index; - const char *curr_rev_index = NULL; + char *curr_rev_index = NULL; const char *index_name = NULL, *pack_name = NULL, *rev_index_name = NULL; const char *keep_msg = NULL; const char *promisor_msg = NULL; @@ -1747,8 +1901,7 @@ int cmd_index_pack(int argc, */ fetch_if_missing = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(index_pack_usage); + show_usage_if_asked(argc, argv, index_pack_usage); disable_replace_refs(); fsck_options.walk = mark_link; @@ -1794,7 +1947,7 @@ int cmd_index_pack(int argc, } else if (skip_to_optional_arg(arg, "--keep", &keep_msg)) { ; /* nothing to do */ } else if (skip_to_optional_arg(arg, "--promisor", &promisor_msg)) { - ; /* already parsed */ + record_outgoing_links = 1; } else if (starts_with(arg, "--threads=")) { char *end; nr_threads = strtoul(arg+10, &end, 0); @@ -1804,19 +1957,11 @@ int cmd_index_pack(int argc, warning(_("no threads support, ignoring %s"), arg); nr_threads = 1; } - } else if (starts_with(arg, "--pack_header=")) { - struct pack_header *hdr; - char *c; - - hdr = (struct pack_header *)input_buffer; - hdr->hdr_signature = htonl(PACK_SIGNATURE); - hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); - if (*c != ',') - die(_("bad %s"), arg); - hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); - if (*c) - die(_("bad %s"), arg); - input_len = sizeof(*hdr); + } else if (skip_prefix(arg, "--pack_header=", &arg)) { + if (parse_pack_header_option(arg, + input_buffer, + &input_len) < 0) + die(_("bad --pack_header: %s"), arg); } else if (!strcmp(arg, "-v")) { verbose = 1; } else if (!strcmp(arg, "--progress-title")) { @@ -1865,6 +2010,8 @@ int cmd_index_pack(int argc, usage(index_pack_usage); if (fix_thin_pack && !from_stdin) die(_("the option '%s' requires '%s'"), "--fix-thin", "--stdin"); + if (promisor_msg && pack_name) + die(_("--promisor cannot be used with a pack name")); if (from_stdin && !startup_info->have_repository) die(_("--stdin requires a git repository")); if (from_stdin && hash_algo) @@ -1928,7 +2075,7 @@ int cmd_index_pack(int argc, parse_pack_objects(pack_hash); if (report_end_of_input) write_in_full(2, "\0", 1); - resolve_deltas(); + resolve_deltas(&opts); conclude_pack(fix_thin_pack, curr_pack, pack_hash); free(ofs_deltas); free(ref_deltas); @@ -1941,11 +2088,12 @@ int cmd_index_pack(int argc, ALLOC_ARRAY(idx_objects, nr_objects); for (i = 0; i < nr_objects; i++) idx_objects[i] = &objects[i].idx; - curr_index = write_idx_file(index_name, idx_objects, nr_objects, &opts, pack_hash); + curr_index = write_idx_file(the_hash_algo, index_name, idx_objects, + nr_objects, &opts, pack_hash); if (rev_index) - curr_rev_index = write_rev_file(rev_index_name, idx_objects, - nr_objects, pack_hash, - opts.flags); + curr_rev_index = write_rev_file(the_hash_algo, rev_index_name, + idx_objects, nr_objects, + pack_hash, opts.flags); free(idx_objects); if (!verify) @@ -1968,8 +2116,9 @@ int cmd_index_pack(int argc, free((void *) curr_pack); if (!index_name) free((void *) curr_index); - if (!rev_index_name) - free((void *) curr_rev_index); + free(curr_rev_index); + + repack_local_links(); /* * Let the caller know this pack is not self contained diff --git a/builtin/init-db.c b/builtin/init-db.c index 7e00d57d654e68..196dccdd77acb8 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -75,10 +75,12 @@ int cmd_init_db(int argc, const char *prefix, struct repository *repo UNUSED) { - const char *git_dir; + char *git_dir; const char *real_git_dir = NULL; - const char *work_tree; + char *real_git_dir_to_free = NULL; + char *work_tree = NULL; const char *template_dir = NULL; + char *template_dir_to_free = NULL; unsigned int flags = 0; const char *object_format = NULL; const char *ref_format = NULL; @@ -106,6 +108,7 @@ int cmd_init_db(int argc, N_("specify the reference format to use")), OPT_END() }; + int ret; argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); @@ -113,12 +116,10 @@ int cmd_init_db(int argc, die(_("options '%s' and '%s' cannot be used together"), "--separate-git-dir", "--bare"); if (real_git_dir && !is_absolute_path(real_git_dir)) - real_git_dir = real_pathdup(real_git_dir, 1); + real_git_dir = real_git_dir_to_free = real_pathdup(real_git_dir, 1); - if (template_dir && *template_dir && !is_absolute_path(template_dir)) { - template_dir = absolute_pathdup(template_dir); - UNLEAK(template_dir); - } + if (template_dir && *template_dir && !is_absolute_path(template_dir)) + template_dir = template_dir_to_free = absolute_pathdup(template_dir); if (argc == 1) { int mkdir_tried = 0; @@ -131,8 +132,8 @@ int cmd_init_db(int argc, * and we know shared_repository should always be 0; * but just in case we play safe. */ - saved = get_shared_repository(); - set_shared_repository(0); + saved = repo_settings_get_shared_repository(the_repository); + repo_settings_set_shared_repository(the_repository, 0); switch (safe_create_leading_directories_const(argv[0])) { case SCLD_OK: case SCLD_PERMS: @@ -144,7 +145,7 @@ int cmd_init_db(int argc, die_errno(_("cannot mkdir %s"), argv[0]); break; } - set_shared_repository(saved); + repo_settings_set_shared_repository(the_repository, saved); if (mkdir(argv[0], 0777) < 0) die_errno(_("cannot mkdir %s"), argv[0]); mkdir_tried = 1; @@ -174,7 +175,7 @@ int cmd_init_db(int argc, } if (init_shared_repository != -1) - set_shared_repository(init_shared_repository); + repo_settings_set_shared_repository(the_repository, init_shared_repository); /* * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR @@ -192,7 +193,7 @@ int cmd_init_db(int argc, * Set up the default .git directory contents */ if (!git_dir) - git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; + git_dir = xstrdup(DEFAULT_GIT_DIR_ENVIRONMENT); /* * When --separate-git-dir is used inside a linked worktree, take @@ -213,6 +214,7 @@ int cmd_init_db(int argc, if (chdir(mainwt.buf) < 0) die_errno(_("cannot chdir to %s"), mainwt.buf); strbuf_release(&mainwt); + free(git_dir); git_dir = strbuf_detach(&sb, NULL); } strbuf_release(&sb); @@ -245,12 +247,14 @@ int cmd_init_db(int argc, set_git_work_tree(work_tree); } - UNLEAK(real_git_dir); - UNLEAK(git_dir); - UNLEAK(work_tree); - flags |= INIT_DB_EXIST_OK; - return init_db(git_dir, real_git_dir, template_dir, hash_algo, - ref_storage_format, initial_branch, - init_shared_repository, flags); + ret = init_db(git_dir, real_git_dir, template_dir, hash_algo, + ref_storage_format, initial_branch, + init_shared_repository, flags); + + free(template_dir_to_free); + free(real_git_dir_to_free); + free(work_tree); + free(git_dir); + return ret; } diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index c5e56e2cd3d6f6..44d8ccddc9d8de 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -141,8 +141,8 @@ static void interpret_trailers(const struct process_trailer_options *opts, { LIST_HEAD(head); struct strbuf sb = STRBUF_INIT; - struct strbuf trailer_block = STRBUF_INIT; - struct trailer_info *info; + struct strbuf trailer_block_sb = STRBUF_INIT; + struct trailer_block *trailer_block; FILE *outfile = stdout; trailer_config_init(); @@ -152,13 +152,13 @@ static void interpret_trailers(const struct process_trailer_options *opts, if (opts->in_place) outfile = create_in_place_tempfile(file); - info = parse_trailers(opts, sb.buf, &head); + trailer_block = parse_trailers(opts, sb.buf, &head); - /* Print the lines before the trailers */ + /* Print the lines before the trailer block */ if (!opts->only_trailers) - fwrite(sb.buf, 1, trailer_block_start(info), outfile); + fwrite(sb.buf, 1, trailer_block_start(trailer_block), outfile); - if (!opts->only_trailers && !blank_line_before_trailer_block(info)) + if (!opts->only_trailers && !blank_line_before_trailer_block(trailer_block)) fprintf(outfile, "\n"); @@ -172,15 +172,16 @@ static void interpret_trailers(const struct process_trailer_options *opts, } /* Print trailer block. */ - format_trailers(opts, &head, &trailer_block); + format_trailers(opts, &head, &trailer_block_sb); free_trailers(&head); - fwrite(trailer_block.buf, 1, trailer_block.len, outfile); - strbuf_release(&trailer_block); + fwrite(trailer_block_sb.buf, 1, trailer_block_sb.len, outfile); + strbuf_release(&trailer_block_sb); - /* Print the lines after the trailers as is */ + /* Print the lines after the trailer block as is. */ if (!opts->only_trailers) - fwrite(sb.buf + trailer_block_end(info), 1, sb.len - trailer_block_end(info), outfile); - trailer_info_release(info); + fwrite(sb.buf + trailer_block_end(trailer_block), 1, + sb.len - trailer_block_end(trailer_block), outfile); + trailer_block_release(trailer_block); if (opts->in_place) if (rename_tempfile(&trailers_tempfile, file)) diff --git a/builtin/log.c b/builtin/log.c index 368f6580a6eb88..04a6ef97bc1442 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -4,7 +4,9 @@ * (C) Copyright 2006 Linus Torvalds * 2006 Junio Hamano */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" #include "config.h" @@ -206,7 +208,6 @@ static void cmd_log_init_defaults(struct rev_info *rev, static void set_default_decoration_filter(struct decoration_filter *decoration_filter) { - int i; char *value = NULL; struct string_list *include = decoration_filter->include_ref_pattern; const struct string_list *config_exclude; @@ -240,7 +241,7 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f * No command-line or config options were given, so * populate with sensible defaults. */ - for (i = 0; i < ARRAY_SIZE(ref_namespace); i++) { + for (size_t i = 0; i < ARRAY_SIZE(ref_namespace); i++) { if (!ref_namespace[i].decoration) continue; @@ -366,7 +367,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, if (rev->line_level_traverse) line_log_init(rev, line_cb.prefix, &line_cb.args); - setup_pager(); + setup_pager(the_repository); } static void cmd_log_init(int argc, const char **argv, const char *prefix, @@ -528,10 +529,14 @@ static int cmd_log_walk_no_free(struct rev_info *rev) * but we didn't actually show the commit. */ rev->max_count++; - if (!rev->reflog_info) { + if (!rev->reflog_info && !rev->remerge_diff) { /* * We may show a given commit multiple times when - * walking the reflogs. + * walking the reflogs. Therefore we still need it. + * + * Likewise, we potentially still need the parents + * of * already shown commits to determine merge + * bases when showing remerge diffs. */ free_commit_buffer(the_repository->parsed_objects, commit); @@ -710,14 +715,14 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev) unsigned long size; enum object_type type; char *buf = repo_read_object_file(the_repository, oid, &type, &size); - int offset = 0; + unsigned long offset = 0; if (!buf) return error(_("could not read object %s"), oid_to_hex(oid)); assert(type == OBJ_TAG); while (offset < size && buf[offset] != '\n') { - int new_offset = offset + 1; + unsigned long new_offset = offset + 1; const char *ident; while (new_offset < size && buf[new_offset++] != '\n') ; /* do nothing */ @@ -1309,24 +1314,25 @@ static void print_signature(const char *signature, FILE *file) static char *find_branch_name(struct rev_info *rev) { - int i, positive = -1; struct object_id branch_oid; const struct object_id *tip_oid; const char *ref, *v; char *full_ref, *branch = NULL; + int interesting_found = 0; + size_t idx; - for (i = 0; i < rev->cmdline.nr; i++) { + for (size_t i = 0; i < rev->cmdline.nr; i++) { if (rev->cmdline.rev[i].flags & UNINTERESTING) continue; - if (positive < 0) - positive = i; - else + if (interesting_found) return NULL; + interesting_found = 1; + idx = i; } - if (positive < 0) + if (!interesting_found) return NULL; - ref = rev->cmdline.rev[positive].name; - tip_oid = &rev->cmdline.rev[positive].item->oid; + ref = rev->cmdline.rev[idx].name; + tip_oid = &rev->cmdline.rev[idx].item->oid; if (repo_dwim_ref(the_repository, ref, strlen(ref), &branch_oid, &full_ref, 0) && skip_prefix(full_ref, "refs/heads/", &v) && @@ -1739,11 +1745,12 @@ struct base_tree_info { static struct commit *get_base_commit(const struct format_config *cfg, struct commit **list, - int total) + size_t total) { struct commit *base = NULL; struct commit **rev; - int i = 0, rev_nr = 0, auto_select, die_on_failure, ret; + int auto_select, die_on_failure, ret; + size_t i = 0, rev_nr = 0; switch (cfg->auto_base) { case AUTO_BASE_NEVER: @@ -1878,13 +1885,12 @@ define_commit_slab(commit_base, int); static void prepare_bases(struct base_tree_info *bases, struct commit *base, struct commit **list, - int total) + size_t total) { struct commit *commit; struct rev_info revs; struct diff_options diffopt; struct commit_base commit_base; - int i; if (!base) return; @@ -1899,7 +1905,7 @@ static void prepare_bases(struct base_tree_info *bases, repo_init_revisions(the_repository, &revs, NULL); revs.max_parents = 1; revs.topo_order = 1; - for (i = 0; i < total; i++) { + for (size_t i = 0; i < total; i++) { list[i]->object.flags &= ~UNINTERESTING; add_pending_object(&revs, &list[i]->object, "rev_list"); *commit_base_at(&commit_base, list[i]) = 1; @@ -2000,7 +2006,7 @@ int cmd_format_patch(int argc, struct rev_info rev; char *to_free = NULL; struct setup_revision_opt s_r_opt; - int nr = 0, total, i; + size_t nr = 0, total, i; int use_stdout = 0; int start_number = -1; int just_numbers = 0; @@ -2176,7 +2182,7 @@ int cmd_format_patch(int argc, fmt_patch_suffix = cfg.fmt_patch_suffix; /* Make sure "0000-$sub.patch" gives non-negative length for $sub */ - if (cfg.log.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix)) + if (cfg.log.fmt_patch_name_max <= cast_size_t_to_int(strlen("0000-") + strlen(fmt_patch_suffix))) cfg.log.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix); if (cover_from_description_arg) @@ -2289,7 +2295,7 @@ int cmd_format_patch(int argc, rev.commit_format = CMIT_FMT_MBOXRD; if (use_stdout) { - setup_pager(); + setup_pager(the_repository); } else if (!rev.diffopt.close_file) { int saved; @@ -2303,8 +2309,8 @@ int cmd_format_patch(int argc, * We consider <outdir> as 'outside of gitdir', therefore avoid * applying adjust_shared_perm in s-c-l-d. */ - saved = get_shared_repository(); - set_shared_repository(0); + saved = repo_settings_get_shared_repository(the_repository); + repo_settings_set_shared_repository(the_repository, 0); switch (safe_create_leading_directories_const(output_directory)) { case SCLD_OK: case SCLD_EXISTS: @@ -2313,7 +2319,7 @@ int cmd_format_patch(int argc, die(_("could not create leading directories " "of '%s'"), output_directory); } - set_shared_repository(saved); + repo_settings_set_shared_repository(the_repository, saved); if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) die_errno(_("could not create directory '%s'"), output_directory); @@ -2492,12 +2498,16 @@ int cmd_format_patch(int argc, rev.add_signoff = cfg.do_signoff; if (show_progress) - progress = start_delayed_progress(_("Generating patches"), total); - while (0 <= --nr) { + progress = start_delayed_progress(the_repository, + _("Generating patches"), total); + for (i = 0; i < nr; i++) { + size_t idx = nr - i - 1; int shown; - display_progress(progress, total - nr); - commit = list[nr]; - rev.nr = total - nr + (start_number - 1); + + display_progress(progress, total - idx); + commit = list[idx]; + rev.nr = total - idx + (start_number - 1); + /* Make the second and subsequent mails replies to the first */ if (cfg.thread) { /* Have we already had a message ID? */ diff --git a/builtin/ls-files.c b/builtin/ls-files.c index e016b0415d167e..a4431429b7de42 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -5,7 +5,10 @@ * * Copyright (C) Linus Torvalds, 2005 */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "convert.h" @@ -641,8 +644,8 @@ int cmd_ls_files(int argc, }; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(ls_files_usage, builtin_ls_files_options); + show_usage_with_options_if_asked(argc, argv, + ls_files_usage, builtin_ls_files_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index f723b3bf3bb5d9..42f34e123610c1 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -166,6 +166,7 @@ int cmd_ls_remote(int argc, status = 0; /* we found something */ } + string_list_clear(&server_options, 0); ref_sorting_release(sorting); ref_array_clear(&ref_array); if (transport_disconnect(transport)) @@ -173,5 +174,6 @@ int cmd_ls_remote(int argc, transport_ls_refs_options_release(&transport_options); strvec_clear(&pattern); + string_list_clear(&server_options, 0); return status; } diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index e17dec27b1df69..8de7ba7de1d6aa 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -83,7 +83,7 @@ int cmd_mailinfo(int argc, OPT_END() }; - setup_mailinfo(&mi); + setup_mailinfo(the_repository, &mi); meta_charset.policy = CHARSET_DEFAULT; argc = parse_options(argc, argv, prefix, options, mailinfo_usage, 0); diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c index b8f7150ce9a5b4..264df6259a0411 100644 --- a/builtin/mailsplit.c +++ b/builtin/mailsplit.c @@ -4,6 +4,9 @@ * It just splits a mbox into a list of files: "0001" "0002" .. * so you can process them further from there. */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "gettext.h" #include "string-list.h" @@ -172,7 +175,6 @@ static int split_maildir(const char *maildir, const char *dir, char *file = NULL; FILE *f = NULL; int ret = -1; - int i; struct string_list list = STRING_LIST_INIT_DUP; list.cmp = maildir_filename_cmp; @@ -180,7 +182,7 @@ static int split_maildir(const char *maildir, const char *dir, if (populate_maildir_list(&list, maildir) < 0) goto out; - for (i = 0; i < list.nr; i++) { + for (size_t i = 0; i < list.nr; i++) { char *name; free(file); @@ -282,6 +284,8 @@ int cmd_mailsplit(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, git_mailsplit_usage); + for (argp = argv+1; *argp; argp++) { const char *arg = *argp; @@ -295,8 +299,6 @@ int cmd_mailsplit(int argc, continue; } else if ( arg[1] == 'f' ) { nr = strtol(arg+2, NULL, 10); - } else if ( arg[1] == 'h' ) { - usage(git_mailsplit_usage); } else if ( arg[1] == 'b' && !arg[2] ) { allow_bare = 1; } else if (!strcmp(arg, "--keep-cr")) { diff --git a/builtin/merge-base.c b/builtin/merge-base.c index a20c93b11aaa0b..123c81515e1f5f 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -8,7 +8,7 @@ #include "parse-options.h" #include "commit-reach.h" -static int show_merge_base(struct commit **rev, int rev_nr, int show_all) +static int show_merge_base(struct commit **rev, size_t rev_nr, int show_all) { struct commit_list *result = NULL, *r; @@ -149,7 +149,7 @@ int cmd_merge_base(int argc, struct repository *repo UNUSED) { struct commit **rev; - int rev_nr = 0; + size_t rev_nr = 0; int show_all = 0; int cmdmode = 0; int ret; diff --git a/builtin/merge-file.c b/builtin/merge-file.c index cb42865eb524bc..7e315f374b2425 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "diff.h" diff --git a/builtin/merge-index.c b/builtin/merge-index.c index a5b87ee3c5e3de..3314fb13361d64 100644 --- a/builtin/merge-index.c +++ b/builtin/merge-index.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "hex.h" #include "read-cache-ll.h" @@ -73,6 +75,9 @@ static void merge_all(void) } } +static const char usage_string[] = +"git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])"; + int cmd_merge_index(int argc, const char **argv, const char *prefix UNUSED, @@ -85,8 +90,10 @@ int cmd_merge_index(int argc, */ signal(SIGCHLD, SIG_DFL); + show_usage_if_asked(argc, argv, usage_string); + if (argc < 3) - usage("git merge-index [-o] [-q] <merge-program> (-a | [--] [<filename>...])"); + usage(usage_string); repo_read_index(the_repository); diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c index 1fcf53f0054e94..97b8a792c77eb7 100644 --- a/builtin/merge-ours.c +++ b/builtin/merge-ours.c @@ -7,7 +7,9 @@ * * Pretend we resolved the heads, but declare our tree trumps everybody else. */ + #define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "builtin.h" #include "diff.h" @@ -21,8 +23,7 @@ int cmd_merge_ours(int argc, const char *prefix UNUSED, struct repository *repo UNUSED) { - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(builtin_merge_ours_usage); + show_usage_if_asked(argc, argv, builtin_merge_ours_usage); /* * The contents of the current index becomes the tree we diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index 1dd295558b207d..abfc060e28a863 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -38,6 +38,12 @@ int cmd_merge_recursive(int argc, if (argv[0] && ends_with(argv[0], "-subtree")) o.subtree_shift = ""; + if (argc == 2 && !strcmp(argv[1], "-h")) { + struct strbuf msg = STRBUF_INIT; + strbuf_addf(&msg, builtin_merge_recursive_usage, argv[0]); + show_usage_if_asked(argc, argv, msg.buf); + } + if (argc < 4) usagef(builtin_merge_recursive_usage, argv[0]); diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index c5ed472967a692..3ec7127b3a6b3f 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "tree-walk.h" #include "xdiff-interface.h" @@ -17,6 +18,7 @@ #include "tree.h" #include "config.h" #include "strvec.h" +#include "write-or-die.h" static int line_termination = '\n'; @@ -497,10 +499,9 @@ static int real_merge(struct merge_tree_options *o, if (!result.clean) { struct string_list conflicted_files = STRING_LIST_INIT_NODUP; const char *last = NULL; - int i; merge_get_conflicted_files(&result, &conflicted_files); - for (i = 0; i < conflicted_files.nr; i++) { + for (size_t i = 0; i < conflicted_files.nr; i++) { const char *name = conflicted_files.items[i].string; struct stage_info *c = conflicted_files.items[i].util; if (!o->name_only) @@ -575,7 +576,7 @@ int cmd_merge_tree(int argc, }; /* Init merge options */ - init_ui_merge_options(&o.merge_options, the_repository); + init_basic_merge_options(&o.merge_options, the_repository); /* Parse arguments */ original_argc = argc - 1; /* ignoring argv[0] */ @@ -584,7 +585,7 @@ int cmd_merge_tree(int argc, if (xopts.nr && o.mode == MODE_TRIVIAL) die(_("--trivial-merge is incompatible with all other options")); - for (int x = 0; x < xopts.nr; x++) + for (size_t x = 0; x < xopts.nr; x++) if (parse_merge_opt(&o.merge_options, xopts.v[x])) die(_("unknown strategy option: -X%s"), xopts.v[x]); @@ -600,7 +601,6 @@ int cmd_merge_tree(int argc, line_termination = '\0'; while (strbuf_getline_lf(&buf, stdin) != EOF) { struct strbuf **split; - int result; const char *input_merge_base = NULL; split = strbuf_split(&buf, ' '); @@ -617,15 +617,14 @@ int cmd_merge_tree(int argc, if (input_merge_base && split[2] && split[3] && !split[4]) { strbuf_rtrim(split[2]); strbuf_rtrim(split[3]); - result = real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix); + real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix); } else if (!input_merge_base && !split[2]) { - result = real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix); + real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix); } else { die(_("malformed input line: '%s'."), buf.buf); } + maybe_flush_or_die(stdout, "stdout"); - if (result < 0) - die(_("merging cannot continue; got unclean result of %d"), result); strbuf_list_free(split); } strbuf_release(&buf); diff --git a/builtin/merge.c b/builtin/merge.c index 84d0f3604bc36c..ba9faf126aa7a4 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -5,7 +5,10 @@ * * Based on git-merge.sh by Junio C Hamano. */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" @@ -498,7 +501,7 @@ static void merge_name(const char *remote, struct strbuf *msg) char *found_ref = NULL; int len, early; - strbuf_branchname(&bname, remote, 0); + copy_branchname(&bname, remote, 0); remote = bname.buf; oidclr(&branch_head, the_repository->hash_algo); @@ -754,6 +757,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, clean = merge_recursive(&o, head, remoteheads->item, reversed, &result); free_commit_list(reversed); + strbuf_release(&o.obuf); if (clean < 0) { rollback_lock_file(&lock); @@ -1296,8 +1300,8 @@ int cmd_merge(int argc, void *branch_to_free; int orig_argc = argc; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_merge_usage, builtin_merge_options); + show_usage_with_options_if_asked(argc, argv, + builtin_merge_usage, builtin_merge_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index d159ed1314d912..2a938466f53aaa 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -119,7 +119,8 @@ static void read_packs_from_stdin(struct string_list *to) } static int cmd_multi_pack_index_write(int argc, const char **argv, - const char *prefix) + const char *prefix, + struct repository *repo) { struct option *options; static struct option builtin_multi_pack_index_write_options[] = { @@ -164,7 +165,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, read_packs_from_stdin(&packs); - ret = write_midx_file_only(opts.object_dir, &packs, + ret = write_midx_file_only(repo, opts.object_dir, &packs, opts.preferred_pack, opts.refs_snapshot, opts.flags); @@ -175,7 +176,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, } - ret = write_midx_file(opts.object_dir, opts.preferred_pack, + ret = write_midx_file(repo, opts.object_dir, opts.preferred_pack, opts.refs_snapshot, opts.flags); free(opts.refs_snapshot); @@ -183,7 +184,8 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, } static int cmd_multi_pack_index_verify(int argc, const char **argv, - const char *prefix) + const char *prefix, + struct repository *repo UNUSED) { struct option *options; static struct option builtin_multi_pack_index_verify_options[] = { @@ -210,7 +212,8 @@ static int cmd_multi_pack_index_verify(int argc, const char **argv, } static int cmd_multi_pack_index_expire(int argc, const char **argv, - const char *prefix) + const char *prefix, + struct repository *repo UNUSED) { struct option *options; static struct option builtin_multi_pack_index_expire_options[] = { @@ -237,7 +240,8 @@ static int cmd_multi_pack_index_expire(int argc, const char **argv, } static int cmd_multi_pack_index_repack(int argc, const char **argv, - const char *prefix) + const char *prefix, + struct repository *repo UNUSED) { struct option *options; static struct option builtin_multi_pack_index_repack_options[] = { @@ -271,7 +275,7 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv, int cmd_multi_pack_index(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { int res; parse_opt_subcommand_fn *fn = NULL; @@ -297,7 +301,7 @@ int cmd_multi_pack_index(int argc, builtin_multi_pack_index_usage, 0); FREE_AND_NULL(options); - res = fn(argc, argv, prefix); + res = fn(argc, argv, prefix, repo); free(opts.object_dir); return res; diff --git a/builtin/mv.c b/builtin/mv.c index 472a27873767b8..55a7d471dca012 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -3,7 +3,9 @@ * * Copyright (C) 2006 Johannes Schindelin */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" #include "abspath.h" diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 765eb20a9312e4..beac166b5cb414 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "environment.h" #include "gettext.h" diff --git a/builtin/notes.c b/builtin/notes.c index 8c26e4552694ab..ff61ec5f2da953 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -32,9 +32,9 @@ static const char *separator = "\n"; static const char * const git_notes_usage[] = { N_("git notes [--ref <notes-ref>] [list [<object>]]"), - N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"), + N_("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>] [-e]"), N_("git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"), - N_("git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]"), + N_("git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>] [-e]"), N_("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"), N_("git notes [--ref <notes-ref>] show [<object>]"), N_("git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"), @@ -197,7 +197,7 @@ static void prepare_note_data(const struct object_id *object, struct note_data * struct strbuf buf = STRBUF_INIT; /* write the template message before editing: */ - d->edit_path = git_pathdup("NOTES_EDITMSG"); + d->edit_path = repo_git_path(the_repository, "NOTES_EDITMSG"); fd = xopen(d->edit_path, O_CREAT | O_TRUNC | O_WRONLY, 0600); if (d->msg_nr) @@ -431,7 +431,8 @@ static struct notes_tree *init_notes_check(const char *subcommand, return t; } -static int list(int argc, const char **argv, const char *prefix) +static int list(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct notes_tree *t; struct object_id object; @@ -468,9 +469,11 @@ static int list(int argc, const char **argv, const char *prefix) return retval; } -static int append_edit(int argc, const char **argv, const char *prefix); +static int append_edit(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED); -static int add(int argc, const char **argv, const char *prefix) +static int add(int argc, const char **argv, const char *prefix, + struct repository *repo) { int force = 0, allow_empty = 0; const char *object_ref; @@ -489,6 +492,8 @@ static int add(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F('c', "reedit-message", &d, N_("object"), N_("reuse and edit specified note object"), PARSE_OPT_NONEG, parse_reedit_arg), + OPT_BOOL('e', "edit", &d.use_editor, + N_("edit note message in editor")), OPT_CALLBACK_F('C', "reuse-message", &d, N_("object"), N_("reuse specified note object"), PARSE_OPT_NONEG, parse_reuse_arg), @@ -541,7 +546,7 @@ static int add(int argc, const char **argv, const char *prefix) * argv[0-1]. */ argv[0] = "edit"; - return append_edit(argc, argv, prefix); + return append_edit(argc, argv, prefix, repo); } fprintf(stderr, _("Overwriting existing notes for object %s\n"), oid_to_hex(&object)); @@ -567,7 +572,8 @@ static int add(int argc, const char **argv, const char *prefix) return 0; } -static int copy(int argc, const char **argv, const char *prefix) +static int copy(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int retval = 0, force = 0, from_stdin = 0; const struct object_id *from_note, *note; @@ -644,7 +650,8 @@ static int copy(int argc, const char **argv, const char *prefix) return retval; } -static int append_edit(int argc, const char **argv, const char *prefix) +static int append_edit(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int allow_empty = 0; const char *object_ref; @@ -667,6 +674,8 @@ static int append_edit(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F('C', "reuse-message", &d, N_("object"), N_("reuse specified note object"), PARSE_OPT_NONEG, parse_reuse_arg), + OPT_BOOL('e', "edit", &d.use_editor, + N_("edit note message in editor")), OPT_BOOL(0, "allow-empty", &allow_empty, N_("allow storing empty note")), OPT_CALLBACK_F(0, "separator", &separator, @@ -745,7 +754,8 @@ static int append_edit(int argc, const char **argv, const char *prefix) return 0; } -static int show(int argc, const char **argv, const char *prefix) +static int show(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { const char *object_ref; struct notes_tree *t; @@ -871,7 +881,8 @@ static int git_config_get_notes_strategy(const char *key, return 0; } -static int merge(int argc, const char **argv, const char *prefix) +static int merge(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct strbuf remote_ref = STRBUF_INIT, msg = STRBUF_INIT; struct object_id result_oid; @@ -968,6 +979,8 @@ static int merge(int argc, const char **argv, const char *prefix) else { /* Merge has unresolved conflicts */ struct worktree **worktrees; const struct worktree *wt; + char *path; + /* Update .git/NOTES_MERGE_PARTIAL with partial merge result */ refs_update_ref(get_main_ref_store(the_repository), msg.buf, "NOTES_MERGE_PARTIAL", &result_oid, NULL, @@ -983,10 +996,13 @@ static int merge(int argc, const char **argv, const char *prefix) if (refs_update_symref(get_main_ref_store(the_repository), "NOTES_MERGE_REF", notes_ref, NULL)) die(_("failed to store link to current notes ref (%s)"), notes_ref); + + path = repo_git_path(the_repository, NOTES_MERGE_WORKTREE); fprintf(stderr, _("Automatic notes merge failed. Fix conflicts in %s " "and commit the result with 'git notes merge --commit', " "or abort the merge with 'git notes merge --abort'.\n"), - git_path(NOTES_MERGE_WORKTREE)); + path); + free(path); } free_notes(t); @@ -1012,7 +1028,8 @@ static int remove_one_note(struct notes_tree *t, const char *name, unsigned flag return (flag & IGNORE_MISSING) ? 0 : status; } -static int remove_cmd(int argc, const char **argv, const char *prefix) +static int remove_cmd(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { unsigned flag = 0; int from_stdin = 0; @@ -1055,7 +1072,8 @@ static int remove_cmd(int argc, const char **argv, const char *prefix) return retval; } -static int prune(int argc, const char **argv, const char *prefix) +static int prune(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct notes_tree *t; int show_only = 0, verbose = 0; @@ -1084,7 +1102,8 @@ static int prune(int argc, const char **argv, const char *prefix) return 0; } -static int get_ref(int argc, const char **argv, const char *prefix) +static int get_ref(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() }; char *notes_ref; @@ -1105,7 +1124,7 @@ static int get_ref(int argc, const char **argv, const char *prefix) int cmd_notes(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { const char *override_notes_ref = NULL; parse_opt_subcommand_fn *fn = NULL; @@ -1144,5 +1163,5 @@ int cmd_notes(int argc, strbuf_release(&sb); } - return !!fn(argc, argv, prefix); + return !!fn(argc, argv, prefix, repo); } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 0fc0680b40252a..58a9b1612626e0 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "environment.h" #include "gettext.h" @@ -239,6 +241,7 @@ static enum { static uint16_t write_bitmap_options = BITMAP_OPT_HASH_CACHE; static int exclude_promisor_objects; +static int exclude_promisor_objects_best_effort; static int use_delta_islands; @@ -266,6 +269,43 @@ struct configured_exclusion { static struct oidmap configured_exclusions; static struct oidset excluded_by_config; +static int name_hash_version = -1; + +/** + * Check whether the name_hash_version chosen by user input is appropriate, + * and also validate whether it is compatible with other features. + */ +static void validate_name_hash_version(void) +{ + if (name_hash_version < 1 || name_hash_version > 2) + die(_("invalid --name-hash-version option: %d"), name_hash_version); + if (write_bitmap_index && name_hash_version != 1) { + warning(_("currently, --write-bitmap-index requires --name-hash-version=1")); + name_hash_version = 1; + } +} + +static inline uint32_t pack_name_hash_fn(const char *name) +{ + static int seen_version = -1; + + if (seen_version < 0) + seen_version = name_hash_version; + else if (seen_version != name_hash_version) + BUG("name hash version changed from %d to %d mid-process", + seen_version, name_hash_version); + + switch (name_hash_version) { + case 1: + return pack_name_hash(name); + + case 2: + return pack_name_hash_v2((const unsigned char *)name); + + default: + BUG("invalid name-hash version: %d", name_hash_version); + } +} /* * stats @@ -1100,78 +1140,64 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile, 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 = reuse_packfile->bitmap_pos; + size_t pos = 0; 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); + if (reuse_packfile->bitmap_pos) { + /* + * We can't reuse whole chunks verbatim out of + * non-preferred packs since we can't guarantee that + * all duplicate objects were resolved in favor of + * that pack. + * + * Even if we have a whole eword_t worth of bits that + * could be reused, there may be objects between the + * objects corresponding to the first and last bit of + * that word which were selected from a different + * pack, causing us to send duplicate or unwanted + * objects. + * + * Handle non-preferred packs from within + * write_reused_pack(), which inspects and reuses + * individual bits. + */ + return reuse_packfile->bitmap_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(). + * Only read through the last word whose bits all correspond + * to objects in the given packfile, since we must stop at a + * word boundary. * - * 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. + * If there is no whole word to read (i.e. the packfile + * contains fewer than BITS_IN_EWORD objects), then we'll + * inspect bits one-by-one in write_reused_pack(). */ - 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; + end = reuse_packfile->bitmap_nr / BITS_IN_EWORD; + if (reuse_packfile_bitmap->word_alloc < end) + BUG("fewer words than expected in reuse_packfile_bitmap"); - while (pos < end && - reuse_packfile_bitmap->words[pos / BITS_IN_EWORD] == (eword_t)~0) - pos += BITS_IN_EWORD; + while (pos < end && 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 - reuse_packfile->bitmap_pos; + written = (pos * BITS_IN_EWORD); + to_write = pack_pos_to_offset(reuse_packfile->p, written) + - sizeof(struct pack_header); /* We're recording one chunk, not one object. */ - record_reused_object(pack_start_off, - pack_start_off - (hashfile_total(out) - pack_start)); + record_reused_object(sizeof(struct pack_header), 0); hashflush(out); copy_pack_data(out, reuse_packfile->p, w_curs, - pack_start_off, pack_end_off - pack_start_off); + sizeof(struct pack_header), to_write); display_progress(progress_state, written); } - if (pos % BITS_IN_EWORD) - BUG("attempted to jump past a word boundary to %"PRIuMAX, - (uintmax_t)pos); - return pos / BITS_IN_EWORD; + return pos; } static void write_reused_pack(struct bitmapped_pack *reuse_packfile, @@ -1183,8 +1209,7 @@ static void write_reused_pack(struct bitmapped_pack *reuse_packfile, struct pack_window *w_curs = NULL; if (allow_ofs_delta) - i = write_reused_pack_verbatim(reuse_packfile, f, pack_start, - &w_curs); + i = write_reused_pack_verbatim(reuse_packfile, f, &w_curs); for (; i < reuse_packfile_bitmap->word_alloc; ++i) { eword_t word = reuse_packfile_bitmap->words[i]; @@ -1276,7 +1301,8 @@ static void write_pack_file(void) struct object_entry **write_order; if (progress > pack_to_stdout) - progress_state = start_progress(_("Writing objects"), nr_result); + progress_state = start_progress(the_repository, + _("Writing objects"), nr_result); ALLOC_ARRAY(written_list, to_pack.nr_objects); write_order = compute_write_order(); @@ -1330,8 +1356,9 @@ static void write_pack_file(void) */ int fd = finalize_hashfile(f, hash, FSYNC_COMPONENT_PACK, 0); - fixup_pack_header_footer(fd, hash, pack_tmp_name, - nr_written, hash, offset); + fixup_pack_header_footer(the_hash_algo, fd, hash, + pack_tmp_name, nr_written, + hash, offset); close(fd); if (write_bitmap_index) { if (write_bitmap_index != WRITE_BITMAP_QUIET) @@ -1379,9 +1406,10 @@ static void write_pack_file(void) if (cruft) pack_idx_opts.flags |= WRITE_MTIMES; - stage_tmp_packfiles(&tmpname, pack_tmp_name, - written_list, nr_written, - &to_pack, &pack_idx_opts, hash, + stage_tmp_packfiles(the_hash_algo, &tmpname, + pack_tmp_name, written_list, + nr_written, &to_pack, + &pack_idx_opts, hash, &idx_tmp_name); if (write_bitmap_index) { @@ -1529,7 +1557,7 @@ static int want_found_object(const struct object_id *oid, int exclude, return 0; if (ignore_packed_keep_in_core && p->pack_keep_in_core) return 0; - if (has_object_kept_pack(oid, flags)) + if (has_object_kept_pack(p->repo, oid, flags)) return 0; } @@ -1556,7 +1584,7 @@ static int want_object_in_pack_one(struct packed_git *p, if (p == *found_pack) offset = *found_offset; else - offset = find_pack_entry_one(oid->hash, p); + offset = find_pack_entry_one(oid, p); if (offset) { if (!*found_pack) { @@ -1698,7 +1726,7 @@ static int add_object_entry(const struct object_id *oid, enum object_type type, return 0; } - create_object_entry(oid, type, pack_name_hash(name), + create_object_entry(oid, type, pack_name_hash_fn(name), exclude, name && no_try_delta(name), found_pack, found_offset); return 1; @@ -1912,7 +1940,7 @@ static void add_preferred_base_object(const char *name) { struct pbase_tree *it; size_t cmplen; - unsigned hash = pack_name_hash(name); + unsigned hash = pack_name_hash_fn(name); if (!num_preferred_base || check_pbase_path(hash)) return; @@ -2412,7 +2440,8 @@ static void get_object_details(void) struct object_entry **sorted_by_offset; if (progress) - progress_state = start_progress(_("Counting objects"), + progress_state = start_progress(the_repository, + _("Counting objects"), to_pack.nr_objects); CALLOC_ARRAY(sorted_by_offset, to_pack.nr_objects); @@ -3232,7 +3261,8 @@ static void prepare_pack(int window, int depth) unsigned nr_done = 0; if (progress) - progress_state = start_progress(_("Compressing objects"), + progress_state = start_progress(the_repository, + _("Compressing objects"), nr_deltas); QSORT(delta_list, n, type_size_sort); ll_find_deltas(delta_list, n, window+1, depth, &nr_done); @@ -3422,7 +3452,7 @@ static void show_object_pack_hint(struct object *object, const char *name, * here using a now in order to perhaps improve the delta selection * process. */ - oe->hash = pack_name_hash(name); + oe->hash = pack_name_hash_fn(name); oe->no_try_delta = name && no_try_delta(name); stdin_packs_hints_nr++; @@ -3572,7 +3602,7 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type entry = packlist_find(&to_pack, oid); if (entry) { if (name) { - entry->hash = pack_name_hash(name); + entry->hash = pack_name_hash_fn(name); entry->no_try_delta = no_try_delta(name); } } else { @@ -3595,7 +3625,7 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type return; } - entry = create_object_entry(oid, type, pack_name_hash(name), + entry = create_object_entry(oid, type, pack_name_hash_fn(name), 0, name && no_try_delta(name), pack, offset); } @@ -3627,7 +3657,7 @@ static void show_cruft_commit(struct commit *commit, void *data) static int cruft_include_check_obj(struct object *obj, void *data UNUSED) { - return !has_object_kept_pack(&obj->oid, IN_CORE_KEEP_PACKS); + return !has_object_kept_pack(to_pack.repo, &obj->oid, IN_CORE_KEEP_PACKS); } static int cruft_include_check(struct commit *commit, void *data) @@ -3660,7 +3690,8 @@ static void add_objects_in_unpacked_packs(void); static void enumerate_cruft_objects(void) { if (progress) - progress_state = start_progress(_("Enumerating cruft objects"), 0); + progress_state = start_progress(the_repository, + _("Enumerating cruft objects"), 0); add_objects_in_unpacked_packs(); add_unreachable_loose_objects(); @@ -3686,7 +3717,8 @@ static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs revs.ignore_missing_links = 1; if (progress) - progress_state = start_progress(_("Enumerating cruft objects"), 0); + progress_state = start_progress(the_repository, + _("Enumerating cruft objects"), 0); ret = add_unseen_recent_objects_to_traversal(&revs, cruft_expiration, set_cruft_mtime, 1); stop_progress(&progress_state); @@ -3705,7 +3737,8 @@ static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs if (prepare_revision_walk(&revs)) die(_("revision walk setup failed")); if (progress) - progress_state = start_progress(_("Traversing cruft objects"), 0); + progress_state = start_progress(the_repository, + _("Traversing cruft objects"), 0); nr_seen = 0; traverse_commit_list(&revs, show_cruft_commit, show_cruft_object, NULL); @@ -3858,7 +3891,8 @@ static void show_object__ma_allow_promisor(struct object *obj, const char *name, * Quietly ignore EXPECTED missing objects. This avoids problems with * staging them now and getting an odd error later. */ - if (!has_object(the_repository, &obj->oid, 0) && is_promisor_object(&obj->oid)) + if (!has_object(the_repository, &obj->oid, 0) && + is_promisor_object(to_pack.repo, &obj->oid)) return; show_object(obj, name, data); @@ -3927,7 +3961,9 @@ static int add_object_in_unpacked_pack(const struct object_id *oid, static void add_objects_in_unpacked_packs(void) { - if (for_each_packed_object(add_object_in_unpacked_pack, NULL, + if (for_each_packed_object(to_pack.repo, + add_object_in_unpacked_pack, + NULL, FOR_EACH_OBJECT_PACK_ORDER | FOR_EACH_OBJECT_LOCAL_ONLY | FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS | @@ -3984,7 +4020,7 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid) while (p) { if ((!p->pack_local || p->pack_keep || p->pack_keep_in_core) && - find_pack_entry_one(oid->hash, p)) { + find_pack_entry_one(oid, p)) { last_found = p; return 1; } @@ -4069,6 +4105,15 @@ static int get_object_list_from_bitmap(struct rev_info *revs) if (!(bitmap_git = prepare_bitmap_walk(revs, 0))) return -1; + /* + * For now, force the name-hash version to be 1 since that + * is the version implied by the bitmap format. Later, the + * format can include this version explicitly in its format, + * allowing readers to know the version that was used during + * the bitmap write. + */ + name_hash_version = 1; + if (pack_options_allow_reuse()) reuse_partial_packfile_from_bitmap(bitmap_git, &reuse_packfiles, @@ -4312,6 +4357,18 @@ static int option_parse_cruft_expiration(const struct option *opt UNUSED, return 0; } +static int is_not_in_promisor_pack_obj(struct object *obj, void *data UNUSED) +{ + struct object_info info = OBJECT_INFO_INIT; + if (oid_object_info_extended(the_repository, &obj->oid, &info, 0)) + BUG("should_include_obj should only be called on existing objects"); + return info.whence != OI_PACKED || !info.u.packed.pack->pack_promisor; +} + +static int is_not_in_promisor_pack(struct commit *commit, void *data) { + return is_not_in_promisor_pack_obj((struct object *) commit, data); +} + int cmd_pack_objects(int argc, const char **argv, const char *prefix, @@ -4424,11 +4481,16 @@ int cmd_pack_objects(int argc, option_parse_missing_action), OPT_BOOL(0, "exclude-promisor-objects", &exclude_promisor_objects, N_("do not pack objects in promisor packfiles")), + OPT_BOOL(0, "exclude-promisor-objects-best-effort", + &exclude_promisor_objects_best_effort, + N_("implies --missing=allow-any")), OPT_BOOL(0, "delta-islands", &use_delta_islands, N_("respect islands during delta compression")), OPT_STRING_LIST(0, "uri-protocol", &uri_protocols, N_("protocol"), N_("exclude any configured uploadpack.blobpackfileuri with this protocol")), + OPT_INTEGER(0, "name-hash-version", &name_hash_version, + N_("use the specified name-hash function to group similar objects")), OPT_END(), }; @@ -4504,10 +4566,18 @@ int cmd_pack_objects(int argc, strvec_push(&rp, "--unpacked"); } + if (exclude_promisor_objects && exclude_promisor_objects_best_effort) + die(_("options '%s' and '%s' cannot be used together"), + "--exclude-promisor-objects", "--exclude-promisor-objects-best-effort"); if (exclude_promisor_objects) { use_internal_rev_list = 1; fetch_if_missing = 0; strvec_push(&rp, "--exclude-promisor-objects"); + } else if (exclude_promisor_objects_best_effort) { + use_internal_rev_list = 1; + fetch_if_missing = 0; + option_parse_missing_action(NULL, "allow-any", 0); + /* revs configured below */ } if (unpack_unreachable || keep_unreachable || pack_loose_unreachable) use_internal_rev_list = 1; @@ -4576,6 +4646,11 @@ int cmd_pack_objects(int argc, if (pack_to_stdout || !rev_list_all) write_bitmap_index = 0; + if (name_hash_version < 0) + name_hash_version = (int)git_env_ulong("GIT_TEST_NAME_HASH_VERSION", 1); + + validate_name_hash_version(); + if (use_delta_islands) strvec_push(&rp, "--topo-order"); @@ -4611,7 +4686,8 @@ int cmd_pack_objects(int argc, prepare_packing_data(the_repository, &to_pack); if (progress && !cruft) - progress_state = start_progress(_("Enumerating objects"), 0); + progress_state = start_progress(the_repository, + _("Enumerating objects"), 0); if (stdin_packs) { /* avoids adding objects in excluded packs */ ignore_packed_keep_in_core = 1; @@ -4627,6 +4703,10 @@ int cmd_pack_objects(int argc, repo_init_revisions(the_repository, &revs, NULL); list_objects_filter_copy(&revs.filter, &filter_options); + if (exclude_promisor_objects_best_effort) { + revs.include_check = is_not_in_promisor_pack; + revs.include_check_obj = is_not_in_promisor_pack_obj; + } get_object_list(&revs, rp.nr, rp.v); release_revisions(&revs); } diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 81f4494d466ade..3febe732f8e1c7 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -5,6 +5,7 @@ * This file is licensed under the GPL v2. * */ + #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" @@ -13,6 +14,7 @@ #include "packfile.h" #include "object-store-ll.h" +#include "strbuf.h" #define BLKSIZE 512 @@ -69,6 +71,15 @@ static inline void llist_init(struct llist **list) (*list)->size = 0; } +static void llist_free(struct llist *list) +{ + for (struct llist_item *i = list->front, *next; i; i = next) { + next = i->next; + llist_item_put(i); + } + free(list); +} + static struct llist * llist_copy(struct llist *list) { struct llist *ret; @@ -206,6 +217,14 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl, return p; } +static void pack_list_free(struct pack_list *pl) +{ + for (struct pack_list *next; pl; pl = next) { + next = pl->next; + free(pl); + } +} + static inline size_t pack_list_size(struct pack_list *pl) { size_t ret = 0; @@ -371,7 +390,6 @@ static int cmp_remaining_objects(const void *a, const void *b) static void sort_pack_list(struct pack_list **pl) { struct pack_list **ary, *p; - int i; size_t n = pack_list_size(*pl); if (n < 2) @@ -385,7 +403,7 @@ static void sort_pack_list(struct pack_list **pl) QSORT(ary, n, cmp_remaining_objects); /* link them back again */ - for (i = 0; i < n - 1; i++) + for (size_t i = 0; i < n - 1; i++) ary[i]->next = ary[i + 1]; ary[n - 1]->next = NULL; *pl = ary[0]; @@ -419,7 +437,8 @@ static void minimize(struct pack_list **min) /* return if there are no objects missing from the unique set */ if (missing->size == 0) { - free(missing); + llist_free(missing); + pack_list_free(non_unique); return; } @@ -434,6 +453,8 @@ static void minimize(struct pack_list **min) } while (non_unique) { + struct pack_list *next; + /* sort the non_unique packs, greater size of remaining_objects first */ sort_pack_list(&non_unique); if (non_unique->remaining_objects->size == 0) @@ -444,8 +465,14 @@ static void minimize(struct pack_list **min) for (pl = non_unique->next; pl && pl->remaining_objects->size > 0; pl = pl->next) llist_sorted_difference_inplace(pl->remaining_objects, non_unique->remaining_objects); - non_unique = non_unique->next; + next = non_unique->next; + free(non_unique); + non_unique = next; } + + pack_list_free(non_unique); + llist_free(unique_pack_objects); + llist_free(missing); } static void load_all_objects(void) @@ -565,11 +592,10 @@ static void load_all(void) int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) { int i; int i_still_use_this = 0; struct pack_list *min = NULL, *red, *pl; struct llist *ignore; - struct object_id *oid; + struct strbuf idx_name = STRBUF_INIT; char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */ - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(pack_redundant_usage); + show_usage_if_asked(argc, argv, pack_redundant_usage); for (i = 1; i < argc; i++) { const char *arg = argv[i]; @@ -625,11 +651,11 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s /* ignore objects given on stdin */ llist_init(&ignore); if (!isatty(0)) { + struct object_id oid; while (fgets(buf, sizeof(buf), stdin)) { - oid = xmalloc(sizeof(*oid)); - if (get_oid_hex(buf, oid)) + if (get_oid_hex(buf, &oid)) die("Bad object ID on stdin: %s", buf); - llist_insert_sorted_unique(ignore, oid, NULL); + llist_insert_sorted_unique(ignore, &oid, NULL); } } llist_sorted_difference_inplace(all_objects, ignore); @@ -663,7 +689,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s pl = red = pack_list_difference(local_packs, min); while (pl) { printf("%s\n%s\n", - sha1_pack_index_name(pl->pack->hash), + odb_pack_name(pl->pack->repo, &idx_name, pl->pack->hash, "idx"), pl->pack->pack_name); pl = pl->next; } @@ -671,5 +697,9 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s fprintf(stderr, "%luMB of redundant packs in total.\n", (unsigned long)pack_set_bytecount(red)/(1024*1024)); + pack_list_free(red); + pack_list_free(min); + llist_free(ignore); + strbuf_release(&idx_name); return 0; } diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index 2d83c1ed2ac8c7..4fdd68880e0c6d 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "gettext.h" diff --git a/builtin/patch-id.c b/builtin/patch-id.c index 93b398e391e00c..cdef2ec10abcd5 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "diff.h" @@ -8,13 +9,13 @@ #include "parse-options.h" #include "setup.h" -static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result) +static void flush_current_id(size_t patchlen, struct object_id *id, struct object_id *result) { if (patchlen) printf("%s %s\n", oid_to_hex(result), oid_to_hex(id)); } -static int remove_space(char *line) +static size_t remove_space(char *line) { char *src = line; char *dst = line; @@ -61,14 +62,15 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after) return 1; } -static int get_one_patchid(struct object_id *next_oid, struct object_id *result, - struct strbuf *line_buf, int stable, int verbatim) +static size_t get_one_patchid(struct object_id *next_oid, struct object_id *result, + struct strbuf *line_buf, int stable, int verbatim) { - int patchlen = 0, found_next = 0; + size_t patchlen = 0; + int found_next = 0; int before = -1, after = -1; int diff_is_binary = 0; char pre_oid_str[GIT_MAX_HEXSZ + 1], post_oid_str[GIT_MAX_HEXSZ + 1]; - git_hash_ctx ctx; + struct git_hash_ctx ctx; the_hash_algo->init_fn(&ctx); oidclr(result, the_repository->hash_algo); @@ -76,14 +78,14 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, while (strbuf_getwholeline(line_buf, stdin, '\n') != EOF) { char *line = line_buf->buf; const char *p = line; - int len; + size_t len; /* Possibly skip over the prefix added by "log" or "format-patch" */ if (!skip_prefix(line, "commit ", &p) && !skip_prefix(line, "From ", &p) && starts_with(line, "\\ ") && 12 < strlen(line)) { if (verbatim) - the_hash_algo->update_fn(&ctx, line, strlen(line)); + git_hash_update(&ctx, line, strlen(line)); continue; } @@ -102,10 +104,10 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, starts_with(line, "Binary files")) { diff_is_binary = 1; before = 0; - the_hash_algo->update_fn(&ctx, pre_oid_str, - strlen(pre_oid_str)); - the_hash_algo->update_fn(&ctx, post_oid_str, - strlen(post_oid_str)); + git_hash_update(&ctx, pre_oid_str, + strlen(pre_oid_str)); + git_hash_update(&ctx, post_oid_str, + strlen(post_oid_str)); if (stable) flush_one_hunk(result, &ctx); continue; @@ -163,7 +165,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, /* Add line to hash algo (possibly removing whitespace) */ len = verbatim ? strlen(line) : remove_space(line); patchlen += len; - the_hash_algo->update_fn(&ctx, line, len); + git_hash_update(&ctx, line, len); } if (!found_next) @@ -177,7 +179,7 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, static void generate_id_list(int stable, int verbatim) { struct object_id oid, n, result; - int patchlen; + size_t patchlen; struct strbuf line_buf = STRBUF_INIT; oidclr(&oid, the_repository->hash_algo); diff --git a/builtin/prune.c b/builtin/prune.c index 2b1de01339fc04..1c357fffd8cde6 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "commit.h" #include "diff.h" @@ -62,7 +64,8 @@ static void perform_reachability_traversal(struct rev_info *revs) return; if (show_progress) - progress = start_delayed_progress(_("Checking connectivity"), 0); + progress = start_delayed_progress(the_repository, + _("Checking connectivity"), 0); mark_reachable_objects(revs, 1, expire, progress); stop_progress(&progress); initialized = 1; diff --git a/builtin/pull.c b/builtin/pull.c index 149f201320549f..9c4a00620a053b 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -7,6 +7,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "advice.h" #include "config.h" @@ -85,7 +86,7 @@ static const char *opt_squash; static const char *opt_commit; static const char *opt_edit; static const char *cleanup_arg; -static const char *opt_ff; +static char *opt_ff; static const char *opt_verify_signatures; static const char *opt_verify; static int opt_autostash = -1; @@ -218,8 +219,8 @@ static struct option pull_options[] = { OPT_PASSTHRU_ARGV(0, "shallow-since", &opt_fetch, N_("time"), N_("deepen history of shallow repository based on time"), 0), - OPT_PASSTHRU_ARGV(0, "shallow-exclude", &opt_fetch, N_("revision"), - N_("deepen history of shallow clone, excluding rev"), + OPT_PASSTHRU_ARGV(0, "shallow-exclude", &opt_fetch, N_("ref"), + N_("deepen history of shallow clone, excluding ref"), 0), OPT_PASSTHRU_ARGV(0, "deepen", &opt_fetch, N_("n"), N_("deepen history of shallow clone"), @@ -941,11 +942,10 @@ static int get_can_ff(struct object_id *orig_head, static int already_up_to_date(struct object_id *orig_head, struct oid_array *merge_heads) { - int i; struct commit *ours; ours = lookup_commit_reference(the_repository, orig_head); - for (i = 0; i < merge_heads->nr; i++) { + for (size_t i = 0; i < merge_heads->nr; i++) { struct commit_list *list = NULL; struct commit *theirs; int ok; @@ -1028,8 +1028,10 @@ int cmd_pull(int argc, * "--rebase" can override a config setting of * pull.ff=only. */ - if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only")) - opt_ff = "--ff"; + if (opt_rebase >= 0 && opt_ff && !strcmp(opt_ff, "--ff-only")) { + free(opt_ff); + opt_ff = xstrdup("--ff"); + } } if (opt_rebase < 0) @@ -1139,7 +1141,8 @@ int cmd_pull(int argc, if (can_ff) { /* we can fast-forward this without invoking rebase */ - opt_ff = "--ff-only"; + free(opt_ff); + opt_ff = xstrdup("--ff-only"); ret = run_merge(); } else { ret = run_rebase(&newbase, &upstream); diff --git a/builtin/push.c b/builtin/push.c index e6f48969b81a06..92d530e5c4dff0 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -1,7 +1,9 @@ /* * "git push" */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "advice.h" #include "branch.h" @@ -76,7 +78,7 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref, .src = matched->name, }; - if (!query_refspecs(&remote->push, &query) && query.dst) { + if (!refspec_find_match(&remote->push, &query) && query.dst) { refspec_appendf(refspec, "%s%s:%s", query.force ? "+" : "", query.src, query.dst); @@ -417,7 +419,7 @@ static int do_push(int flags, const struct string_list *push_options, struct remote *remote) { - int i, errs; + int errs; struct strvec *url; struct refspec *push_refspec = &rs; @@ -432,7 +434,7 @@ static int do_push(int flags, } errs = 0; url = push_url_of_remote(remote); - for (i = 0; i < url->nr; i++) { + for (size_t i = 0; i < url->nr; i++) { struct transport *transport = transport_get(remote, url->v[i]); if (flags & TRANSPORT_PUSH_OPTIONS) @@ -519,14 +521,7 @@ static int git_push_config(const char *k, const char *v, RECURSE_SUBMODULES_ON_DEMAND : RECURSE_SUBMODULES_OFF; recurse_submodules = val; } else if (!strcmp(k, "push.pushoption")) { - if (!v) - return config_error_nonbool(k); - else - if (!*v) - string_list_clear(&push_options_config, 0); - else - string_list_append(&push_options_config, v); - return 0; + return parse_transport_option(k, v, &push_options_config); } else if (!strcmp(k, "color.push")) { push_use_color = git_config_colorbool(k, v); return 0; @@ -669,6 +664,7 @@ int cmd_push(int argc, rc = do_push(flags, push_options, remote); string_list_clear(&push_options_cmdline, 0); string_list_clear(&push_options_config, 0); + clear_cas_option(&cas); if (rc == -1) usage_with_options(push_usage, options); else diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 1b33ab66a7b201..32ddb6613fb443 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "gettext.h" #include "object-name.h" @@ -21,6 +22,7 @@ int cmd_range_diff(int argc, { struct diff_options diffopt = { NULL }; struct strvec other_arg = STRVEC_INIT; + struct strvec diff_merges_arg = STRVEC_INIT; struct range_diff_options range_diff_opts = { .creation_factor = RANGE_DIFF_CREATION_FACTOR_DEFAULT, .diffopt = &diffopt, @@ -36,6 +38,10 @@ int cmd_range_diff(int argc, OPT_PASSTHRU_ARGV(0, "notes", &other_arg, N_("notes"), N_("passed to 'git log'"), PARSE_OPT_OPTARG), + OPT_PASSTHRU_ARGV(0, "diff-merges", &diff_merges_arg, + N_("style"), N_("passed to 'git log'"), 0), + OPT_PASSTHRU_ARGV(0, "remerge-diff", &diff_merges_arg, NULL, + N_("passed to 'git log'"), PARSE_OPT_NOARG), OPT_BOOL(0, "left-only", &left_only, N_("only emit output related to the first range")), OPT_BOOL(0, "right-only", &right_only, @@ -62,6 +68,12 @@ int cmd_range_diff(int argc, if (!simple_color) diffopt.use_color = 1; + /* If `--diff-merges` was specified, imply `--merges` */ + if (diff_merges_arg.nr) { + range_diff_opts.include_merges = 1; + strvec_pushv(&other_arg, diff_merges_arg.v); + } + for (i = 0; i < argc; i++) if (!strcmp(argv[i], "--")) { dash_dash = i; @@ -155,6 +167,7 @@ int cmd_range_diff(int argc, res = show_range_diff(range1.buf, range2.buf, &range_diff_opts); strvec_clear(&other_arg); + strvec_clear(&diff_merges_arg); strbuf_release(&range1); strbuf_release(&range2); diff --git a/builtin/rebase.c b/builtin/rebase.c index bbaca3c5d57835..d4715ed35d77ed 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -3,7 +3,10 @@ * * Copyright (c) 2018 Pratik Karki */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" @@ -641,7 +644,7 @@ static int run_am(struct rebase_options *opts) return run_command(&am); } - rebased_patches = xstrdup(git_path("rebased-patches")); + rebased_patches = repo_git_path(the_repository, "rebased-patches"); format_patch.out = open(rebased_patches, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (format_patch.out < 0) { @@ -1220,9 +1223,9 @@ int cmd_rebase(int argc, }; int i; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(builtin_rebase_usage, - builtin_rebase_options); + show_usage_with_options_if_asked(argc, argv, + builtin_rebase_usage, + builtin_rebase_options); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 536d22761d6d9e..7b28fc9df6ec0b 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" @@ -172,7 +174,7 @@ static int receive_pack_config(const char *var, const char *value, char *path; if (git_config_pathname(&path, var, value)) - return 1; + return -1; strbuf_addf(&fsck_msg_types, "%cskiplist=%s", fsck_msg_types.len ? ',' : '=', path); free(path); @@ -374,6 +376,7 @@ static void write_head_info(void) struct command { struct command *next; const char *error_string; + char *error_string_owned; struct ref_push_report *report; unsigned int skip_update:1, did_not_exist:1, @@ -563,14 +566,14 @@ static void hmac_hash(unsigned char *out, unsigned char k_ipad[GIT_MAX_BLKSZ]; unsigned char k_opad[GIT_MAX_BLKSZ]; int i; - git_hash_ctx ctx; + struct git_hash_ctx ctx; /* RFC 2104 2. (1) */ memset(key, '\0', GIT_MAX_BLKSZ); if (the_hash_algo->blksz < key_len) { the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, key_in, key_len); - the_hash_algo->final_fn(key, &ctx); + git_hash_update(&ctx, key_in, key_len); + git_hash_final(key, &ctx); } else { memcpy(key, key_in, key_len); } @@ -583,15 +586,15 @@ static void hmac_hash(unsigned char *out, /* RFC 2104 2. (3) & (4) */ the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, k_ipad, sizeof(k_ipad)); - the_hash_algo->update_fn(&ctx, text, text_len); - the_hash_algo->final_fn(out, &ctx); + git_hash_update(&ctx, k_ipad, sizeof(k_ipad)); + git_hash_update(&ctx, text, text_len); + git_hash_final(out, &ctx); /* RFC 2104 2. (6) & (7) */ the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, k_opad, sizeof(k_opad)); - the_hash_algo->update_fn(&ctx, out, the_hash_algo->rawsz); - the_hash_algo->final_fn(out, &ctx); + git_hash_update(&ctx, k_opad, sizeof(k_opad)); + git_hash_update(&ctx, out, the_hash_algo->rawsz); + git_hash_final(out, &ctx); } static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp) @@ -1083,7 +1086,7 @@ static int read_proc_receive_report(struct packet_reader *reader, hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED; if (!strcmp(head, "ng")) { if (p) - hint->error_string = xstrdup(p); + hint->error_string = hint->error_string_owned = xstrdup(p); else hint->error_string = "failed"; code = -1; @@ -1432,7 +1435,8 @@ static const char *push_to_checkout(unsigned char *hash, static const char *update_worktree(unsigned char *sha1, const struct worktree *worktree) { - const char *retval, *git_dir; + const char *retval; + char *git_dir; struct strvec env = STRVEC_INIT; int invoked_hook; @@ -1450,6 +1454,7 @@ static const char *update_worktree(unsigned char *sha1, const struct worktree *w retval = push_to_deploy(sha1, &env, worktree->path); strvec_clear(&env); + free(git_dir); return retval; } @@ -1848,7 +1853,7 @@ static void execute_commands_non_atomic(struct command *commands, continue; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) { rp_error("%s", err.buf); strbuf_reset(&err); @@ -1877,7 +1882,7 @@ static void execute_commands_atomic(struct command *commands, const char *reported_error = "atomic push failure"; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) { rp_error("%s", err.buf); strbuf_reset(&err); @@ -2054,6 +2059,8 @@ static void free_commands(struct command *commands) while (commands) { struct command *next = commands->next; + ref_push_report_free(commands->report); + free(commands->error_string_owned); free(commands); commands = next; } @@ -2234,7 +2241,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) strvec_push(&child.args, alt_shallow_file); } - tmp_objdir = tmp_objdir_create("incoming"); + tmp_objdir = tmp_objdir_create(the_repository, "incoming"); if (!tmp_objdir) { if (err_fd > 0) close(err_fd); @@ -2299,7 +2306,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) if (status) return "index-pack fork failed"; - lockfile = index_pack_lockfile(child.out, NULL); + lockfile = index_pack_lockfile(the_repository, child.out, NULL); if (lockfile) { pack_lockfile = register_tempfile(lockfile); free(lockfile); @@ -2623,7 +2630,7 @@ int cmd_receive_pack(int argc, } } if (auto_update_server_info) - update_server_info(0); + update_server_info(the_repository, 0); clear_shallow_info(&si); } if (use_sideband) diff --git a/builtin/reflog.c b/builtin/reflog.c index 22df6834f71098..95f264989bbf1a 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "gettext.h" @@ -234,7 +235,8 @@ static int expire_total_callback(const struct option *opt, return 0; } -static int cmd_reflog_show(int argc, const char **argv, const char *prefix) +static int cmd_reflog_show(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() @@ -253,7 +255,8 @@ static int show_reflog(const char *refname, void *cb_data UNUSED) return 0; } -static int cmd_reflog_list(int argc, const char **argv, const char *prefix) +static int cmd_reflog_list(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() @@ -270,7 +273,8 @@ static int cmd_reflog_list(int argc, const char **argv, const char *prefix) return refs_for_each_reflog(ref_store, show_reflog, NULL); } -static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) +static int cmd_reflog_expire(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct cmd_reflog_expire_cb cmd = { 0 }; timestamp_t now = time(NULL); @@ -394,7 +398,8 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) return status; } -static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) +static int cmd_reflog_delete(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i, status = 0; unsigned int flags = 0; @@ -424,7 +429,8 @@ static int cmd_reflog_delete(int argc, const char **argv, const char *prefix) return status; } -static int cmd_reflog_exists(int argc, const char **argv, const char *prefix) +static int cmd_reflog_exists(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() @@ -467,7 +473,7 @@ int cmd_reflog(int argc, PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); if (fn) - return fn(argc - 1, argv + 1, prefix); + return fn(argc - 1, argv + 1, prefix, repository); else return cmd_log_reflog(argc, argv, prefix, repository); } diff --git a/builtin/refs.c b/builtin/refs.c index 24978a7b7b081a..44d592a94cf381 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -5,14 +5,16 @@ #include "parse-options.h" #include "refs.h" #include "strbuf.h" +#include "worktree.h" #define REFS_MIGRATE_USAGE \ - N_("git refs migrate --ref-format=<format> [--dry-run]") + N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]") #define REFS_VERIFY_USAGE \ N_("git refs verify [--strict] [--verbose]") -static int cmd_refs_migrate(int argc, const char **argv, const char *prefix) +static int cmd_refs_migrate(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { const char * const migrate_usage[] = { REFS_MIGRATE_USAGE, @@ -28,6 +30,9 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix) OPT_BIT(0, "dry-run", &flags, N_("perform a non-destructive dry-run"), REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN), + OPT_BIT(0, "no-reflog", &flags, + N_("drop reflogs entirely during the migration"), + REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG), OPT_END(), }; struct strbuf errbuf = STRBUF_INIT; @@ -63,9 +68,11 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix) return err; } -static int cmd_refs_verify(int argc, const char **argv, const char *prefix) +static int cmd_refs_verify(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct fsck_options fsck_refs_options = FSCK_REFS_OPTIONS_DEFAULT; + struct worktree **worktrees; const char * const verify_usage[] = { REFS_VERIFY_USAGE, NULL, @@ -75,7 +82,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "strict", &fsck_refs_options.strict, N_("enable strict checking")), OPT_END(), }; - int ret; + int ret = 0; argc = parse_options(argc, argv, prefix, options, verify_usage, 0); if (argc) @@ -84,16 +91,20 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix) git_config(git_fsck_config, &fsck_refs_options); prepare_repo_settings(the_repository); - ret = refs_fsck(get_main_ref_store(the_repository), &fsck_refs_options); + worktrees = get_worktrees(); + for (size_t i = 0; worktrees[i]; i++) + ret |= refs_fsck(get_worktree_ref_store(worktrees[i]), + &fsck_refs_options, worktrees[i]); fsck_options_clear(&fsck_refs_options); + free_worktrees(worktrees); return ret; } int cmd_refs(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { const char * const refs_usage[] = { REFS_MIGRATE_USAGE, @@ -108,5 +119,5 @@ int cmd_refs(int argc, }; argc = parse_options(argc, argv, prefix, opts, refs_usage, 0); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index 33c8ae0fc7d638..bd2037f27da0c4 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -202,6 +202,8 @@ int cmd_remote_ext(int argc, { BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, usage_msg); + if (argc != 3) usage(usage_msg); diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c index ae896eda57b86d..39908546ba0128 100644 --- a/builtin/remote-fd.c +++ b/builtin/remote-fd.c @@ -64,6 +64,7 @@ int cmd_remote_fd(int argc, BUG_ON_NON_EMPTY_PREFIX(prefix); + show_usage_if_asked(argc, argv, usage_msg); if (argc != 3) usage(usage_msg); diff --git a/builtin/remote.c b/builtin/remote.c index 76670ddd8b44e5..1b7aad88380735 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "gettext.h" @@ -155,7 +157,8 @@ static int parse_mirror_opt(const struct option *opt, const char *arg, int not) return 0; } -static int add(int argc, const char **argv, const char *prefix) +static int add(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int fetch = 0, fetch_tags = TAGS_DEFAULT; unsigned mirror = MIRROR_NONE; @@ -377,10 +380,10 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat for (i = 0; i < states->remote->fetch.nr; i++) if (get_fetch_map(remote_refs, &states->remote->fetch.items[i], &tail, 1)) die(_("Could not get fetch map for refspec %s"), - states->remote->fetch.raw[i]); + states->remote->fetch.items[i].raw); for (ref = fetch_map; ref; ref = ref->next) { - if (omit_name_by_refspec(ref->name, &states->remote->fetch)) + if (refname_matches_negative_refspec_item(ref->name, &states->remote->fetch)) string_list_append(&states->skipped, abbrev_branch(ref->name)); else if (!ref->peer_ref || !refs_ref_exists(get_main_ref_store(the_repository), ref->peer_ref->name)) string_list_append(&states->new_refs, abbrev_branch(ref->name)); @@ -633,16 +636,20 @@ static int migrate_file(struct remote *remote) git_config_set_multivar(buf.buf, remote->url.v[i], "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.push", remote->name); - for (i = 0; i < remote->push.raw_nr; i++) - git_config_set_multivar(buf.buf, remote->push.raw[i], "^$", 0); + for (i = 0; i < remote->push.nr; i++) + git_config_set_multivar(buf.buf, remote->push.items[i].raw, "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", remote->name); - for (i = 0; i < remote->fetch.raw_nr; i++) - git_config_set_multivar(buf.buf, remote->fetch.raw[i], "^$", 0); + for (i = 0; i < remote->fetch.nr; i++) + git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0); +#ifndef WITH_BREAKING_CHANGES if (remote->origin == REMOTE_REMOTES) - unlink_or_warn(git_path("remotes/%s", remote->name)); + unlink_or_warn(repo_git_path_replace(the_repository, &buf, + "remotes/%s", remote->name)); else if (remote->origin == REMOTE_BRANCHES) - unlink_or_warn(git_path("branches/%s", remote->name)); + unlink_or_warn(repo_git_path_replace(the_repository, &buf, + "branches/%s", remote->name)); +#endif /* WITH_BREAKING_CHANGES */ strbuf_release(&buf); return 0; @@ -706,7 +713,8 @@ static void handle_push_default(const char* old_name, const char* new_name) } -static int mv(int argc, const char **argv, const char *prefix) +static int mv(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int show_progress = isatty(2); struct option options[] = { @@ -759,16 +767,16 @@ static int mv(int argc, const char **argv, const char *prefix) goto out; } - if (oldremote->fetch.raw_nr) { + if (oldremote->fetch.nr) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", rename.new_name); git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name); - for (i = 0; i < oldremote->fetch.raw_nr; i++) { + for (i = 0; i < oldremote->fetch.nr; i++) { char *ptr; strbuf_reset(&buf2); - strbuf_addstr(&buf2, oldremote->fetch.raw[i]); + strbuf_addstr(&buf2, oldremote->fetch.items[i].raw); ptr = strstr(buf2.buf, old_remote_context.buf); if (ptr) { refspec_updated = 1; @@ -816,7 +824,8 @@ static int mv(int argc, const char **argv, const char *prefix) * Count symrefs twice, since "renaming" them is done by * deleting and recreating them in two separate passes. */ - progress = start_progress(_("Renaming remote references"), + progress = start_progress(the_repository, + _("Renaming remote references"), rename.remote_branches->nr + rename.symrefs_nr); } for (i = 0; i < remote_branches.nr; i++) { @@ -881,7 +890,8 @@ static int mv(int argc, const char **argv, const char *prefix) return result; } -static int rm(int argc, const char **argv, const char *prefix) +static int rm(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() @@ -1303,7 +1313,8 @@ static int show_all(void) return result; } -static int show(int argc, const char **argv, const char *prefix) +static int show(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int no_query = 0, result = 0, query_flag = 0; struct option options[] = { @@ -1399,11 +1410,42 @@ static int show(int argc, const char **argv, const char *prefix) return result; } -static int set_head(int argc, const char **argv, const char *prefix) +static void report_set_head_auto(const char *remote, const char *head_name, + struct strbuf *b_local_head, int was_detached) { + struct strbuf buf_prefix = STRBUF_INIT; + const char *prev_head = NULL; + + strbuf_addf(&buf_prefix, "refs/remotes/%s/", remote); + skip_prefix(b_local_head->buf, buf_prefix.buf, &prev_head); + + if (prev_head && !strcmp(prev_head, head_name)) + printf(_("'%s/HEAD' is unchanged and points to '%s'\n"), + remote, head_name); + else if (prev_head) + printf(_("'%s/HEAD' has changed from '%s' and now points to '%s'\n"), + remote, prev_head, head_name); + else if (!b_local_head->len) + printf(_("'%s/HEAD' is now created and points to '%s'\n"), + remote, head_name); + else if (was_detached && b_local_head->len) + printf(_("'%s/HEAD' was detached at '%s' and now points to '%s'\n"), + remote, b_local_head->buf, head_name); + else + printf(_("'%s/HEAD' used to point to '%s' " + "(which is not a remote branch), but now points to '%s'\n"), + remote, b_local_head->buf, head_name); + strbuf_release(&buf_prefix); +} + +static int set_head(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { - int i, opt_a = 0, opt_d = 0, result = 0; - struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT; + int i, opt_a = 0, opt_d = 0, result = 0, was_detached; + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, + b_local_head = STRBUF_INIT; char *head_name = NULL; + struct ref_store *refs = get_main_ref_store(the_repository); + struct remote *remote; struct option options[] = { OPT_BOOL('a', "auto", &opt_a, @@ -1414,8 +1456,10 @@ static int set_head(int argc, const char **argv, const char *prefix) }; argc = parse_options(argc, argv, prefix, options, builtin_remote_sethead_usage, 0); - if (argc) - strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]); + if (argc) { + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]); + remote = remote_get(argv[0]); + } if (!opt_a && !opt_d && argc == 2) { head_name = xstrdup(argv[1]); @@ -1434,25 +1478,39 @@ static int set_head(int argc, const char **argv, const char *prefix) head_name = xstrdup(states.heads.items[0].string); free_remote_ref_states(&states); } else if (opt_d && !opt_a && argc == 1) { - if (refs_delete_ref(get_main_ref_store(the_repository), NULL, buf.buf, NULL, REF_NO_DEREF)) - result |= error(_("Could not delete %s"), buf.buf); + if (refs_delete_ref(refs, NULL, b_head.buf, NULL, REF_NO_DEREF)) + result |= error(_("Could not delete %s"), b_head.buf); } else usage_with_options(builtin_remote_sethead_usage, options); - if (head_name) { - strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name); - /* make sure it's valid */ - if (!refs_ref_exists(get_main_ref_store(the_repository), buf2.buf)) - result |= error(_("Not a valid ref: %s"), buf2.buf); - else if (refs_update_symref(get_main_ref_store(the_repository), buf.buf, buf2.buf, "remote set-head")) - result |= error(_("Could not setup %s"), buf.buf); - else if (opt_a) - printf("%s/HEAD set to %s\n", argv[0], head_name); - free(head_name); + if (!head_name) + goto cleanup; + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", argv[0], head_name); + if (!refs_ref_exists(refs, b_remote_head.buf)) { + result |= error(_("Not a valid ref: %s"), b_remote_head.buf); + goto cleanup; + } + was_detached = refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf, + "remote set-head", &b_local_head, 0); + if (was_detached == -1) { + result |= error(_("Could not set up %s"), b_head.buf); + goto cleanup; + } + if (opt_a) + report_set_head_auto(argv[0], head_name, &b_local_head, was_detached); + if (remote->follow_remote_head == FOLLOW_REMOTE_ALWAYS) { + struct strbuf config_name = STRBUF_INIT; + strbuf_addf(&config_name, + "remote.%s.followremotehead", remote->name); + git_config_set(config_name.buf, "warn"); + strbuf_release(&config_name); } - strbuf_release(&buf); - strbuf_release(&buf2); +cleanup: + free(head_name); + strbuf_release(&b_head); + strbuf_release(&b_remote_head); + strbuf_release(&b_local_head); return result; } @@ -1503,7 +1561,8 @@ static int prune_remote(const char *remote, int dry_run) return result; } -static int prune(int argc, const char **argv, const char *prefix) +static int prune(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int dry_run = 0, result = 0; struct option options[] = { @@ -1534,7 +1593,8 @@ static int get_remote_default(const char *key, const char *value UNUSED, return 0; } -static int update(int argc, const char **argv, const char *prefix) +static int update(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i, prune = -1; struct option options[] = { @@ -1616,7 +1676,8 @@ static int set_remote_branches(const char *remotename, const char **branches, return 0; } -static int set_branches(int argc, const char **argv, const char *prefix) +static int set_branches(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int add_mode = 0; struct option options[] = { @@ -1635,7 +1696,8 @@ static int set_branches(int argc, const char **argv, const char *prefix) return set_remote_branches(argv[0], argv + 1, add_mode); } -static int get_url(int argc, const char **argv, const char *prefix) +static int get_url(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i, push_mode = 0, all_mode = 0; const char *remotename = NULL; @@ -1674,7 +1736,8 @@ static int get_url(int argc, const char **argv, const char *prefix) return 0; } -static int set_url(int argc, const char **argv, const char *prefix) +static int set_url(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i, push_mode = 0, add_mode = 0, delete_mode = 0; int matches = 0, negative_matches = 0; @@ -1765,7 +1828,7 @@ static int set_url(int argc, const char **argv, const char *prefix) int cmd_remote(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -1788,7 +1851,7 @@ int cmd_remote(int argc, PARSE_OPT_SUBCOMMAND_OPTIONAL); if (fn) { - return !!fn(argc, argv, prefix); + return !!fn(argc, argv, prefix, repo); } else { if (argc) { error(_("unknown subcommand: `%s'"), argv[0]); diff --git a/builtin/repack.c b/builtin/repack.c index cb4420f08566b4..75e3752353a27f 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "dir.h" @@ -39,7 +41,9 @@ static int run_update_server_info = 1; static char *packdir, *packtmp_name, *packtmp; static const char *const git_repack_usage[] = { - N_("git repack [<options>]"), + N_("git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" + "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" + "[--write-midx] [--name-hash-version=<n>]"), NULL }; @@ -58,6 +62,7 @@ struct pack_objects_args { int no_reuse_object; int quiet; int local; + int name_hash_version; struct list_objects_filter_options filter_options; }; @@ -86,17 +91,34 @@ static int repack_config(const char *var, const char *value, run_update_server_info = git_config_bool(var, value); return 0; } - if (!strcmp(var, "repack.cruftwindow")) + if (!strcmp(var, "repack.cruftwindow")) { + free(cruft_po_args->window); return git_config_string(&cruft_po_args->window, var, value); - if (!strcmp(var, "repack.cruftwindowmemory")) + } + if (!strcmp(var, "repack.cruftwindowmemory")) { + free(cruft_po_args->window_memory); return git_config_string(&cruft_po_args->window_memory, var, value); - if (!strcmp(var, "repack.cruftdepth")) + } + if (!strcmp(var, "repack.cruftdepth")) { + free(cruft_po_args->depth); return git_config_string(&cruft_po_args->depth, var, value); - if (!strcmp(var, "repack.cruftthreads")) + } + if (!strcmp(var, "repack.cruftthreads")) { + free(cruft_po_args->threads); return git_config_string(&cruft_po_args->threads, var, value); + } return git_default_config(var, value, ctx, cb); } +static void pack_objects_args_release(struct pack_objects_args *args) +{ + free(args->window); + free(args->window_memory); + free(args->depth); + free(args->threads); + list_objects_filter_release(&args->filter_options); +} + struct existing_packs { struct string_list kept_packs; struct string_list non_kept_packs; @@ -289,6 +311,8 @@ static void prepare_pack_objects(struct child_process *cmd, strvec_pushf(&cmd->args, "--no-reuse-delta"); if (args->no_reuse_object) strvec_pushf(&cmd->args, "--no-reuse-object"); + if (args->name_hash_version) + strvec_pushf(&cmd->args, "--name-hash-version=%d", args->name_hash_version); if (args->local) strvec_push(&cmd->args, "--local"); if (args->quiet) @@ -387,7 +411,7 @@ static void repack_promisor_objects(const struct pack_objects_args *args, * {type -> existing pack order} ordering when computing deltas instead * of a {type -> size} ordering, which may produce better deltas. */ - for_each_packed_object(write_oid, &cmd, + for_each_packed_object(the_repository, write_oid, &cmd, FOR_EACH_OBJECT_PROMISOR_ONLY); if (cmd.in == -1) { @@ -1156,12 +1180,16 @@ int cmd_repack(int argc, const char *unpack_unreachable = NULL; int keep_unreachable = 0; struct string_list keep_pack_list = STRING_LIST_INIT_NODUP; - struct pack_objects_args po_args = {NULL}; - struct pack_objects_args cruft_po_args = {NULL}; + struct pack_objects_args po_args = { 0 }; + struct pack_objects_args cruft_po_args = { 0 }; int write_midx = 0; const char *cruft_expiration = NULL; const char *expire_to = NULL; const char *filter_to = NULL; + const char *opt_window = NULL; + const char *opt_window_memory = NULL; + const char *opt_depth = NULL; + const char *opt_threads = NULL; struct option builtin_repack_options[] = { OPT_BIT('a', NULL, &pack_everything, @@ -1182,6 +1210,8 @@ int cmd_repack(int argc, N_("pass --no-reuse-delta to git-pack-objects")), OPT_BOOL('F', NULL, &po_args.no_reuse_object, N_("pass --no-reuse-object to git-pack-objects")), + OPT_INTEGER(0, "name-hash-version", &po_args.name_hash_version, + N_("specify the name hash version to use for grouping similar objects by path")), OPT_NEGBIT('n', NULL, &run_update_server_info, N_("do not run git-update-server-info"), 1), OPT__QUIET(&po_args.quiet, N_("be quiet")), @@ -1195,13 +1225,13 @@ int cmd_repack(int argc, N_("with -A, do not loosen objects older than this")), OPT_BOOL('k', "keep-unreachable", &keep_unreachable, N_("with -a, repack unreachable objects")), - OPT_STRING(0, "window", &po_args.window, N_("n"), + OPT_STRING(0, "window", &opt_window, N_("n"), N_("size of the window used for delta compression")), - OPT_STRING(0, "window-memory", &po_args.window_memory, N_("bytes"), + OPT_STRING(0, "window-memory", &opt_window_memory, N_("bytes"), N_("same as the above, but limit memory size instead of entries count")), - OPT_STRING(0, "depth", &po_args.depth, N_("n"), + OPT_STRING(0, "depth", &opt_depth, N_("n"), N_("limits the maximum delta depth")), - OPT_STRING(0, "threads", &po_args.threads, N_("n"), + OPT_STRING(0, "threads", &opt_threads, N_("n"), N_("limits the maximum number of threads")), OPT_MAGNITUDE(0, "max-pack-size", &po_args.max_pack_size, N_("maximum size of each packfile")), @@ -1228,6 +1258,11 @@ int cmd_repack(int argc, argc = parse_options(argc, argv, prefix, builtin_repack_options, git_repack_usage, 0); + po_args.window = xstrdup_or_null(opt_window); + po_args.window_memory = xstrdup_or_null(opt_window_memory); + po_args.depth = xstrdup_or_null(opt_depth); + po_args.threads = xstrdup_or_null(opt_threads); + if (delete_redundant && repository_format_precious_objects) die(_("cannot delete packs in a precious-objects repo")); @@ -1342,9 +1377,12 @@ int cmd_repack(int argc, "--unpack-unreachable"); } else if (keep_unreachable) { strvec_push(&cmd.args, "--keep-unreachable"); - strvec_push(&cmd.args, "--pack-loose-unreachable"); } } + + if (keep_unreachable && delete_redundant && + !(pack_everything & PACK_CRUFT)) + strvec_push(&cmd.args, "--pack-loose-unreachable"); } else if (geometry.split_factor) { strvec_push(&cmd.args, "--stdin-packs"); strvec_push(&cmd.args, "--unpacked"); @@ -1393,13 +1431,13 @@ int cmd_repack(int argc, const char *pack_prefix = find_pack_prefix(packdir, packtmp); if (!cruft_po_args.window) - cruft_po_args.window = po_args.window; + cruft_po_args.window = xstrdup_or_null(po_args.window); if (!cruft_po_args.window_memory) - cruft_po_args.window_memory = po_args.window_memory; + cruft_po_args.window_memory = xstrdup_or_null(po_args.window_memory); if (!cruft_po_args.depth) - cruft_po_args.depth = po_args.depth; + cruft_po_args.depth = xstrdup_or_null(po_args.depth); if (!cruft_po_args.threads) - cruft_po_args.threads = po_args.threads; + cruft_po_args.threads = xstrdup_or_null(po_args.threads); if (!cruft_po_args.max_pack_size) cruft_po_args.max_pack_size = po_args.max_pack_size; @@ -1537,13 +1575,13 @@ int cmd_repack(int argc, } if (run_update_server_info) - update_server_info(0); + update_server_info(the_repository, 0); if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) { unsigned flags = 0; if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0)) flags |= MIDX_WRITE_INCREMENTAL; - write_midx_file(repo_get_object_directory(the_repository), + write_midx_file(the_repository, repo_get_object_directory(the_repository), NULL, NULL, flags); } @@ -1552,7 +1590,8 @@ int cmd_repack(int argc, string_list_clear(&names, 1); existing_packs_release(&existing); free_pack_geometry(&geometry); - list_objects_filter_release(&po_args.filter_options); + pack_objects_args_release(&po_args); + pack_objects_args_release(&cruft_po_args); return ret; } diff --git a/builtin/replace.c b/builtin/replace.c index a44f4e7ea9ff55..15ec0922ce14d8 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -201,7 +201,7 @@ static int replace_object_oid(const char *object_ref, } transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction || ref_transaction_update(transaction, ref.buf, repl, &prev, NULL, NULL, 0, NULL, &err) || @@ -345,7 +345,7 @@ static int edit_and_replace(const char *object_ref, int force, int raw) } strbuf_release(&ref); - tmpfile = git_pathdup("REPLACE_EDITOBJ"); + tmpfile = repo_git_path(the_repository, "REPLACE_EDITOBJ"); if (export_object(&old_oid, type, raw, tmpfile)) { free(tmpfile); return -1; diff --git a/builtin/replay.c b/builtin/replay.c index 2d12a4e403fa7d..032c172b65ece4 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -2,9 +2,11 @@ * "git replay" builtin command */ +#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" -#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "hex.h" @@ -161,9 +163,10 @@ static void determine_replay_mode(struct rev_cmdline_info *cmd_info, 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) { + + die_for_incompatible_opt2(!!onto_name, "--onto", + !!*advance_name, "--advance"); + if (onto_name) { *onto = peel_committish(onto_name); if (rinfo.positive_refexprs < strset_get_size(&rinfo.positive_refs)) diff --git a/builtin/rerere.c b/builtin/rerere.c index f7143c3f5d5670..1312e79d89f38e 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -1,11 +1,12 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" - -#include "string-list.h" #include "rerere.h" +#include "strbuf.h" +#include "string-list.h" #include "xdiff/xdiff.h" #include "xdiff-interface.h" #include "pathspec.h" @@ -55,7 +56,7 @@ int cmd_rerere(int argc, struct repository *repo UNUSED) { struct string_list merge_rr = STRING_LIST_INIT_DUP; - int i, autoupdate = -1, flags = 0; + int autoupdate = -1, flags = 0; struct option options[] = { OPT_SET_INT(0, "rerere-autoupdate", &autoupdate, @@ -98,11 +99,11 @@ int cmd_rerere(int argc, if (setup_rerere(the_repository, &merge_rr, flags | RERERE_READONLY) < 0) return 0; - for (i = 0; i < merge_rr.nr; i++) + for (size_t i = 0; i < merge_rr.nr; i++) printf("%s\n", merge_rr.items[i].string); } else if (!strcmp(argv[0], "remaining")) { rerere_remaining(the_repository, &merge_rr); - for (i = 0; i < merge_rr.nr; i++) { + for (size_t i = 0; i < merge_rr.nr; i++) { if (merge_rr.items[i].util != RERERE_RESOLVED) printf("%s\n", merge_rr.items[i].string); else @@ -111,15 +112,18 @@ int cmd_rerere(int argc, merge_rr.items[i].util = NULL; } } else if (!strcmp(argv[0], "diff")) { + struct strbuf buf = STRBUF_INIT; if (setup_rerere(the_repository, &merge_rr, flags | RERERE_READONLY) < 0) return 0; - for (i = 0; i < merge_rr.nr; i++) { + for (size_t i = 0; i < merge_rr.nr; i++) { const char *path = merge_rr.items[i].string; const struct rerere_id *id = merge_rr.items[i].util; - if (diff_two(rerere_path(id, "preimage"), path, path, path)) - die(_("unable to generate diff for '%s'"), rerere_path(id, NULL)); + if (diff_two(rerere_path(&buf, id, "preimage"), path, path, path)) + die(_("unable to generate diff for '%s'"), rerere_path(&buf, id, NULL)); } + + strbuf_release(&buf); } else usage_with_options(rerere_usage, options); diff --git a/builtin/reset.c b/builtin/reset.c index 7154f88826d4c4..73b4537a9a567d 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -7,7 +7,9 @@ * * Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "advice.h" #include "config.h" diff --git a/builtin/rev-list.c b/builtin/rev-list.c index f62bcbf2b140d1..bb26bee0d4565a 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "commit.h" @@ -20,7 +22,10 @@ #include "progress.h" #include "reflog-walk.h" #include "oidset.h" +#include "oidmap.h" #include "packfile.h" +#include "quote.h" +#include "strbuf.h" static const char rev_list_usage[] = "git rev-list [<options>] <commit>... [--] [<path>...]\n" @@ -71,11 +76,17 @@ static unsigned progress_counter; static struct oidset omitted_objects; static int arg_print_omitted; /* print objects omitted by filter */ -static struct oidset missing_objects; +struct missing_objects_map_entry { + struct oidmap_entry entry; + const char *path; + unsigned type; +}; +static struct oidmap missing_objects; enum missing_action { MA_ERROR = 0, /* fail if any missing objects are encountered */ MA_ALLOW_ANY, /* silently allow ALL missing objects */ MA_PRINT, /* print ALL missing objects in special section */ + MA_PRINT_INFO, /* same as MA_PRINT but also prints missing object info */ MA_ALLOW_PROMISOR, /* silently allow all missing PROMISOR objects */ }; static enum missing_action arg_missing_action; @@ -99,7 +110,49 @@ static off_t get_object_disk_usage(struct object *obj) return size; } -static inline void finish_object__ma(struct object *obj) +static void add_missing_object_entry(struct object_id *oid, const char *path, + unsigned type) +{ + struct missing_objects_map_entry *entry; + + if (oidmap_get(&missing_objects, oid)) + return; + + CALLOC_ARRAY(entry, 1); + entry->entry.oid = *oid; + entry->type = type; + if (path) + entry->path = xstrdup(path); + oidmap_put(&missing_objects, entry); +} + +static void print_missing_object(struct missing_objects_map_entry *entry, + int print_missing_info) +{ + struct strbuf sb = STRBUF_INIT; + + if (!print_missing_info) { + printf("?%s\n", oid_to_hex(&entry->entry.oid)); + return; + } + + if (entry->path && *entry->path) { + struct strbuf path = STRBUF_INIT; + + strbuf_addstr(&sb, " path="); + quote_path(entry->path, NULL, &path, QUOTE_PATH_QUOTE_SP); + strbuf_addbuf(&sb, &path); + + strbuf_release(&path); + } + if (entry->type) + strbuf_addf(&sb, " type=%s", type_name(entry->type)); + + printf("?%s%s\n", oid_to_hex(&entry->entry.oid), sb.buf); + strbuf_release(&sb); +} + +static inline void finish_object__ma(struct object *obj, const char *name) { /* * Whether or not we try to dynamically fetch missing objects @@ -117,11 +170,12 @@ static inline void finish_object__ma(struct object *obj) return; case MA_PRINT: - oidset_insert(&missing_objects, &obj->oid); + case MA_PRINT_INFO: + add_missing_object_entry(&obj->oid, name, obj->type); return; case MA_ALLOW_PROMISOR: - if (is_promisor_object(&obj->oid)) + if (is_promisor_object(the_repository, &obj->oid)) return; die("unexpected missing %s object '%s'", type_name(obj->type), oid_to_hex(&obj->oid)); @@ -150,7 +204,7 @@ static void show_commit(struct commit *commit, void *data) if (revs->do_not_die_on_missing_objects && oidset_contains(&revs->missing_commits, &commit->object.oid)) { - finish_object__ma(&commit->object); + finish_object__ma(&commit->object, NULL); return; } @@ -266,12 +320,11 @@ static void show_commit(struct commit *commit, void *data) finish_commit(commit); } -static int finish_object(struct object *obj, const char *name UNUSED, - void *cb_data) +static int finish_object(struct object *obj, const char *name, void *cb_data) { struct rev_list_info *info = cb_data; if (oid_object_info_extended(the_repository, &obj->oid, NULL, 0) < 0) { - finish_object__ma(obj); + finish_object__ma(obj, name); return 1; } if (info->revs->verify_objects && !obj->parsed && obj->type != OBJ_COMMIT) @@ -412,6 +465,12 @@ static inline int parse_missing_action_value(const char *value) return 1; } + if (!strcmp(value, "print-info")) { + arg_missing_action = MA_PRINT_INFO; + fetch_if_missing = 0; + return 1; + } + if (!strcmp(value, "allow-promisor")) { arg_missing_action = MA_ALLOW_PROMISOR; fetch_if_missing = 0; @@ -485,6 +544,13 @@ static int try_bitmap_traversal(struct rev_info *revs, if (revs->max_count >= 0) return -1; + /* + * We can't know which commits were left/right in a single traversal, + * and we don't yet know how to traverse them separately. + */ + if (revs->left_right) + return -1; + bitmap_git = prepare_bitmap_walk(revs, filter_provided_objects); if (!bitmap_git) return -1; @@ -533,8 +599,7 @@ int cmd_rev_list(int argc, const char *show_progress = NULL; int ret = 0; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(rev_list_usage); + show_usage_if_asked(argc, argv, rev_list_usage); git_config(git_default_config, NULL); repo_init_revisions(the_repository, &revs, prefix); @@ -726,7 +791,8 @@ int cmd_rev_list(int argc, revs.limited = 1; if (show_progress) - progress = start_delayed_progress(show_progress, 0); + progress = start_delayed_progress(the_repository, + show_progress, 0); if (use_bitmap_index) { if (!try_bitmap_count(&revs, filter_provided_objects)) @@ -772,10 +838,18 @@ int cmd_rev_list(int argc, if (arg_print_omitted) oidset_init(&omitted_objects, DEFAULT_OIDSET_SIZE); - if (arg_missing_action == MA_PRINT) { - oidset_init(&missing_objects, DEFAULT_OIDSET_SIZE); + if (arg_missing_action == MA_PRINT || + arg_missing_action == MA_PRINT_INFO) { + struct oidset_iter iter; + struct object_id *oid; + + oidmap_init(&missing_objects, DEFAULT_OIDSET_SIZE); + oidset_iter_init(&revs.missing_commits, &iter); + /* Add missing tips */ - oidset_insert_from_set(&missing_objects, &revs.missing_commits); + while ((oid = oidset_iter_next(&iter))) + add_missing_object_entry(oid, NULL, 0); + oidset_clear(&revs.missing_commits); } @@ -791,13 +865,20 @@ int cmd_rev_list(int argc, printf("~%s\n", oid_to_hex(oid)); oidset_clear(&omitted_objects); } - if (arg_missing_action == MA_PRINT) { - struct oidset_iter iter; - struct object_id *oid; - oidset_iter_init(&missing_objects, &iter); - while ((oid = oidset_iter_next(&iter))) - printf("?%s\n", oid_to_hex(oid)); - oidset_clear(&missing_objects); + if (arg_missing_action == MA_PRINT || + arg_missing_action == MA_PRINT_INFO) { + struct missing_objects_map_entry *entry; + struct oidmap_iter iter; + + oidmap_iter_init(&missing_objects, &iter); + + while ((entry = oidmap_iter_next(&iter))) { + print_missing_object(entry, arg_missing_action == + MA_PRINT_INFO); + free((void *)entry->path); + } + + oidmap_free(&missing_objects, true); } stop_progress(&progress); diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 8401b4d7ab64f0..490da33beccf72 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -3,7 +3,10 @@ * * Copyright (C) Linus Torvalds, 2005 */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" @@ -710,6 +713,8 @@ int cmd_rev_parse(int argc, int seen_end_of_options = 0; enum format_type format = FORMAT_DEFAULT; + show_usage_if_asked(argc, argv, builtin_rev_parse_usage); + if (argc > 1 && !strcmp("--parseopt", argv[1])) return cmd_parseopt(argc - 1, argv + 1, prefix); @@ -784,8 +789,8 @@ int cmd_rev_parse(int argc, if (!strcmp(arg, "--git-path")) { if (!argv[i + 1]) die(_("--git-path requires an argument")); - strbuf_reset(&buf); - print_path(git_path("%s", argv[i + 1]), prefix, + print_path(repo_git_path_replace(the_repository, &buf, + "%s", argv[i + 1]), prefix, format, DEFAULT_RELATIVE_IF_SHARED); i++; @@ -1078,7 +1083,7 @@ int cmd_rev_parse(int argc, die(_("Could not read the index")); if (the_repository->index->split_index) { const struct object_id *oid = &the_repository->index->split_index->base_oid; - const char *path = git_path("sharedindex.%s", oid_to_hex(oid)); + const char *path = repo_git_path_replace(the_repository, &buf, "sharedindex.%s", oid_to_hex(oid)); print_path(path, prefix, format, DEFAULT_RELATIVE); } continue; diff --git a/builtin/revert.c b/builtin/revert.c index 55ba1092c52f42..aca6c293cdfb2f 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "builtin.h" #include "parse-options.h" @@ -110,6 +111,9 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, const char * const * usage_str = revert_or_cherry_pick_usage(opts); const char *me = action_name(opts); const char *cleanup_arg = NULL; + const char sentinel_value; + const char *strategy = &sentinel_value; + const char *gpg_sign = &sentinel_value; enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED; int cmd = 0; struct option base_options[] = { @@ -125,10 +129,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, OPT_CALLBACK('m', "mainline", opts, N_("parent-number"), N_("select mainline parent"), option_parse_m), OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto), - OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")), + OPT_STRING(0, "strategy", &strategy, N_("strategy"), N_("merge strategy")), OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"), N_("option for merge strategy")), - { OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"), + { OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"), N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" }, OPT_END() }; @@ -240,8 +244,14 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, usage_with_options(usage_str, options); /* These option values will be free()d */ - opts->gpg_sign = xstrdup_or_null(opts->gpg_sign); - opts->strategy = xstrdup_or_null(opts->strategy); + if (gpg_sign != &sentinel_value) { + free(opts->gpg_sign); + opts->gpg_sign = xstrdup_or_null(gpg_sign); + } + if (strategy != &sentinel_value) { + free(opts->strategy); + opts->strategy = xstrdup_or_null(strategy); + } if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM")) opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM")); free(options); diff --git a/builtin/rm.c b/builtin/rm.c index eaff027258db4d..12ae086a556ce3 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -3,7 +3,10 @@ * * Copyright (C) Linus Torvalds 2006 */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "advice.h" #include "config.h" diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 81fc96d423afd7..8d461008e2e860 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -317,7 +317,7 @@ int cmd_send_pack(int argc, set_ref_status_for_push(remote_refs, args.send_mirror, args.force_update); - ret = send_pack(&args, fd, conn, remote_refs, &extra_have); + ret = send_pack(the_repository, &args, fd, conn, remote_refs, &extra_have); if (helper_status) print_helper_status(remote_refs); @@ -340,8 +340,11 @@ int cmd_send_pack(int argc, /* stable plumbing output; do not modify or localize */ fprintf(stderr, "Everything up-to-date\n"); + string_list_clear(&push_options, 0); free_refs(remote_refs); free_refs(local_refs); refspec_clear(&rs); + oid_array_clear(&shallow); + clear_cas_option(&cas); return ret; } diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 3ed5c460786dfc..30075b67be8dac 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "config.h" #include "commit.h" @@ -407,6 +408,18 @@ int cmd_shortlog(int argc, struct parse_opt_ctx_t ctx; + /* + * NEEDSWORK: Later on we'll call parse_revision_opt which relies on + * the hash algorithm being set but since we are operating outside of a + * Git repository we cannot determine one. This is only needed because + * parse_revision_opt expects hexsz for --abbrev which is irrelevant + * for shortlog outside of a git repository. For now explicitly set + * SHA1, but ideally the parsing machinery would be split between + * git/nongit so that we do not have to do this. + */ + if (nongit && !the_hash_algo) + repo_set_hash_algo(the_repository, GIT_HASH_SHA1); + git_config(git_default_config, NULL); shortlog_init(&log); repo_init_revisions(the_repository, &rev, prefix); diff --git a/builtin/show-branch.c b/builtin/show-branch.c index cd6bdf63bc103d..fce6b404e9265b 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "environment.h" diff --git a/builtin/show-index.c b/builtin/show-index.c index f164c01bbea400..9d4ecf5e7ba010 100644 --- a/builtin/show-index.c +++ b/builtin/show-index.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "gettext.h" #include "hash.h" @@ -7,7 +9,7 @@ #include "parse-options.h" static const char *const show_index_usage[] = { - "git show-index [--object-format=<hash-algorithm>]", + "git show-index [--object-format=<hash-algorithm>] < <pack-idx-file>", NULL }; @@ -38,6 +40,15 @@ int cmd_show_index(int argc, repo_set_hash_algo(the_repository, hash_algo); } + /* + * Fallback to SHA1 if we are running outside of a repository. + * + * TODO: Figure out and implement a way to detect the hash algorithm in use by the + * the index file passed in and use that instead. + */ + if (!the_hash_algo) + repo_set_hash_algo(the_repository, GIT_HASH_SHA1); + hashsz = the_hash_algo->rawsz; if (fread(top_index, 2 * 4, 1, stdin) != 1) diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index e4e791a4c9a6c2..14dcace5f8ff7c 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "dir.h" @@ -48,7 +50,8 @@ static char const * const builtin_sparse_checkout_list_usage[] = { NULL }; -static int sparse_checkout_list(int argc, const char **argv, const char *prefix) +static int sparse_checkout_list(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_sparse_checkout_list_options[] = { OPT_END(), @@ -443,7 +446,8 @@ static struct sparse_checkout_init_opts { int sparse_index; } init_opts; -static int sparse_checkout_init(int argc, const char **argv, const char *prefix) +static int sparse_checkout_init(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct pattern_list pl; char *sparse_filename; @@ -669,7 +673,7 @@ static void add_patterns_literal(int argc, const char **argv, add_patterns_from_input(pl, argc, argv, use_stdin ? stdin : NULL); } -static int modify_pattern_list(int argc, const char **argv, int use_stdin, +static int modify_pattern_list(struct strvec *args, int use_stdin, enum modify_type m) { int result; @@ -679,13 +683,13 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin, switch (m) { case ADD: if (core_sparse_checkout_cone) - add_patterns_cone_mode(argc, argv, pl, use_stdin); + add_patterns_cone_mode(args->nr, args->v, pl, use_stdin); else - add_patterns_literal(argc, argv, pl, use_stdin); + add_patterns_literal(args->nr, args->v, pl, use_stdin); break; case REPLACE: - add_patterns_from_input(pl, argc, argv, + add_patterns_from_input(pl, args->nr, args->v, use_stdin ? stdin : NULL); break; } @@ -706,12 +710,12 @@ static int modify_pattern_list(int argc, const char **argv, int use_stdin, return result; } -static void sanitize_paths(int argc, const char **argv, +static void sanitize_paths(struct strvec *args, const char *prefix, int skip_checks) { int i; - if (!argc) + if (!args->nr) return; if (prefix && *prefix && core_sparse_checkout_cone) { @@ -721,8 +725,11 @@ static void sanitize_paths(int argc, const char **argv, */ int prefix_len = strlen(prefix); - for (i = 0; i < argc; i++) - argv[i] = prefix_path(prefix, prefix_len, argv[i]); + for (i = 0; i < args->nr; i++) { + char *prefixed_path = prefix_path(prefix, prefix_len, args->v[i]); + strvec_replace(args, i, prefixed_path); + free(prefixed_path); + } } if (skip_checks) @@ -732,20 +739,20 @@ static void sanitize_paths(int argc, const char **argv, die(_("please run from the toplevel directory in non-cone mode")); if (core_sparse_checkout_cone) { - for (i = 0; i < argc; i++) { - if (argv[i][0] == '/') + for (i = 0; i < args->nr; i++) { + if (args->v[i][0] == '/') die(_("specify directories rather than patterns (no leading slash)")); - if (argv[i][0] == '!') + if (args->v[i][0] == '!') die(_("specify directories rather than patterns. If your directory starts with a '!', pass --skip-checks")); - if (strpbrk(argv[i], "*?[]")) + if (strpbrk(args->v[i], "*?[]")) die(_("specify directories rather than patterns. If your directory really has any of '*?[]\\' in it, pass --skip-checks")); } } - for (i = 0; i < argc; i++) { + for (i = 0; i < args->nr; i++) { struct cache_entry *ce; struct index_state *index = the_repository->index; - int pos = index_name_pos(index, argv[i], strlen(argv[i])); + int pos = index_name_pos(index, args->v[i], strlen(args->v[i])); if (pos < 0) continue; @@ -754,9 +761,9 @@ static void sanitize_paths(int argc, const char **argv, continue; if (core_sparse_checkout_cone) - die(_("'%s' is not a directory; to treat it as a directory anyway, rerun with --skip-checks"), argv[i]); + die(_("'%s' is not a directory; to treat it as a directory anyway, rerun with --skip-checks"), args->v[i]); else - warning(_("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)."), argv[i]); + warning(_("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)."), args->v[i]); } } @@ -770,7 +777,8 @@ static struct sparse_checkout_add_opts { int use_stdin; } add_opts; -static int sparse_checkout_add(int argc, const char **argv, const char *prefix) +static int sparse_checkout_add(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_sparse_checkout_add_options[] = { OPT_BOOL_F(0, "skip-checks", &add_opts.skip_checks, @@ -780,6 +788,8 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) N_("read patterns from standard in")), OPT_END(), }; + struct strvec patterns = STRVEC_INIT; + int ret; setup_work_tree(); if (!core_apply_sparse_checkout) @@ -791,9 +801,14 @@ static int sparse_checkout_add(int argc, const char **argv, const char *prefix) builtin_sparse_checkout_add_options, builtin_sparse_checkout_add_usage, 0); - sanitize_paths(argc, argv, prefix, add_opts.skip_checks); + for (int i = 0; i < argc; i++) + strvec_push(&patterns, argv[i]); + sanitize_paths(&patterns, prefix, add_opts.skip_checks); - return modify_pattern_list(argc, argv, add_opts.use_stdin, ADD); + ret = modify_pattern_list(&patterns, add_opts.use_stdin, ADD); + + strvec_clear(&patterns); + return ret; } static char const * const builtin_sparse_checkout_set_usage[] = { @@ -808,7 +823,8 @@ static struct sparse_checkout_set_opts { int use_stdin; } set_opts; -static int sparse_checkout_set(int argc, const char **argv, const char *prefix) +static int sparse_checkout_set(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int default_patterns_nr = 2; const char *default_patterns[] = {"/*", "!/*/", NULL}; @@ -826,6 +842,8 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) PARSE_OPT_NONEG), OPT_END(), }; + struct strvec patterns = STRVEC_INIT; + int ret; setup_work_tree(); repo_read_index(the_repository); @@ -846,13 +864,18 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix) * top-level directory (much as 'init' would do). */ if (!core_sparse_checkout_cone && !set_opts.use_stdin && argc == 0) { - argv = default_patterns; - argc = default_patterns_nr; + for (int i = 0; i < default_patterns_nr; i++) + strvec_push(&patterns, default_patterns[i]); } else { - sanitize_paths(argc, argv, prefix, set_opts.skip_checks); + for (int i = 0; i < argc; i++) + strvec_push(&patterns, argv[i]); + sanitize_paths(&patterns, prefix, set_opts.skip_checks); } - return modify_pattern_list(argc, argv, set_opts.use_stdin, REPLACE); + ret = modify_pattern_list(&patterns, set_opts.use_stdin, REPLACE); + + strvec_clear(&patterns); + return ret; } static char const * const builtin_sparse_checkout_reapply_usage[] = { @@ -866,7 +889,8 @@ static struct sparse_checkout_reapply_opts { } reapply_opts; static int sparse_checkout_reapply(int argc, const char **argv, - const char *prefix) + const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_sparse_checkout_reapply_options[] = { OPT_BOOL(0, "cone", &reapply_opts.cone_mode, @@ -901,7 +925,8 @@ static char const * const builtin_sparse_checkout_disable_usage[] = { }; static int sparse_checkout_disable(int argc, const char **argv, - const char *prefix) + const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_sparse_checkout_disable_options[] = { OPT_END(), @@ -924,6 +949,11 @@ static int sparse_checkout_disable(int argc, const char **argv, builtin_sparse_checkout_disable_options, builtin_sparse_checkout_disable_usage, 0); + /* + * Disable the advice message for expanding a sparse index, as we + * are expecting to do that when disabling sparse-checkout. + */ + give_advice_on_expansion = 0; repo_read_index(the_repository); memset(&pl, 0, sizeof(pl)); @@ -984,7 +1014,8 @@ static int check_rules(struct pattern_list *pl, int null_terminated) { return 0; } -static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix) +static int sparse_checkout_check_rules(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_sparse_checkout_check_rules_options[] = { OPT_BOOL('z', NULL, &check_rules_opts.null_termination, @@ -1032,7 +1063,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char * int cmd_sparse_checkout(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_sparse_checkout_options[] = { @@ -1055,5 +1086,5 @@ int cmd_sparse_checkout(int argc, prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/stash.c b/builtin/stash.c index f1acc918d08d72..dbaa999cf171a7 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" #include "config.h" @@ -249,7 +250,8 @@ static int do_clear_stash(void) ref_stash, &obj, 0); } -static int clear_stash(int argc, const char **argv, const char *prefix) +static int clear_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() @@ -652,7 +654,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, return ret; } -static int apply_stash(int argc, const char **argv, const char *prefix) +static int apply_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int ret = -1; int quiet = 0; @@ -726,7 +729,8 @@ static int get_stash_info_assert(struct stash_info *info, int argc, return 0; } -static int drop_stash(int argc, const char **argv, const char *prefix) +static int drop_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int ret = -1; int quiet = 0; @@ -748,7 +752,8 @@ static int drop_stash(int argc, const char **argv, const char *prefix) return ret; } -static int pop_stash(int argc, const char **argv, const char *prefix) +static int pop_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int ret = -1; int index = 0; @@ -778,7 +783,8 @@ static int pop_stash(int argc, const char **argv, const char *prefix) return ret; } -static int branch_stash(int argc, const char **argv, const char *prefix) +static int branch_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int ret = -1; const char *branch = NULL; @@ -816,7 +822,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix) return ret; } -static int list_stash(int argc, const char **argv, const char *prefix) +static int list_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct child_process cp = CHILD_PROCESS_INIT; struct option options[] = { @@ -867,9 +874,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op struct tree *tree[ARRAY_SIZE(oid)]; struct tree_desc tree_desc[ARRAY_SIZE(oid)]; struct unpack_trees_options unpack_tree_opt = { 0 }; - int i; - for (i = 0; i < ARRAY_SIZE(oid); i++) { + for (size_t i = 0; i < ARRAY_SIZE(oid); i++) { tree[i] = parse_tree_indirect(oid[i]); if (parse_tree(tree[i]) < 0) die(_("failed to parse tree")); @@ -889,7 +895,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op do_diff_cache(&info->b_commit, diff_opt); } -static int show_stash(int argc, const char **argv, const char *prefix) +static int show_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i; int ret = -1; @@ -1017,7 +1024,8 @@ static int do_store_stash(const struct object_id *w_commit, const char *stash_ms return 0; } -static int store_stash(int argc, const char **argv, const char *prefix) +static int store_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int quiet = 0; const char *stash_msg = NULL; @@ -1491,7 +1499,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b return ret; } -static int create_stash(int argc, const char **argv, const char *prefix UNUSED) +static int create_stash(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { int ret; struct strbuf stash_msg_buf = STRBUF_INIT; @@ -1548,12 +1557,11 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q repo_read_index_preload(the_repository, NULL, 0); if (!include_untracked && ps->nr) { - int i; char *ps_matched = xcalloc(ps->nr, 1); /* TODO: audit for interaction with sparse-index. */ ensure_full_index(the_repository->index); - for (i = 0; i < the_repository->index->cache_nr; i++) + for (size_t i = 0; i < the_repository->index->cache_nr; i++) ce_path_match(the_repository->index, the_repository->index->cache[i], ps, ps_matched); @@ -1759,7 +1767,7 @@ static int push_stash(int argc, const char **argv, const char *prefix, int quiet = 0; int pathspec_file_nul = 0; const char *stash_msg = NULL; - const char *pathspec_from_file = NULL; + char *pathspec_from_file = NULL; struct pathspec ps; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, @@ -1821,16 +1829,20 @@ static int push_stash(int argc, const char **argv, const char *prefix, ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode, include_untracked, only_staged); + clear_pathspec(&ps); + free(pathspec_from_file); return ret; } -static int push_stash_unassumed(int argc, const char **argv, const char *prefix) +static int push_stash_unassumed(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { return push_stash(argc, argv, prefix, 0); } -static int save_stash(int argc, const char **argv, const char *prefix) +static int save_stash(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int keep_index = -1; int only_staged = 0; @@ -1876,7 +1888,7 @@ static int save_stash(int argc, const char **argv, const char *prefix) int cmd_stash(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { pid_t pid = getpid(); const char *index_file; @@ -1914,9 +1926,9 @@ int cmd_stash(int argc, (uintmax_t)pid); if (fn) - return !!fn(argc, argv, prefix); + return !!fn(argc, argv, prefix, repo); else if (!argc) - return !!push_stash_unassumed(0, NULL, prefix); + return !!push_stash_unassumed(0, NULL, prefix, repo); /* Assume 'stash push' */ strvec_push(&args, "push"); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 8d36aefbe6d084..c1a8029714bfe9 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "abspath.h" #include "environment.h" @@ -194,7 +195,7 @@ static int module_list_compute(const char **argv, struct pathspec *pathspec, struct module_list *list) { - int i, result = 0; + int result = 0; char *ps_matched = NULL; parse_pathspec(pathspec, 0, @@ -207,7 +208,7 @@ static int module_list_compute(const char **argv, if (repo_read_index(the_repository) < 0) die(_("index file corrupt")); - for (i = 0; i < the_repository->index->cache_nr; i++) { + for (size_t i = 0; i < the_repository->index->cache_nr; i++) { const struct cache_entry *ce = the_repository->index->cache[i]; if (!match_pathspec(the_repository->index, pathspec, ce->name, ce_namelen(ce), @@ -364,9 +365,13 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, if (!info->quiet) printf(_("Entering '%s'\n"), displaypath); - if (info->argv[0] && run_command(&cp)) - die(_("run_command returned non-zero status for %s\n."), - displaypath); + if (info->argv[0]) { + if (run_command(&cp)) + die(_("run_command returned non-zero status for %s\n."), + displaypath); + } else { + child_process_clear(&cp); + } if (info->recursive) { struct child_process cpr = CHILD_PROCESS_INIT; @@ -395,7 +400,8 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, free(displaypath); } -static int module_foreach(int argc, const char **argv, const char *prefix) +static int module_foreach(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct foreach_cb info = FOREACH_CB_INIT; struct pathspec pathspec = { 0 }; @@ -540,7 +546,8 @@ static void init_submodule_cb(const struct cache_entry *list_item, void *cb_data info->flags); } -static int module_init(int argc, const char **argv, const char *prefix) +static int module_init(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct init_cb info = INIT_CB_INIT; struct pathspec pathspec = { 0 }; @@ -734,7 +741,8 @@ static void status_submodule_cb(const struct cache_entry *list_item, info->prefix, info->super_prefix, info->flags); } -static int module_status(int argc, const char **argv, const char *prefix) +static int module_status(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct status_cb info = STATUS_CB_INIT; struct pathspec pathspec = { 0 }; @@ -1159,7 +1167,8 @@ static int compute_summary_module_list(struct object_id *head_oid, return ret; } -static int module_summary(int argc, const char **argv, const char *prefix) +static int module_summary(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct summary_cb info = SUMMARY_CB_INIT; int cached = 0; @@ -1292,7 +1301,7 @@ static void sync_submodule(const char *path, const char *prefix, remote_key = xstrfmt("remote.%s.url", default_remote); free(default_remote); - submodule_to_gitdir(&sb, path); + submodule_to_gitdir(the_repository, &sb, path); strbuf_addstr(&sb, "/config"); if (git_config_set_in_file_gently(sb.buf, remote_key, NULL, sub_origin_url)) @@ -1335,7 +1344,8 @@ static void sync_submodule_cb(const struct cache_entry *list_item, void *cb_data info->flags); } -static int module_sync(int argc, const char **argv, const char *prefix) +static int module_sync(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct sync_cb info = SYNC_CB_INIT; struct pathspec pathspec = { 0 }; @@ -1481,7 +1491,8 @@ static void deinit_submodule_cb(const struct cache_entry *list_item, deinit_submodule(list_item->name, info->prefix, info->flags); } -static int module_deinit(int argc, const char **argv, const char *prefix) +static int module_deinit(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct deinit_cb info = DEINIT_CB_INIT; struct pathspec pathspec = { 0 }; @@ -1622,6 +1633,8 @@ static int add_possible_reference_from_superproject( ; /* nothing */ } } + + strbuf_release(&err); strbuf_release(&sb); } @@ -1813,7 +1826,7 @@ static int clone_submodule(const struct module_clone_data *clone_data, connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0); - p = git_pathdup_submodule(clone_data_path, "config"); + p = repo_submodule_path(the_repository, clone_data_path, "config"); if (!p) die(_("could not get submodule directory for '%s'"), clone_data_path); @@ -1836,7 +1849,8 @@ static int clone_submodule(const struct module_clone_data *clone_data, return 0; } -static int module_clone(int argc, const char **argv, const char *prefix) +static int module_clone(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int dissociate = 0, quiet = 0, progress = 0, require_init = 0; struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT; @@ -2026,6 +2040,7 @@ struct update_data { static void update_data_release(struct update_data *ud) { free(ud->displaypath); + submodule_update_strategy_release(&ud->update_strategy); module_list_release(&ud->list); } @@ -2326,7 +2341,14 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, strvec_pushf(&cp.args, "--depth=%d", depth); if (oid) { char *hex = oid_to_hex(oid); - char *remote = get_default_remote(); + char *remote; + int code; + + code = get_default_remote_submodule(module_path, &remote); + if (code) { + child_process_clear(&cp); + return code; + } strvec_pushl(&cp.args, remote, hex, NULL); free(remote); @@ -2646,15 +2668,20 @@ static int update_submodule(struct update_data *update_data) if (!update_data->nofetch) { if (fetch_in_submodule(update_data->sm_path, update_data->depth, - 0, NULL)) + 0, NULL)) { + free(remote_ref); return die_message(_("Unable to fetch in submodule path '%s'"), update_data->sm_path); + } } if (repo_resolve_gitlink_ref(the_repository, update_data->sm_path, - remote_ref, &update_data->oid)) - return die_message(_("Unable to find %s revision in submodule path '%s'"), - remote_ref, update_data->sm_path); + remote_ref, &update_data->oid)) { + ret = die_message(_("Unable to find %s revision in submodule path '%s'"), + remote_ref, update_data->sm_path); + free(remote_ref); + return ret; + } free(remote_ref); } @@ -2760,7 +2787,8 @@ static int update_submodules(struct update_data *update_data) return ret; } -static int module_update(int argc, const char **argv, const char *prefix) +static int module_update(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { struct pathspec pathspec = { 0 }; struct pathspec pathspec2 = { 0 }; @@ -2892,7 +2920,8 @@ static int module_update(int argc, const char **argv, const char *prefix) return ret; } -static int push_check(int argc, const char **argv, const char *prefix UNUSED) +static int push_check(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { struct remote *remote; const char *superproject_head; @@ -2972,7 +3001,8 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED) return 0; } -static int absorb_git_dirs(int argc, const char **argv, const char *prefix) +static int absorb_git_dirs(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int i; struct pathspec pathspec = { 0 }; @@ -3005,7 +3035,8 @@ static int absorb_git_dirs(int argc, const char **argv, const char *prefix) return ret; } -static int module_set_url(int argc, const char **argv, const char *prefix) +static int module_set_url(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int quiet = 0, ret; const char *newurl; @@ -3044,7 +3075,8 @@ static int module_set_url(int argc, const char **argv, const char *prefix) return !!ret; } -static int module_set_branch(int argc, const char **argv, const char *prefix) +static int module_set_branch(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int opt_default = 0, ret; const char *opt_branch = NULL; @@ -3094,7 +3126,8 @@ static int module_set_branch(int argc, const char **argv, const char *prefix) return !!ret; } -static int module_create_branch(int argc, const char **argv, const char *prefix) +static int module_create_branch(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { enum branch_track track; int quiet = 0, force = 0, reflog = 0, dry_run = 0; @@ -3364,7 +3397,6 @@ static void die_on_index_match(const char *path, int force) die(_("index file corrupt")); if (ps.nr) { - int i; char *ps_matched = xcalloc(ps.nr, 1); /* TODO: audit for interaction with sparse-index. */ @@ -3374,7 +3406,7 @@ static void die_on_index_match(const char *path, int force) * Since there is only one pathspec, we just need to * check ps_matched[0] to know if a cache entry matched. */ - for (i = 0; i < the_repository->index->cache_nr; i++) { + for (size_t i = 0; i < the_repository->index->cache_nr; i++) { ce_path_match(the_repository->index, the_repository->index->cache[i], &ps, ps_matched); @@ -3405,7 +3437,8 @@ static void die_on_repo_without_commits(const char *path) strbuf_release(&sb); } -static int module_add(int argc, const char **argv, const char *prefix) +static int module_add(int argc, const char **argv, const char *prefix, + struct repository *repo UNUSED) { int force = 0, quiet = 0, progress = 0, dissociate = 0; struct add_data add_data = ADD_DATA_INIT; @@ -3538,7 +3571,7 @@ static int module_add(int argc, const char **argv, const char *prefix) int cmd_submodule__helper(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; const char *const usage[] = { @@ -3564,5 +3597,5 @@ int cmd_submodule__helper(int argc, }; argc = parse_options(argc, argv, prefix, options, usage, 0); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/survey.c b/builtin/survey.c new file mode 100644 index 00000000000000..41a360a195f355 --- /dev/null +++ b/builtin/survey.c @@ -0,0 +1,937 @@ +/* + * This macro is necessary to access 'default_abbrev' + * within REV_INFO_INIT. + */ +#define USE_THE_REPOSITORY_VARIABLE + +#include "builtin.h" +#include "config.h" +#include "environment.h" +#include "hex.h" +#include "object.h" +#include "object-name.h" +#include "object-store-ll.h" +#include "parse-options.h" +#include "path-walk.h" +#include "progress.h" +#include "ref-filter.h" +#include "refs.h" +#include "revision.h" +#include "strbuf.h" +#include "strvec.h" +#include "tag.h" +#include "trace2.h" +#include "color.h" + +static const char * const survey_usage[] = { + N_("git survey [--[no-]progress] [--all-refs]\n" + " [--branches] [--tags] [--remotes] [--detached] [--other]"), + NULL, +}; + +struct survey_refs_wanted { + int want_all_refs; /* special override */ + + int want_branches; + int want_tags; + int want_remotes; + int want_detached; + int want_other; /* see FILTER_REFS_OTHERS -- refs/notes/, refs/stash/ */ +}; + +static struct survey_refs_wanted default_ref_options = { + .want_all_refs = 1, +}; + +struct survey_opts { + int verbose; + int show_progress; + int top_nr; + struct survey_refs_wanted refs; +}; + +struct survey_report_ref_summary { + size_t refs_nr; + size_t branches_nr; + size_t remote_refs_nr; + size_t tags_nr; + size_t tags_annotated_nr; + size_t others_nr; + size_t unknown_nr; +}; + +struct survey_report_object_summary { + size_t commits_nr; + size_t tags_nr; + size_t trees_nr; + size_t blobs_nr; +}; + +/** + * For some category given by 'label', count the number of objects + * that match that label along with the on-disk size and the size + * after decompressing (both with delta bases and zlib). + */ +struct survey_report_object_size_summary { + char *label; + size_t nr; + size_t disk_size; + size_t inflated_size; + size_t num_missing; +}; + +typedef int (*survey_top_cmp)(void *v1, void *v2); + +static int cmp_by_nr(void *v1, void *v2) +{ + struct survey_report_object_size_summary *s1 = v1; + struct survey_report_object_size_summary *s2 = v2; + + if (s1->nr < s2->nr) + return -1; + if (s1->nr > s2->nr) + return 1; + return 0; +} + +static int cmp_by_disk_size(void *v1, void *v2) +{ + struct survey_report_object_size_summary *s1 = v1; + struct survey_report_object_size_summary *s2 = v2; + + if (s1->disk_size < s2->disk_size) + return -1; + if (s1->disk_size > s2->disk_size) + return 1; + return 0; +} + +static int cmp_by_inflated_size(void *v1, void *v2) +{ + struct survey_report_object_size_summary *s1 = v1; + struct survey_report_object_size_summary *s2 = v2; + + if (s1->inflated_size < s2->inflated_size) + return -1; + if (s1->inflated_size > s2->inflated_size) + return 1; + return 0; +} + +/** + * Store a list of "top" categories by some sorting function. When + * inserting a new category, reorder the list and free the one that + * got ejected (if any). + */ +struct survey_report_top_table { + const char *name; + survey_top_cmp cmp_fn; + size_t nr; + size_t alloc; + + /** + * 'data' stores an array of structs and must be cast into + * the proper array type before evaluating an index. + */ + void *data; +}; + +static void init_top_sizes(struct survey_report_top_table *top, + size_t limit, const char *name, + survey_top_cmp cmp) +{ + struct survey_report_object_size_summary *sz_array; + + top->name = name; + top->cmp_fn = cmp; + top->alloc = limit; + top->nr = 0; + + CALLOC_ARRAY(sz_array, limit); + top->data = sz_array; +} + +MAYBE_UNUSED +static void clear_top_sizes(struct survey_report_top_table *top) +{ + struct survey_report_object_size_summary *sz_array = top->data; + + for (size_t i = 0; i < top->nr; i++) + free(sz_array[i].label); + free(sz_array); +} + +static void maybe_insert_into_top_size(struct survey_report_top_table *top, + struct survey_report_object_size_summary *summary) +{ + struct survey_report_object_size_summary *sz_array = top->data; + size_t pos = top->nr; + + /* Compare against list from the bottom. */ + while (pos > 0 && top->cmp_fn(&sz_array[pos - 1], summary) < 0) + pos--; + + /* Not big enough! */ + if (pos >= top->alloc) + return; + + /* We need to shift the data. */ + if (top->nr == top->alloc) + free(sz_array[top->nr - 1].label); + else + top->nr++; + + for (size_t i = top->nr - 1; i > pos; i--) + memcpy(&sz_array[i], &sz_array[i - 1], sizeof(*sz_array)); + + memcpy(&sz_array[pos], summary, sizeof(*summary)); + sz_array[pos].label = xstrdup(summary->label); +} + +/** + * This struct contains all of the information that needs to be printed + * at the end of the exploration of the repository and its references. + */ +struct survey_report { + struct survey_report_ref_summary refs; + struct survey_report_object_summary reachable_objects; + + struct survey_report_object_size_summary *by_type; + + struct survey_report_top_table *top_paths_by_count; + struct survey_report_top_table *top_paths_by_disk; + struct survey_report_top_table *top_paths_by_inflate; +}; + +#define REPORT_TYPE_COMMIT 0 +#define REPORT_TYPE_TREE 1 +#define REPORT_TYPE_BLOB 2 +#define REPORT_TYPE_TAG 3 +#define REPORT_TYPE_COUNT 4 + +struct survey_context { + struct repository *repo; + + /* Options that control what is done. */ + struct survey_opts opts; + + /* Info for output only. */ + struct survey_report report; + + /* + * The rest of the members are about enabling the activity + * of the 'git survey' command, including ref listings, object + * pointers, and progress. + */ + + struct progress *progress; + size_t progress_nr; + size_t progress_total; + + struct strvec refs; + struct ref_array ref_array; +}; + +static void clear_survey_context(struct survey_context *ctx) +{ + ref_array_clear(&ctx->ref_array); + strvec_clear(&ctx->refs); +} + +struct survey_table { + const char *table_name; + struct strvec header; + struct strvec *rows; + size_t rows_nr; + size_t rows_alloc; +}; + +#define SURVEY_TABLE_INIT { \ + .header = STRVEC_INIT, \ +} + +static void clear_table(struct survey_table *table) +{ + strvec_clear(&table->header); + for (size_t i = 0; i < table->rows_nr; i++) + strvec_clear(&table->rows[i]); + free(table->rows); +} + +static void insert_table_rowv(struct survey_table *table, ...) +{ + va_list ap; + char *arg; + ALLOC_GROW(table->rows, table->rows_nr + 1, table->rows_alloc); + + memset(&table->rows[table->rows_nr], 0, sizeof(struct strvec)); + + va_start(ap, table); + while ((arg = va_arg(ap, char *))) + strvec_push(&table->rows[table->rows_nr], arg); + va_end(ap); + + table->rows_nr++; +} + +#define SECTION_SEGMENT "========================================" +#define SECTION_SEGMENT_LEN 40 +static const char *section_line = SECTION_SEGMENT + SECTION_SEGMENT + SECTION_SEGMENT + SECTION_SEGMENT; +static const size_t section_len = 4 * SECTION_SEGMENT_LEN; + +static void print_table_title(const char *name, size_t *widths, size_t nr) +{ + size_t width = 3 * (nr - 1); + size_t min_width = strlen(name); + + for (size_t i = 0; i < nr; i++) + width += widths[i]; + + if (width < min_width) + width = min_width; + + if (width > section_len) + width = section_len; + + printf("\n%s\n%.*s\n", name, (int)width, section_line); +} + +static void print_row_plaintext(struct strvec *row, size_t *widths) +{ + static struct strbuf line = STRBUF_INIT; + strbuf_setlen(&line, 0); + + for (size_t i = 0; i < row->nr; i++) { + const char *str = row->v[i]; + size_t len = strlen(str); + if (i) + strbuf_add(&line, " | ", 3); + strbuf_addchars(&line, ' ', widths[i] - len); + strbuf_add(&line, str, len); + } + printf("%s\n", line.buf); +} + +static void print_divider_plaintext(size_t *widths, size_t nr) +{ + static struct strbuf line = STRBUF_INIT; + strbuf_setlen(&line, 0); + + for (size_t i = 0; i < nr; i++) { + if (i) + strbuf_add(&line, "-+-", 3); + strbuf_addchars(&line, '-', widths[i]); + } + printf("%s\n", line.buf); +} + +static void print_table_plaintext(struct survey_table *table) +{ + size_t *column_widths; + size_t columns_nr = table->header.nr; + CALLOC_ARRAY(column_widths, columns_nr); + + for (size_t i = 0; i < columns_nr; i++) { + column_widths[i] = strlen(table->header.v[i]); + + for (size_t j = 0; j < table->rows_nr; j++) { + size_t rowlen = strlen(table->rows[j].v[i]); + if (column_widths[i] < rowlen) + column_widths[i] = rowlen; + } + } + + print_table_title(table->table_name, column_widths, columns_nr); + print_row_plaintext(&table->header, column_widths); + print_divider_plaintext(column_widths, columns_nr); + + for (size_t j = 0; j < table->rows_nr; j++) + print_row_plaintext(&table->rows[j], column_widths); + + free(column_widths); +} + +static void survey_report_plaintext_refs(struct survey_context *ctx) +{ + struct survey_report_ref_summary *refs = &ctx->report.refs; + struct survey_table table = SURVEY_TABLE_INIT; + + table.table_name = _("REFERENCES SUMMARY"); + + strvec_push(&table.header, _("Ref Type")); + strvec_push(&table.header, _("Count")); + + if (ctx->opts.refs.want_all_refs || ctx->opts.refs.want_branches) { + char *fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)refs->branches_nr); + insert_table_rowv(&table, _("Branches"), fmt, NULL); + free(fmt); + } + + if (ctx->opts.refs.want_all_refs || ctx->opts.refs.want_remotes) { + char *fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)refs->remote_refs_nr); + insert_table_rowv(&table, _("Remote refs"), fmt, NULL); + free(fmt); + } + + if (ctx->opts.refs.want_all_refs || ctx->opts.refs.want_tags) { + char *fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)refs->tags_nr); + insert_table_rowv(&table, _("Tags (all)"), fmt, NULL); + free(fmt); + fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)refs->tags_annotated_nr); + insert_table_rowv(&table, _("Tags (annotated)"), fmt, NULL); + free(fmt); + } + + print_table_plaintext(&table); + clear_table(&table); +} + +static void survey_report_plaintext_reachable_object_summary(struct survey_context *ctx) +{ + struct survey_report_object_summary *objs = &ctx->report.reachable_objects; + struct survey_table table = SURVEY_TABLE_INIT; + char *fmt; + + table.table_name = _("REACHABLE OBJECT SUMMARY"); + + strvec_push(&table.header, _("Object Type")); + strvec_push(&table.header, _("Count")); + + fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)objs->tags_nr); + insert_table_rowv(&table, _("Tags"), fmt, NULL); + free(fmt); + + fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)objs->commits_nr); + insert_table_rowv(&table, _("Commits"), fmt, NULL); + free(fmt); + + fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)objs->trees_nr); + insert_table_rowv(&table, _("Trees"), fmt, NULL); + free(fmt); + + fmt = xstrfmt("%"PRIuMAX"", (uintmax_t)objs->blobs_nr); + insert_table_rowv(&table, _("Blobs"), fmt, NULL); + free(fmt); + + print_table_plaintext(&table); + clear_table(&table); +} + +static void survey_report_object_sizes(const char *title, + const char *categories, + struct survey_report_object_size_summary *summary, + size_t summary_nr) +{ + struct survey_table table = SURVEY_TABLE_INIT; + table.table_name = title; + + strvec_push(&table.header, categories); + strvec_push(&table.header, _("Count")); + strvec_push(&table.header, _("Disk Size")); + strvec_push(&table.header, _("Inflated Size")); + + for (size_t i = 0; i < summary_nr; i++) { + char *label_str = xstrdup(summary[i].label); + char *nr_str = xstrfmt("%"PRIuMAX, (uintmax_t)summary[i].nr); + char *disk_str = xstrfmt("%"PRIuMAX, (uintmax_t)summary[i].disk_size); + char *inflate_str = xstrfmt("%"PRIuMAX, (uintmax_t)summary[i].inflated_size); + + insert_table_rowv(&table, label_str, nr_str, + disk_str, inflate_str, NULL); + + free(label_str); + free(nr_str); + free(disk_str); + free(inflate_str); + } + + print_table_plaintext(&table); + clear_table(&table); +} + +static void survey_report_plaintext_sorted_size( + struct survey_report_top_table *top) +{ + survey_report_object_sizes(top->name, _("Path"), + top->data, top->nr); +} + +static void survey_report_plaintext(struct survey_context *ctx) +{ + printf("GIT SURVEY for \"%s\"\n", ctx->repo->worktree); + printf("-----------------------------------------------------\n"); + survey_report_plaintext_refs(ctx); + survey_report_plaintext_reachable_object_summary(ctx); + survey_report_object_sizes(_("TOTAL OBJECT SIZES BY TYPE"), + _("Object Type"), + ctx->report.by_type, + REPORT_TYPE_COUNT); + + survey_report_plaintext_sorted_size( + &ctx->report.top_paths_by_count[REPORT_TYPE_TREE]); + survey_report_plaintext_sorted_size( + &ctx->report.top_paths_by_count[REPORT_TYPE_BLOB]); + + survey_report_plaintext_sorted_size( + &ctx->report.top_paths_by_disk[REPORT_TYPE_TREE]); + survey_report_plaintext_sorted_size( + &ctx->report.top_paths_by_disk[REPORT_TYPE_BLOB]); + + survey_report_plaintext_sorted_size( + &ctx->report.top_paths_by_inflate[REPORT_TYPE_TREE]); + survey_report_plaintext_sorted_size( + &ctx->report.top_paths_by_inflate[REPORT_TYPE_BLOB]); +} + +/* + * After parsing the command line arguments, figure out which refs we + * should scan. + * + * If ANY were given in positive sense, then we ONLY include them and + * do not use the builtin values. + */ +static void fixup_refs_wanted(struct survey_context *ctx) +{ + struct survey_refs_wanted *rw = &ctx->opts.refs; + + /* + * `--all-refs` overrides and enables everything. + */ + if (rw->want_all_refs == 1) { + rw->want_branches = 1; + rw->want_tags = 1; + rw->want_remotes = 1; + rw->want_detached = 1; + rw->want_other = 1; + return; + } + + /* + * If none of the `--<ref-type>` were given, we assume all + * of the builtin unspecified values. + */ + if (rw->want_branches == -1 && + rw->want_tags == -1 && + rw->want_remotes == -1 && + rw->want_detached == -1 && + rw->want_other == -1) { + *rw = default_ref_options; + return; + } + + /* + * Since we only allow positive boolean values on the command + * line, we will only have true values where they specified + * a `--<ref-type>`. + * + * So anything that still has an unspecified value should be + * set to false. + */ + if (rw->want_branches == -1) + rw->want_branches = 0; + if (rw->want_tags == -1) + rw->want_tags = 0; + if (rw->want_remotes == -1) + rw->want_remotes = 0; + if (rw->want_detached == -1) + rw->want_detached = 0; + if (rw->want_other == -1) + rw->want_other = 0; +} + +static int survey_load_config_cb(const char *var, const char *value, + const struct config_context *cctx, void *pvoid) +{ + struct survey_context *ctx = pvoid; + + if (!strcmp(var, "survey.verbose")) { + ctx->opts.verbose = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "survey.progress")) { + ctx->opts.show_progress = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "survey.top")) { + ctx->opts.top_nr = git_config_bool(var, value); + return 0; + } + + return git_default_config(var, value, cctx, pvoid); +} + +static void survey_load_config(struct survey_context *ctx) +{ + repo_config(ctx->repo, survey_load_config_cb, ctx); +} + +static void do_load_refs(struct survey_context *ctx, + struct ref_array *ref_array) +{ + struct ref_filter filter = REF_FILTER_INIT; + struct ref_sorting *sorting; + struct string_list sorting_options = STRING_LIST_INIT_DUP; + + string_list_append(&sorting_options, "objectname"); + sorting = ref_sorting_options(&sorting_options); + + if (ctx->opts.refs.want_detached) + strvec_push(&ctx->refs, "HEAD"); + + if (ctx->opts.refs.want_all_refs) { + strvec_push(&ctx->refs, "refs/"); + } else { + if (ctx->opts.refs.want_branches) + strvec_push(&ctx->refs, "refs/heads/"); + if (ctx->opts.refs.want_tags) + strvec_push(&ctx->refs, "refs/tags/"); + if (ctx->opts.refs.want_remotes) + strvec_push(&ctx->refs, "refs/remotes/"); + if (ctx->opts.refs.want_other) { + strvec_push(&ctx->refs, "refs/notes/"); + strvec_push(&ctx->refs, "refs/stash/"); + } + } + + filter.name_patterns = ctx->refs.v; + filter.ignore_case = 0; + filter.match_as_path = 1; + + if (ctx->opts.show_progress) { + ctx->progress_total = 0; + ctx->progress = start_progress(ctx->repo, _("Scanning refs..."), 0); + } + + filter_refs(ref_array, &filter, FILTER_REFS_KIND_MASK); + + if (ctx->opts.show_progress) { + ctx->progress_total = ref_array->nr; + display_progress(ctx->progress, ctx->progress_total); + } + + ref_array_sort(sorting, ref_array); + + stop_progress(&ctx->progress); + ref_filter_clear(&filter); + ref_sorting_release(sorting); +} + +/* + * The REFS phase: + * + * Load the set of requested refs and assess them for scalablity problems. + * Use that set to start a treewalk to all reachable objects and assess + * them. + * + * This data will give us insights into the repository itself (the number + * of refs, the size and shape of the DAG, the number and size of the + * objects). + * + * Theoretically, this data is independent of the on-disk representation + * (e.g. independent of packing concerns). + */ +static void survey_phase_refs(struct survey_context *ctx) +{ + trace2_region_enter("survey", "phase/refs", ctx->repo); + do_load_refs(ctx, &ctx->ref_array); + + ctx->report.refs.refs_nr = ctx->ref_array.nr; + for (int i = 0; i < ctx->ref_array.nr; i++) { + unsigned long size; + struct ref_array_item *item = ctx->ref_array.items[i]; + + switch (item->kind) { + case FILTER_REFS_TAGS: + ctx->report.refs.tags_nr++; + if (oid_object_info(ctx->repo, + &item->objectname, + &size) == OBJ_TAG) + ctx->report.refs.tags_annotated_nr++; + break; + + case FILTER_REFS_BRANCHES: + ctx->report.refs.branches_nr++; + break; + + case FILTER_REFS_REMOTES: + ctx->report.refs.remote_refs_nr++; + break; + + case FILTER_REFS_OTHERS: + ctx->report.refs.others_nr++; + break; + + default: + ctx->report.refs.unknown_nr++; + break; + } + } + + trace2_region_leave("survey", "phase/refs", ctx->repo); +} + +static void increment_object_counts( + struct survey_report_object_summary *summary, + enum object_type type, + size_t nr) +{ + switch (type) { + case OBJ_COMMIT: + summary->commits_nr += nr; + break; + + case OBJ_TREE: + summary->trees_nr += nr; + break; + + case OBJ_BLOB: + summary->blobs_nr += nr; + break; + + case OBJ_TAG: + summary->tags_nr += nr; + break; + + default: + break; + } +} + +static void increment_totals(struct survey_context *ctx, + struct oid_array *oids, + struct survey_report_object_size_summary *summary) +{ + for (size_t i = 0; i < oids->nr; i++) { + struct object_info oi = OBJECT_INFO_INIT; + unsigned oi_flags = OBJECT_INFO_FOR_PREFETCH; + unsigned long object_length = 0; + off_t disk_sizep = 0; + enum object_type type; + + oi.typep = &type; + oi.sizep = &object_length; + oi.disk_sizep = &disk_sizep; + + if (oid_object_info_extended(ctx->repo, &oids->oid[i], + &oi, oi_flags) < 0) { + summary->num_missing++; + } else { + summary->nr++; + summary->disk_size += disk_sizep; + summary->inflated_size += object_length; + } + } +} + +static void increment_object_totals(struct survey_context *ctx, + struct oid_array *oids, + enum object_type type, + const char *path) +{ + struct survey_report_object_size_summary *total; + struct survey_report_object_size_summary summary = { 0 }; + + increment_totals(ctx, oids, &summary); + + switch (type) { + case OBJ_COMMIT: + total = &ctx->report.by_type[REPORT_TYPE_COMMIT]; + break; + + case OBJ_TREE: + total = &ctx->report.by_type[REPORT_TYPE_TREE]; + break; + + case OBJ_BLOB: + total = &ctx->report.by_type[REPORT_TYPE_BLOB]; + break; + + case OBJ_TAG: + total = &ctx->report.by_type[REPORT_TYPE_TAG]; + break; + + default: + BUG("No other type allowed"); + } + + total->nr += summary.nr; + total->disk_size += summary.disk_size; + total->inflated_size += summary.inflated_size; + total->num_missing += summary.num_missing; + + if (type == OBJ_TREE || type == OBJ_BLOB) { + int index = type == OBJ_TREE ? + REPORT_TYPE_TREE : REPORT_TYPE_BLOB; + struct survey_report_top_table *top; + + /* + * Temporarily store (const char *) here, but it will + * be duped if inserted and will not be freed. + */ + summary.label = (char *)path; + + top = ctx->report.top_paths_by_count; + maybe_insert_into_top_size(&top[index], &summary); + + top = ctx->report.top_paths_by_disk; + maybe_insert_into_top_size(&top[index], &summary); + + top = ctx->report.top_paths_by_inflate; + maybe_insert_into_top_size(&top[index], &summary); + } +} + +static int survey_objects_path_walk_fn(const char *path, + struct oid_array *oids, + enum object_type type, + void *data) +{ + struct survey_context *ctx = data; + + increment_object_counts(&ctx->report.reachable_objects, + type, oids->nr); + increment_object_totals(ctx, oids, type, path); + + ctx->progress_nr += oids->nr; + display_progress(ctx->progress, ctx->progress_nr); + + return 0; +} + +static void initialize_report(struct survey_context *ctx) +{ + CALLOC_ARRAY(ctx->report.by_type, REPORT_TYPE_COUNT); + ctx->report.by_type[REPORT_TYPE_COMMIT].label = xstrdup(_("Commits")); + ctx->report.by_type[REPORT_TYPE_TREE].label = xstrdup(_("Trees")); + ctx->report.by_type[REPORT_TYPE_BLOB].label = xstrdup(_("Blobs")); + ctx->report.by_type[REPORT_TYPE_TAG].label = xstrdup(_("Tags")); + + CALLOC_ARRAY(ctx->report.top_paths_by_count, REPORT_TYPE_COUNT); + init_top_sizes(&ctx->report.top_paths_by_count[REPORT_TYPE_TREE], + ctx->opts.top_nr, _("TOP DIRECTORIES BY COUNT"), cmp_by_nr); + init_top_sizes(&ctx->report.top_paths_by_count[REPORT_TYPE_BLOB], + ctx->opts.top_nr, _("TOP FILES BY COUNT"), cmp_by_nr); + + CALLOC_ARRAY(ctx->report.top_paths_by_disk, REPORT_TYPE_COUNT); + init_top_sizes(&ctx->report.top_paths_by_disk[REPORT_TYPE_TREE], + ctx->opts.top_nr, _("TOP DIRECTORIES BY DISK SIZE"), cmp_by_disk_size); + init_top_sizes(&ctx->report.top_paths_by_disk[REPORT_TYPE_BLOB], + ctx->opts.top_nr, _("TOP FILES BY DISK SIZE"), cmp_by_disk_size); + + CALLOC_ARRAY(ctx->report.top_paths_by_inflate, REPORT_TYPE_COUNT); + init_top_sizes(&ctx->report.top_paths_by_inflate[REPORT_TYPE_TREE], + ctx->opts.top_nr, _("TOP DIRECTORIES BY INFLATED SIZE"), cmp_by_inflated_size); + init_top_sizes(&ctx->report.top_paths_by_inflate[REPORT_TYPE_BLOB], + ctx->opts.top_nr, _("TOP FILES BY INFLATED SIZE"), cmp_by_inflated_size); +} + +static void survey_phase_objects(struct survey_context *ctx) +{ + struct rev_info revs = REV_INFO_INIT; + struct path_walk_info info = PATH_WALK_INFO_INIT; + unsigned int add_flags = 0; + + trace2_region_enter("survey", "phase/objects", ctx->repo); + + info.revs = &revs; + info.path_fn = survey_objects_path_walk_fn; + info.path_fn_data = ctx; + + initialize_report(ctx); + + repo_init_revisions(ctx->repo, &revs, ""); + revs.tag_objects = 1; + + ctx->progress_nr = 0; + ctx->progress_total = ctx->ref_array.nr; + if (ctx->opts.show_progress) + ctx->progress = start_progress(ctx->repo, + _("Preparing object walk"), + ctx->progress_total); + for (int i = 0; i < ctx->ref_array.nr; i++) { + struct ref_array_item *item = ctx->ref_array.items[i]; + add_pending_oid(&revs, NULL, &item->objectname, add_flags); + display_progress(ctx->progress, ++(ctx->progress_nr)); + } + stop_progress(&ctx->progress); + + ctx->progress_nr = 0; + ctx->progress_total = 0; + if (ctx->opts.show_progress) + ctx->progress = start_progress(ctx->repo, + _("Walking objects"), 0); + walk_objects_by_path(&info); + stop_progress(&ctx->progress); + + release_revisions(&revs); + trace2_region_leave("survey", "phase/objects", ctx->repo); +} + +int cmd_survey(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + static struct survey_context ctx = { + .opts = { + .verbose = 0, + .show_progress = -1, /* defaults to isatty(2) */ + .top_nr = 100, + + .refs.want_all_refs = -1, + + .refs.want_branches = -1, /* default these to undefined */ + .refs.want_tags = -1, + .refs.want_remotes = -1, + .refs.want_detached = -1, + .refs.want_other = -1, + }, + .refs = STRVEC_INIT, + }; + + static struct option survey_options[] = { + OPT__VERBOSE(&ctx.opts.verbose, N_("verbose output")), + OPT_BOOL(0, "progress", &ctx.opts.show_progress, N_("show progress")), + OPT_INTEGER('n', "top", &ctx.opts.top_nr, + N_("number of entries to include in detail tables")), + + OPT_BOOL_F(0, "all-refs", &ctx.opts.refs.want_all_refs, N_("include all refs"), PARSE_OPT_NONEG), + + OPT_BOOL_F(0, "branches", &ctx.opts.refs.want_branches, N_("include branches"), PARSE_OPT_NONEG), + OPT_BOOL_F(0, "tags", &ctx.opts.refs.want_tags, N_("include tags"), PARSE_OPT_NONEG), + OPT_BOOL_F(0, "remotes", &ctx.opts.refs.want_remotes, N_("include all remotes refs"), PARSE_OPT_NONEG), + OPT_BOOL_F(0, "detached", &ctx.opts.refs.want_detached, N_("include detached HEAD"), PARSE_OPT_NONEG), + OPT_BOOL_F(0, "other", &ctx.opts.refs.want_other, N_("include notes and stashes"), PARSE_OPT_NONEG), + + OPT_END(), + }; + + show_usage_with_options_if_asked(argc, argv, survey_usage, survey_options); + + if (isatty(2)) + color_fprintf_ln(stderr, + want_color_fd(2, GIT_COLOR_AUTO) ? GIT_COLOR_YELLOW : "", + "(THIS IS EXPERIMENTAL, EXPECT THE OUTPUT FORMAT TO CHANGE!)"); + + ctx.repo = repo; + + prepare_repo_settings(ctx.repo); + survey_load_config(&ctx); + + argc = parse_options(argc, argv, prefix, survey_options, survey_usage, 0); + + if (ctx.opts.show_progress < 0) + ctx.opts.show_progress = isatty(2); + + fixup_refs_wanted(&ctx); + + survey_phase_refs(&ctx); + + survey_phase_objects(&ctx); + + survey_report_plaintext(&ctx); + + clear_survey_context(&ctx); + return 0; +} diff --git a/builtin/tag.c b/builtin/tag.c index 93d10d59157d2e..d3e0943b734759 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -5,7 +5,10 @@ * Carlos Rica <jasampler@gmail.com> * Based on git-tag.sh and mktag.c by Linus Torvalds. */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "advice.h" #include "config.h" @@ -164,7 +167,7 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid, int ret = -1; if (sign_buffer(buffer, &sig, keyid)) - return -1; + goto out; if (compat) { const struct git_hash_algo *algo = the_repository->hash_algo; @@ -447,17 +450,6 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) return 0; } -static int strbuf_check_tag_ref(struct strbuf *sb, const char *name) -{ - if (name[0] == '-') - return -1; - - strbuf_reset(sb); - strbuf_addf(sb, "refs/tags/%s", name); - - return check_refname_format(sb->buf, 0); -} - int cmd_tag(int argc, const char **argv, const char *prefix, @@ -650,7 +642,7 @@ int cmd_tag(int argc, if (repo_get_oid(the_repository, object_ref, &object)) die(_("Failed to resolve '%s' as a valid ref."), object_ref); - if (strbuf_check_tag_ref(&ref, tag)) + if (check_tag_ref(&ref, tag)) die(_("'%s' is not a valid tag name."), tag); if (refs_read_ref(get_main_ref_store(the_repository), ref.buf, &prev)) @@ -675,13 +667,13 @@ int cmd_tag(int argc, if (create_tag_object) { if (force_sign_annotate && !annotate) opt.sign = 1; - path = git_pathdup("TAG_EDITMSG"); + path = repo_git_path(the_repository, "TAG_EDITMSG"); create_tag(&object, object_ref, tag, &buf, &opt, &prev, &object, &trailer_args, path); } transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction || ref_transaction_update(transaction, ref.buf, &object, &prev, NULL, NULL, @@ -706,7 +698,6 @@ int cmd_tag(int argc, cleanup: ref_sorting_release(sorting); ref_filter_clear(&filter); - ref_format_clear(&format); strbuf_release(&buf); strbuf_release(&ref); strbuf_release(&reflog_msg); diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index 6da282575391b9..fb5fcbc40a86d6 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -26,6 +26,9 @@ static char *create_temp_file(struct object_id *oid) return path; } +static const char usage_msg[] = +"git unpack-file <blob>"; + int cmd_unpack_file(int argc, const char **argv, const char *prefix UNUSED, @@ -33,8 +36,9 @@ int cmd_unpack_file(int argc, { struct object_id oid; - if (argc != 2 || !strcmp(argv[1], "-h")) - usage("git unpack-file <blob>"); + show_usage_if_asked(argc, argv, usage_msg); + if (argc != 2) + usage(usage_msg); if (repo_get_oid(the_repository, argv[1], &oid)) die("Not a valid object name %s", argv[1]); diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 02b8d02f63f0a2..8383bcf404957d 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "bulk-checkin.h" #include "config.h" @@ -16,6 +18,7 @@ #include "progress.h" #include "decorate.h" #include "fsck.h" +#include "packfile.h" static int dry_run, quiet, recover, has_errors, strict; static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]"; @@ -25,7 +28,7 @@ static unsigned char buffer[4096]; static unsigned int offset, len; static off_t consumed_bytes; static off_t max_input_size; -static git_hash_ctx ctx; +static struct git_hash_ctx ctx; static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT; static struct progress *progress; @@ -67,7 +70,7 @@ static void *fill(int min) if (min > sizeof(buffer)) die("cannot fill %d bytes", min); if (offset) { - the_hash_algo->update_fn(&ctx, buffer, offset); + git_hash_update(&ctx, buffer, offset); memmove(buffer, buffer + offset, len); offset = 0; } @@ -576,19 +579,21 @@ static void unpack_one(unsigned nr) static void unpack_all(void) { int i; - struct pack_header *hdr = fill(sizeof(struct pack_header)); - - nr_objects = ntohl(hdr->hdr_entries); + unsigned char *hdr = fill(sizeof(struct pack_header)); - if (ntohl(hdr->hdr_signature) != PACK_SIGNATURE) + if (get_be32(hdr) != PACK_SIGNATURE) die("bad pack file"); - if (!pack_version_ok(hdr->hdr_version)) + hdr += 4; + if (!pack_version_ok_native(get_be32(hdr))) die("unknown pack file version %"PRIu32, - ntohl(hdr->hdr_version)); + get_be32(hdr)); + hdr += 4; + nr_objects = get_be32(hdr); use(sizeof(struct pack_header)); if (!quiet) - progress = start_progress(_("Unpacking objects"), nr_objects); + progress = start_progress(the_repository, + _("Unpacking objects"), nr_objects); CALLOC_ARRAY(obj_list, nr_objects); begin_odb_transaction(); for (i = 0; i < nr_objects; i++) { @@ -609,7 +614,7 @@ int cmd_unpack_objects(int argc, { int i; struct object_id oid; - git_hash_ctx tmp_ctx; + struct git_hash_ctx tmp_ctx; disable_replace_refs(); @@ -617,6 +622,8 @@ int cmd_unpack_objects(int argc, quiet = !isatty(2); + show_usage_if_asked(argc, argv, unpack_usage); + for (i = 1 ; i < argc; i++) { const char *arg = argv[i]; @@ -642,19 +649,10 @@ int cmd_unpack_objects(int argc, fsck_set_msg_types(&fsck_options, arg); continue; } - if (starts_with(arg, "--pack_header=")) { - struct pack_header *hdr; - char *c; - - hdr = (struct pack_header *)buffer; - hdr->hdr_signature = htonl(PACK_SIGNATURE); - hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10)); - if (*c != ',') - die("bad %s", arg); - hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10)); - if (*c) - die("bad %s", arg); - len = sizeof(*hdr); + if (skip_prefix(arg, "--pack_header=", &arg)) { + if (parse_pack_header_option(arg, + buffer, &len) < 0) + die(_("bad --pack_header: %s"), arg); continue; } if (skip_prefix(arg, "--max-input-size=", &arg)) { @@ -669,10 +667,9 @@ int cmd_unpack_objects(int argc, } the_hash_algo->init_fn(&ctx); unpack_all(); - the_hash_algo->update_fn(&ctx, buffer, offset); - the_hash_algo->init_fn(&tmp_ctx); - the_hash_algo->clone_fn(&tmp_ctx, &ctx); - the_hash_algo->final_oid_fn(&oid, &tmp_ctx); + git_hash_update(&ctx, buffer, offset); + git_hash_clone(&tmp_ctx, &ctx); + git_hash_final_oid(&oid, &tmp_ctx); if (strict) { write_rest(); if (fsck_finish(&fsck_options)) diff --git a/builtin/update-index.c b/builtin/update-index.c index 45b4a8b5556e08..b2f6b1a3fbb6cd 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -3,7 +3,10 @@ * * Copyright (C) Linus Torvalds, 2005 */ + #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "bulk-checkin.h" #include "config.h" @@ -1042,8 +1045,8 @@ int cmd_update_index(int argc, OPT_END() }; - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(update_index_usage, options); + show_usage_with_options_if_asked(argc, argv, + update_index_usage, options); git_config(git_default_config, NULL); diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 8a98615dc8613a..4d35bdc4b4b579 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "config.h" #include "gettext.h" @@ -612,7 +614,7 @@ static void update_refs_stdin(void) int i, j; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) die("%s", err.buf); @@ -680,7 +682,7 @@ static void update_refs_stdin(void) */ state = cmd->state; transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) die("%s", err.buf); diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index 6769611a025d0d..d7467290a84f99 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -13,7 +12,7 @@ static const char * const update_server_info_usage[] = { int cmd_update_server_info(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { int force = 0; struct option options[] = { @@ -21,11 +20,12 @@ int cmd_update_server_info(int argc, OPT_END() }; - git_config(git_default_config, NULL); + if (repo) + repo_config(repo, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, update_server_info_usage, 0); if (argc > 0) usage_with_options(update_server_info_usage, options); - return !!update_server_info(force); + return !!update_server_info(repo, force); } diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 9e9343f1213be7..97d7c9522f9868 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -27,7 +27,8 @@ int cmd_upload_archive_writer(int argc, const char *arg_cmd = "argument "; int ret; - if (argc != 2 || !strcmp(argv[1], "-h")) + show_usage_if_asked(argc, argv, upload_archive_usage); + if (argc != 2) usage(upload_archive_usage); if (!enter_repo(argv[1], 0)) @@ -92,8 +93,7 @@ struct repository *repo UNUSED) BUG_ON_NON_EMPTY_PREFIX(prefix); - if (argc == 2 && !strcmp(argv[1], "-h")) - usage(upload_archive_usage); + show_usage_if_asked(argc, argv, upload_archive_usage); /* * Set up sideband subprocess. diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c index 3b6c83fbce3684..c2bbc035ab0c91 100644 --- a/builtin/upload-pack.c +++ b/builtin/upload-pack.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "exec-cmd.h" #include "gettext.h" @@ -39,6 +41,7 @@ int cmd_upload_pack(int argc, N_("interrupt transfer after <n> seconds of inactivity")), OPT_END() }; + unsigned enter_repo_flags = ENTER_REPO_ANY_OWNER_OK; packet_trace_identity("upload-pack"); disable_replace_refs(); @@ -54,15 +57,17 @@ int cmd_upload_pack(int argc, dir = argv[0]; - if (!enter_repo(dir, strict)) + if (strict) + enter_repo_flags |= ENTER_REPO_STRICT; + if (!enter_repo(dir, enter_repo_flags)) die("'%s' does not appear to be a git repository", dir); switch (determine_protocol_version_server()) { case protocol_v2: if (advertise_refs) - protocol_v2_advertise_capabilities(); + protocol_v2_advertise_capabilities(the_repository); else - protocol_v2_serve_loop(stateless_rpc); + protocol_v2_serve_loop(the_repository, stateless_rpc); break; case protocol_v1: /* diff --git a/builtin/var.c b/builtin/var.c index 2ecaed51b44196..ada642a9fe5257 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -3,7 +3,9 @@ * * Copyright (C) Eric Biederman, 2005 */ + #define USE_THE_REPOSITORY_VARIABLE + #include "builtin.h" #include "attr.h" @@ -40,7 +42,7 @@ static char *sequence_editor(int ident_flag UNUSED) static char *pager(int ident_flag UNUSED) { - const char *pgm = git_pager(1); + const char *pgm = git_pager(the_repository, 1); if (!pgm) pgm = "cat"; @@ -178,10 +180,9 @@ static void list_vars(void) if ((val = ptr->read(0))) { if (ptr->multivalued && *val) { struct string_list list = STRING_LIST_INIT_DUP; - int i; string_list_split(&list, val, '\n', -1); - for (i = 0; i < list.nr; i++) + for (size_t i = 0; i < list.nr; i++) printf("%s=%s\n", ptr->name, list.items[i].string); string_list_clear(&list, 0); } else { @@ -220,6 +221,7 @@ int cmd_var(int argc, const struct git_var *git_var; char *val; + show_usage_if_asked(argc, argv, var_usage); if (argc != 2) usage(var_usage); diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index a7f20618ffd528..f6b97048a57d37 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -69,6 +69,5 @@ int cmd_verify_tag(int argc, if (format.format) pretty_print_ref(name, &oid, &format); } - ref_format_clear(&format); return had_error; } diff --git a/builtin/worktree.c b/builtin/worktree.c index fc31d072a620d7..48448a83550944 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -1,4 +1,6 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "builtin.h" #include "abspath.h" #include "advice.h" @@ -120,12 +122,14 @@ struct add_opts { int quiet; int checkout; int orphan; + int relative_paths; const char *keep_locked; }; static int show_only; static int verbose; static int guess_remote; +static int use_relative_paths; static timestamp_t expire; static int git_worktree_config(const char *var, const char *value, @@ -134,6 +138,9 @@ static int git_worktree_config(const char *var, const char *value, if (!strcmp(var, "worktree.guessremote")) { guess_remote = git_config_bool(var, value); return 0; + } else if (!strcmp(var, "worktree.userelativepaths")) { + use_relative_paths = git_config_bool(var, value); + return 0; } return git_default_config(var, value, ctx, cb); @@ -144,7 +151,7 @@ static int delete_git_dir(const char *id) struct strbuf sb = STRBUF_INIT; int ret; - strbuf_addstr(&sb, git_common_path("worktrees/%s", id)); + repo_common_path_append(the_repository, &sb, "worktrees/%s", id); ret = remove_dir_recursively(&sb, 0); if (ret < 0 && errno == ENOTDIR) ret = unlink(sb.buf); @@ -156,7 +163,9 @@ static int delete_git_dir(const char *id) static void delete_worktrees_dir_if_empty(void) { - rmdir(git_path("worktrees")); /* ignore failed removal */ + char *path = repo_git_path(the_repository, "worktrees"); + rmdir(path); /* ignore failed removal */ + free(path); } static void prune_worktree(const char *id, const char *reason) @@ -205,8 +214,13 @@ static void prune_worktrees(void) struct strbuf reason = STRBUF_INIT; struct strbuf main_path = STRBUF_INIT; struct string_list kept = STRING_LIST_INIT_DUP; - DIR *dir = opendir(git_path("worktrees")); + char *path; + DIR *dir; struct dirent *d; + + path = repo_git_path(the_repository, "worktrees"); + dir = opendir(path); + free(path); if (!dir) return; while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) { @@ -231,7 +245,8 @@ static void prune_worktrees(void) strbuf_release(&reason); } -static int prune(int ac, const char **av, const char *prefix) +static int prune(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT__DRY_RUN(&show_only, N_("do not remove, show only")), @@ -329,7 +344,7 @@ static void check_candidate_path(const char *path, static void copy_sparse_checkout(const char *worktree_git_dir) { - char *from_file = git_pathdup("info/sparse-checkout"); + char *from_file = repo_git_path(the_repository, "info/sparse-checkout"); char *to_file = xstrfmt("%s/info/sparse-checkout", worktree_git_dir); if (file_exists(from_file)) { @@ -345,7 +360,7 @@ static void copy_sparse_checkout(const char *worktree_git_dir) static void copy_filtered_worktree_config(const char *worktree_git_dir) { - char *from_file = git_pathdup("config.worktree"); + char *from_file = repo_git_path(the_repository, "config.worktree"); char *to_file = xstrfmt("%s/config.worktree", worktree_git_dir); if (file_exists(from_file)) { @@ -414,7 +429,7 @@ static int add_worktree(const char *path, const char *refname, const struct add_opts *opts) { struct strbuf sb_git = STRBUF_INIT, sb_repo = STRBUF_INIT; - struct strbuf sb = STRBUF_INIT, realpath = STRBUF_INIT; + struct strbuf sb = STRBUF_INIT; const char *name; struct strvec child_env = STRVEC_INIT; unsigned int counter = 0; @@ -432,7 +447,7 @@ static int add_worktree(const char *path, const char *refname, worktrees = NULL; /* is 'refname' a branch or commit? */ - if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) && + if (!opts->detach && !check_branch_ref(&symref, refname) && refs_ref_exists(get_main_ref_store(the_repository), symref.buf)) { is_branch = 1; if (!opts->force) @@ -449,7 +464,7 @@ static int add_worktree(const char *path, const char *refname, BUG("How come '%s' becomes empty after sanitization?", sb.buf); strbuf_reset(&sb); name = sb_name.buf; - git_path_buf(&sb_repo, "worktrees/%s", name); + repo_git_path_replace(the_repository, &sb_repo, "worktrees/%s", name); len = sb_repo.len; if (safe_create_leading_directories_const(sb_repo.buf)) die_errno(_("could not create leading directories of '%s'"), @@ -490,11 +505,7 @@ static int add_worktree(const char *path, const char *refname, strbuf_reset(&sb); strbuf_addf(&sb, "%s/gitdir", sb_repo.buf); - strbuf_realpath(&realpath, sb_git.buf, 1); - write_file(sb.buf, "%s", realpath.buf); - strbuf_realpath(&realpath, repo_get_common_dir(the_repository), 1); - write_file(sb_git.buf, "gitdir: %s/worktrees/%s", - realpath.buf, name); + write_worktree_linking_files(sb_git, sb, opts->relative_paths); strbuf_reset(&sb); strbuf_addf(&sb, "%s/commondir", sb_repo.buf); write_file(sb.buf, "../.."); @@ -582,7 +593,6 @@ static int add_worktree(const char *path, const char *refname, strbuf_release(&sb_repo); strbuf_release(&sb_git); strbuf_release(&sb_name); - strbuf_release(&realpath); free_worktree(wt); return ret; } @@ -604,7 +614,7 @@ static void print_preparing_worktree_line(int detach, fprintf_ln(stderr, _("Preparing worktree (new branch '%s')"), new_branch); } else { struct strbuf s = STRBUF_INIT; - if (!detach && !strbuf_check_branch_ref(&s, branch) && + if (!detach && !check_branch_ref(&s, branch) && refs_ref_exists(get_main_ref_store(the_repository), s.buf)) fprintf_ln(stderr, _("Preparing worktree (checking out '%s')"), branch); @@ -654,8 +664,9 @@ static int can_use_local_refs(const struct add_opts *opts) if (!opts->quiet) { struct strbuf path = STRBUF_INIT; struct strbuf contents = STRBUF_INIT; + char *wt_gitdir = get_worktree_git_dir(NULL); - strbuf_add_real_path(&path, get_worktree_git_dir(NULL)); + strbuf_add_real_path(&path, wt_gitdir); strbuf_addstr(&path, "/HEAD"); strbuf_read_file(&contents, path.buf, 64); strbuf_stripspace(&contents, NULL); @@ -667,6 +678,7 @@ static int can_use_local_refs(const struct add_opts *opts) path.buf, contents.buf); strbuf_release(&path); strbuf_release(&contents); + free(wt_gitdir); } return 1; } @@ -745,7 +757,7 @@ static char *dwim_branch(const char *path, char **new_branch) char *branchname = xstrndup(s, n); struct strbuf ref = STRBUF_INIT; - branch_exists = !strbuf_check_branch_ref(&ref, branchname) && + branch_exists = !check_branch_ref(&ref, branchname) && refs_ref_exists(get_main_ref_store(the_repository), ref.buf); strbuf_release(&ref); @@ -761,7 +773,8 @@ static char *dwim_branch(const char *path, char **new_branch) return NULL; } -static int add(int ac, const char **av, const char *prefix) +static int add(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { struct add_opts opts; const char *new_branch_force = NULL; @@ -794,12 +807,15 @@ static int add(int ac, const char **av, const char *prefix) PARSE_OPT_NOARG | PARSE_OPT_OPTARG), OPT_BOOL(0, "guess-remote", &guess_remote, N_("try to match the new branch name with a remote-tracking branch")), + OPT_BOOL(0, "relative-paths", &opts.relative_paths, + N_("use relative paths for worktrees")), OPT_END() }; int ret; memset(&opts, 0, sizeof(opts)); opts.checkout = 1; + opts.relative_paths = use_relative_paths; ac = parse_options(ac, av, prefix, options, git_worktree_add_usage, 0); if (!!opts.detach + !!new_branch + !!new_branch_force > 1) die(_("options '%s', '%s', and '%s' cannot be used together"), "-b", "-B", "--detach"); @@ -838,7 +854,7 @@ static int add(int ac, const char **av, const char *prefix) new_branch = new_branch_force; if (!opts.force && - !strbuf_check_branch_ref(&symref, new_branch) && + !check_branch_ref(&symref, new_branch) && refs_ref_exists(get_main_ref_store(the_repository), symref.buf)) die_if_checked_out(symref.buf, 0); strbuf_release(&symref); @@ -1037,7 +1053,8 @@ static void pathsort(struct worktree **wt) QSORT(wt, n, pathcmp); } -static int list(int ac, const char **av, const char *prefix) +static int list(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { int porcelain = 0; int line_terminator = '\n'; @@ -1082,7 +1099,8 @@ static int list(int ac, const char **av, const char *prefix) return 0; } -static int lock_worktree(int ac, const char **av, const char *prefix) +static int lock_worktree(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { const char *reason = "", *old_reason; struct option options[] = { @@ -1091,6 +1109,7 @@ static int lock_worktree(int ac, const char **av, const char *prefix) OPT_END() }; struct worktree **worktrees, *wt; + char *path; ac = parse_options(ac, av, prefix, options, git_worktree_lock_usage, 0); if (ac != 1) @@ -1111,18 +1130,22 @@ static int lock_worktree(int ac, const char **av, const char *prefix) die(_("'%s' is already locked"), av[0]); } - write_file(git_common_path("worktrees/%s/locked", wt->id), - "%s", reason); + path = repo_common_path(the_repository, "worktrees/%s/locked", wt->id); + write_file(path, "%s", reason); + free_worktrees(worktrees); + free(path); return 0; } -static int unlock_worktree(int ac, const char **av, const char *prefix) +static int unlock_worktree(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { struct option options[] = { OPT_END() }; struct worktree **worktrees, *wt; + char *path; int ret; ac = parse_options(ac, av, prefix, options, git_worktree_unlock_usage, 0); @@ -1137,8 +1160,12 @@ static int unlock_worktree(int ac, const char **av, const char *prefix) die(_("The main working tree cannot be locked or unlocked")); if (!worktree_lock_reason(wt)) die(_("'%s' is not locked"), av[0]); - ret = unlink_or_warn(git_common_path("worktrees/%s/locked", wt->id)); + + path = repo_common_path(the_repository, "worktrees/%s/locked", wt->id); + ret = unlink_or_warn(path); + free_worktrees(worktrees); + free(path); return ret; } @@ -1147,6 +1174,9 @@ static void validate_no_submodules(const struct worktree *wt) struct index_state istate = INDEX_STATE_INIT(the_repository); struct strbuf path = STRBUF_INIT; int i, found_submodules = 0; + char *wt_gitdir; + + wt_gitdir = get_worktree_git_dir(wt); if (is_directory(worktree_git_path(the_repository, wt, "modules"))) { /* @@ -1156,7 +1186,7 @@ static void validate_no_submodules(const struct worktree *wt) */ found_submodules = 1; } else if (read_index_from(&istate, worktree_git_path(the_repository, wt, "index"), - get_worktree_git_dir(wt)) > 0) { + wt_gitdir) > 0) { for (i = 0; i < istate.cache_nr; i++) { struct cache_entry *ce = istate.cache[i]; int err; @@ -1175,18 +1205,22 @@ static void validate_no_submodules(const struct worktree *wt) } discard_index(&istate); strbuf_release(&path); + free(wt_gitdir); if (found_submodules) die(_("working trees containing submodules cannot be moved or removed")); } -static int move_worktree(int ac, const char **av, const char *prefix) +static int move_worktree(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { int force = 0; struct option options[] = { OPT__FORCE(&force, N_("force move even if worktree is dirty or locked"), PARSE_OPT_NOCOMPLETE), + OPT_BOOL(0, "relative-paths", &use_relative_paths, + N_("use relative paths for worktrees")), OPT_END() }; struct worktree **worktrees, *wt; @@ -1239,7 +1273,7 @@ static int move_worktree(int ac, const char **av, const char *prefix) if (rename(wt->path, dst.buf) == -1) die_errno(_("failed to move '%s' to '%s'"), wt->path, dst.buf); - update_worktree_location(wt, dst.buf); + update_worktree_location(wt, dst.buf, use_relative_paths); strbuf_release(&dst); free_worktrees(worktrees); @@ -1310,7 +1344,8 @@ static int delete_git_work_tree(struct worktree *wt) return ret; } -static int remove_worktree(int ac, const char **av, const char *prefix) +static int remove_worktree(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { int force = 0; struct option options[] = { @@ -1375,11 +1410,14 @@ static void report_repair(int iserr, const char *path, const char *msg, void *cb } } -static int repair(int ac, const char **av, const char *prefix) +static int repair(int ac, const char **av, const char *prefix, + struct repository *repo UNUSED) { const char **p; const char *self[] = { ".", NULL }; struct option options[] = { + OPT_BOOL(0, "relative-paths", &use_relative_paths, + N_("use relative paths for worktrees")), OPT_END() }; int rc = 0; @@ -1387,15 +1425,15 @@ static int repair(int ac, const char **av, const char *prefix) ac = parse_options(ac, av, prefix, options, git_worktree_repair_usage, 0); p = ac > 0 ? av : self; for (; *p; p++) - repair_worktree_at_path(*p, report_repair, &rc); - repair_worktrees(report_repair, &rc); + repair_worktree_at_path(*p, report_repair, &rc, use_relative_paths); + repair_worktrees(report_repair, &rc, use_relative_paths); return rc; } int cmd_worktree(int ac, const char **av, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -1420,5 +1458,5 @@ int cmd_worktree(int ac, prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - return fn(ac, av, prefix); + return fn(ac, av, prefix, repo); } diff --git a/bulk-checkin.c b/bulk-checkin.c index 2753d5bbe4af3d..20f2da67b93faa 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -3,6 +3,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "bulk-checkin.h" @@ -43,8 +44,9 @@ static void finish_tmp_packfile(struct strbuf *basename, { char *idx_tmp_name = NULL; - stage_tmp_packfiles(basename, pack_tmp_name, written_list, nr_written, - NULL, pack_idx_opts, hash, &idx_tmp_name); + stage_tmp_packfiles(the_hash_algo, basename, pack_tmp_name, + written_list, nr_written, NULL, pack_idx_opts, hash, + &idx_tmp_name); rename_tmp_packfile_idx(basename, &idx_tmp_name); free(idx_tmp_name); @@ -69,7 +71,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state) CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE); } else { int fd = finalize_hashfile(state->f, hash, FSYNC_COMPONENT_PACK, 0); - fixup_pack_header_footer(fd, hash, state->pack_tmp_name, + fixup_pack_header_footer(the_hash_algo, fd, hash, state->pack_tmp_name, state->nr_written, hash, state->offset); close(fd); @@ -160,7 +162,7 @@ static int already_written(struct bulk_checkin_packfile *state, struct object_id * with a new pack. */ static int stream_blob_to_pack(struct bulk_checkin_packfile *state, - git_hash_ctx *ctx, off_t *already_hashed_to, + struct git_hash_ctx *ctx, off_t *already_hashed_to, int fd, size_t size, const char *path, unsigned flags) { @@ -193,7 +195,7 @@ static int stream_blob_to_pack(struct bulk_checkin_packfile *state, if (rsize < hsize) hsize = rsize; if (hsize) - the_hash_algo->update_fn(ctx, ibuf, hsize); + git_hash_update(ctx, ibuf, hsize); *already_hashed_to = offset; } s.next_in = ibuf; @@ -257,10 +259,10 @@ static int deflate_blob_to_pack(struct bulk_checkin_packfile *state, const char *path, unsigned flags) { off_t seekback, already_hashed_to; - git_hash_ctx ctx; + struct git_hash_ctx ctx; unsigned char obuf[16384]; unsigned header_len; - struct hashfile_checkpoint checkpoint = {0}; + struct hashfile_checkpoint checkpoint; struct pack_idx_entry *idx = NULL; seekback = lseek(fd, 0, SEEK_CUR); @@ -270,13 +272,16 @@ static int deflate_blob_to_pack(struct bulk_checkin_packfile *state, header_len = format_object_header((char *)obuf, sizeof(obuf), OBJ_BLOB, size); the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, obuf, header_len); - the_hash_algo->init_fn(&checkpoint.ctx); + git_hash_update(&ctx, obuf, header_len); /* Note: idx is non-NULL when we are writing */ - if ((flags & HASH_WRITE_OBJECT) != 0) + if ((flags & HASH_WRITE_OBJECT) != 0) { CALLOC_ARRAY(idx, 1); + prepare_to_stream(state, flags); + hashfile_checkpoint_init(state->f, &checkpoint); + } + already_hashed_to = 0; while (1) { @@ -302,7 +307,7 @@ static int deflate_blob_to_pack(struct bulk_checkin_packfile *state, if (lseek(fd, seekback, SEEK_SET) == (off_t) -1) return error("cannot seek back"); } - the_hash_algo->final_oid_fn(result_oid, &ctx); + git_hash_final_oid(result_oid, &ctx); if (!idx) return 0; @@ -332,7 +337,7 @@ void prepare_loose_object_bulk_checkin(void) if (!odb_transaction_nesting || bulk_fsync_objdir) return; - bulk_fsync_objdir = tmp_objdir_create("bulk-fsync"); + bulk_fsync_objdir = tmp_objdir_create(the_repository, "bulk-fsync"); if (bulk_fsync_objdir) tmp_objdir_replace_primary_odb(bulk_fsync_objdir, 0); } diff --git a/bundle-uri.c b/bundle-uri.c index 4b1a2e293757b9..744257c49c1328 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "bundle-uri.h" @@ -367,18 +368,27 @@ static int unbundle_from_file(struct repository *r, const char *file) struct string_list_item *refname; struct strbuf bundle_ref = STRBUF_INIT; size_t bundle_prefix_len; + struct unbundle_opts opts = { + .flags = VERIFY_BUNDLE_QUIET | + (fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0), + }; - if ((bundle_fd = read_bundle_header(file, &header)) < 0) - return 1; + bundle_fd = read_bundle_header(file, &header); + if (bundle_fd < 0) { + result = 1; + goto cleanup; + } /* * Skip the reachability walk here, since we will be adding * a reachable ref pointing to the new tips, which will reach * the prerequisite commits. */ - if ((result = unbundle(r, &header, bundle_fd, NULL, - VERIFY_BUNDLE_QUIET | (fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0)))) - return 1; + result = unbundle(r, &header, bundle_fd, NULL, &opts); + if (result) { + result = 1; + goto cleanup; + } /* * Convert all refs/heads/ from the bundle into refs/bundles/ @@ -407,6 +417,8 @@ static int unbundle_from_file(struct repository *r, const char *file) 0, UPDATE_REFS_MSG_ON_ERR); } +cleanup: + strbuf_release(&bundle_ref); bundle_header_release(&header); return result; } diff --git a/bundle.c b/bundle.c index 4773b51eb1df80..d7ad6908433ecf 100644 --- a/bundle.c +++ b/bundle.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "lockfile.h" @@ -420,36 +421,6 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs) e->name); goto skip_write_ref; } - /* - * If you run "git bundle create bndl v1.0..v2.0", the - * name of the positive ref is "v2.0" but that is the - * commit that is referenced by the tag, and not the tag - * itself. - */ - if (!oideq(&oid, &e->item->oid)) { - /* - * Is this the positive end of a range expressed - * in terms of a tag (e.g. v2.0 from the range - * "v1.0..v2.0")? - */ - struct commit *one = lookup_commit_reference(revs->repo, &oid); - struct object *obj; - - if (e->item == &(one->object)) { - /* - * Need to include e->name as an - * independent ref to the pack-objects - * input, so that the tag is included - * in the output; otherwise we would - * end up triggering "empty bundle" - * error. - */ - obj = parse_object_or_die(&oid, e->name); - obj->flags |= SHOWN; - add_pending_object(revs, obj, e->name); - } - goto skip_write_ref; - } ref_count++; write_or_die(bundle_fd, oid_to_hex(&e->item->oid), the_hash_algo->hexsz); @@ -628,12 +599,18 @@ int create_bundle(struct repository *r, const char *path, int unbundle(struct repository *r, struct bundle_header *header, int bundle_fd, struct strvec *extra_index_pack_args, - enum verify_bundle_flags flags) + struct unbundle_opts *opts) { struct child_process ip = CHILD_PROCESS_INIT; + struct unbundle_opts opts_fallback = { 0 }; + + if (!opts) + opts = &opts_fallback; - if (verify_bundle(r, header, flags)) + if (verify_bundle(r, header, opts->flags)) { + close(bundle_fd); return -1; + } strvec_pushl(&ip.args, "index-pack", "--fix-thin", "--stdin", NULL); @@ -641,8 +618,9 @@ int unbundle(struct repository *r, struct bundle_header *header, if (header->filter.choice) strvec_push(&ip.args, "--promisor=from-bundle"); - if (flags & VERIFY_BUNDLE_FSCK) - strvec_push(&ip.args, "--fsck-objects"); + if (opts->flags & VERIFY_BUNDLE_FSCK) + strvec_pushf(&ip.args, "--fsck-objects%s", + opts->fsck_msg_types ? opts->fsck_msg_types : ""); if (extra_index_pack_args) strvec_pushv(&ip.args, extra_index_pack_args->v); diff --git a/bundle.h b/bundle.h index 5ccc9a061a4dd2..d664b2f2d61e20 100644 --- a/bundle.h +++ b/bundle.h @@ -39,6 +39,17 @@ enum verify_bundle_flags { int verify_bundle(struct repository *r, struct bundle_header *header, enum verify_bundle_flags flags); +struct unbundle_opts { + enum verify_bundle_flags flags; + /* + * fsck_msg_types may optionally contain fsck message severity + * configuration. If present, this configuration gets directly appended + * to a '--fsck-objects' option and therefore must be prefixed with '='. + * (E.g. "=missingEmail=ignore,gitmodulesUrl=ignore") + */ + const char *fsck_msg_types; +}; + /** * Unbundle after reading the header with read_bundle_header(). * @@ -49,12 +60,14 @@ int verify_bundle(struct repository *r, struct bundle_header *header, * (e.g. "-v" for verbose/progress), NULL otherwise. The provided * "extra_index_pack_args" (if any) will be strvec_clear()'d for you. * - * Before unbundling, this method will call verify_bundle() with the - * given 'flags'. + * Before unbundling, this method will call verify_bundle() with 'flags' + * provided in 'opts'. + * + * Note that the `bundle_fd` will be closed as part of the operation. */ int unbundle(struct repository *r, struct bundle_header *header, int bundle_fd, struct strvec *extra_index_pack_args, - enum verify_bundle_flags flags); + struct unbundle_opts *opts); int list_bundle_refs(struct bundle_header *header, int argc, const char **argv); diff --git a/cache-tree.c b/cache-tree.c index b482167a69ae6a..bcbcad3d61a09c 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -1,6 +1,8 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" +#include "gettext.h" #include "hex.h" #include "lockfile.h" #include "tree.h" @@ -865,15 +867,15 @@ int cache_tree_matches_traversal(struct cache_tree *root, return 0; } -static void verify_one_sparse(struct index_state *istate, - struct strbuf *path, - int pos) +static int verify_one_sparse(struct index_state *istate, + struct strbuf *path, + int pos) { struct cache_entry *ce = istate->cache[pos]; - if (!S_ISSPARSEDIR(ce->ce_mode)) - BUG("directory '%s' is present in index, but not sparse", - path->buf); + return error(_("directory '%s' is present in index, but not sparse"), + path->buf); + return 0; } /* @@ -882,6 +884,7 @@ static void verify_one_sparse(struct index_state *istate, * 1 - Restart verification - a call to ensure_full_index() freed the cache * tree that is being verified and verification needs to be restarted from * the new toplevel cache tree. + * -1 - Verification failed. */ static int verify_one(struct repository *r, struct index_state *istate, @@ -891,18 +894,23 @@ static int verify_one(struct repository *r, int i, pos, len = path->len; struct strbuf tree_buf = STRBUF_INIT; struct object_id new_oid; + int ret; for (i = 0; i < it->subtree_nr; i++) { strbuf_addf(path, "%s/", it->down[i]->name); - if (verify_one(r, istate, it->down[i]->cache_tree, path)) - return 1; + ret = verify_one(r, istate, it->down[i]->cache_tree, path); + if (ret) + goto out; + strbuf_setlen(path, len); } if (it->entry_count < 0 || /* no verification on tests (t7003) that replace trees */ - lookup_replace_object(r, &it->oid) != &it->oid) - return 0; + lookup_replace_object(r, &it->oid) != &it->oid) { + ret = 0; + goto out; + } if (path->len) { /* @@ -912,12 +920,14 @@ static int verify_one(struct repository *r, */ int is_sparse = istate->sparse_index; pos = index_name_pos(istate, path->buf, path->len); - if (is_sparse && !istate->sparse_index) - return 1; + if (is_sparse && !istate->sparse_index) { + ret = 1; + goto out; + } if (pos >= 0) { - verify_one_sparse(istate, path, pos); - return 0; + ret = verify_one_sparse(istate, path, pos); + goto out; } pos = -pos - 1; @@ -925,6 +935,11 @@ static int verify_one(struct repository *r, pos = 0; } + if (it->entry_count + pos > istate->cache_nr) { + ret = error(_("corrupted cache-tree has entries not present in index")); + goto out; + } + i = 0; while (i < it->entry_count) { struct cache_entry *ce = istate->cache[pos + i]; @@ -935,16 +950,23 @@ static int verify_one(struct repository *r, unsigned mode; int entlen; - if (ce->ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE)) - BUG("%s with flags 0x%x should not be in cache-tree", - ce->name, ce->ce_flags); + if (ce->ce_flags & (CE_STAGEMASK | CE_INTENT_TO_ADD | CE_REMOVE)) { + ret = error(_("%s with flags 0x%x should not be in cache-tree"), + ce->name, ce->ce_flags); + goto out; + } + name = ce->name + path->len; slash = strchr(name, '/'); if (slash) { entlen = slash - name; + sub = find_subtree(it, ce->name + path->len, entlen, 0); - if (!sub || sub->cache_tree->entry_count < 0) - BUG("bad subtree '%.*s'", entlen, name); + if (!sub || sub->cache_tree->entry_count < 0) { + ret = error(_("bad subtree '%.*s'"), entlen, name); + goto out; + } + oid = &sub->cache_tree->oid; mode = S_IFDIR; i += sub->cache_tree->entry_count; @@ -957,27 +979,50 @@ static int verify_one(struct repository *r, strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0'); strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz); } + hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, OBJ_TREE, &new_oid); - if (!oideq(&new_oid, &it->oid)) - BUG("cache-tree for path %.*s does not match. " - "Expected %s got %s", len, path->buf, - oid_to_hex(&new_oid), oid_to_hex(&it->oid)); + + if (!oideq(&new_oid, &it->oid)) { + ret = error(_("cache-tree for path %.*s does not match. " + "Expected %s got %s"), len, path->buf, + oid_to_hex(&new_oid), oid_to_hex(&it->oid)); + goto out; + } + + ret = 0; +out: strbuf_setlen(path, len); strbuf_release(&tree_buf); - return 0; + return ret; } -void cache_tree_verify(struct repository *r, struct index_state *istate) +int cache_tree_verify(struct repository *r, struct index_state *istate) { struct strbuf path = STRBUF_INIT; + int ret; - if (!istate->cache_tree) - return; - if (verify_one(r, istate, istate->cache_tree, &path)) { + if (!istate->cache_tree) { + ret = 0; + goto out; + } + + ret = verify_one(r, istate, istate->cache_tree, &path); + if (ret < 0) + goto out; + if (ret > 0) { strbuf_reset(&path); - if (verify_one(r, istate, istate->cache_tree, &path)) + + ret = verify_one(r, istate, istate->cache_tree, &path); + if (ret < 0) + goto out; + if (ret > 0) BUG("ensure_full_index() called twice while verifying cache tree"); } + + ret = 0; + +out: strbuf_release(&path); + return ret; } diff --git a/cache-tree.h b/cache-tree.h index faae88be63c2ce..b82c4963e7c805 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -33,7 +33,7 @@ struct cache_tree *cache_tree_read(const char *buffer, unsigned long size); int cache_tree_fully_valid(struct cache_tree *); int cache_tree_update(struct index_state *, int); -void cache_tree_verify(struct repository *, struct index_state *); +int cache_tree_verify(struct repository *, struct index_state *); /* bitmasks to write_index_as_tree flags */ #define WRITE_TREE_MISSING_OK 1 diff --git a/chunk-format.c b/chunk-format.c index 2dde24e6a317ce..51b5a2c959a1cf 100644 --- a/chunk-format.c +++ b/chunk-format.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "chunk-format.h" diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 08656a15308ada..0df74610d063fb 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -24,42 +24,44 @@ fi case "$distro" in alpine-*) - apk add --update shadow sudo build-base curl-dev openssl-dev expat-dev gettext \ - pcre2-dev python3 musl-libintl perl-utils ncurses \ + apk add --update shadow sudo meson ninja-build gcc libc-dev curl-dev openssl-dev expat-dev gettext \ + zlib-ng-dev 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 perl-io-tty >/dev/null ;; -fedora-*) +fedora-*|almalinux-*) 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 + dnf -yq install shadow-utils sudo make gcc findutils diffutils perl python3 gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel >/dev/null ;; -ubuntu-*|ubuntu32-*) +ubuntu-*|i386/ubuntu-*|debian-*) # Required so that apt doesn't wait for user input on certain packages. export DEBIAN_FRONTEND=noninteractive case "$distro" in ubuntu-*) SVN='libsvn-perl subversion' + LANGUAGES='language-pack-is' ;; - *) + i386/ubuntu-*) SVN= + LANGUAGES='language-pack-is' + ;; + *) + SVN='libsvn-perl subversion' + LANGUAGES='locales-all' ;; esac sudo apt-get -q update sudo apt-get -q -y install \ - language-pack-is apache2 cvs cvsps git gnupg $SVN \ + $LANGUAGES apache2 cvs cvsps git gnupg $SVN \ make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \ tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \ libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \ + libsecret-1-dev libpcre2-dev meson ninja-build pkg-config \ ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE case "$distro" in - ubuntu-16.04) - # Does not support JGit, but we also don't really care about - # the others. We rather care whether Git still compiles and - # runs fine overall. - ;; ubuntu-*) mkdir --parents "$CUSTOM_PATH" @@ -89,6 +91,12 @@ macos-*) sudo xattr -d com.apple.quarantine "$CUSTOM_PATH/p4" "$CUSTOM_PATH/p4d" 2>/dev/null || true rm helix-core-server.tgz + case "$jobname" in + osx-meson) + brew install meson ninja pcre2 + ;; + esac + if test -n "$CC_PACKAGE" then BREW_PACKAGE=${CC_PACKAGE/-/@} @@ -119,6 +127,7 @@ Documentation) test -n "$ALREADY_HAVE_ASCIIDOCTOR" || sudo gem install --version 1.5.8 asciidoctor + sudo gem install concurrent-ruby ;; esac diff --git a/ci/install-sdk.ps1 b/ci/install-sdk.ps1 new file mode 100755 index 00000000000000..66f24838a40ecb --- /dev/null +++ b/ci/install-sdk.ps1 @@ -0,0 +1,12 @@ +param( + [string]$directory='git-sdk', + [string]$url='https://github.com/git-for-windows/git-sdk-64/releases/download/ci-artifacts/git-sdk-x86_64-minimal.zip' +) + +Invoke-WebRequest "$url" -OutFile git-sdk.zip +Expand-Archive -LiteralPath git-sdk.zip -DestinationPath "$directory" +Remove-Item -Path git-sdk.zip + +New-Item -Path .git/info -ItemType Directory -Force +New-Item -Path .git/info/exclude -ItemType File -Force +Add-Content -Path .git/info/exclude -Value "/$directory" diff --git a/ci/lib.sh b/ci/lib.sh index 74b430be2387ac..f561884d40166c 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -18,7 +18,8 @@ elif test true = "$GITLAB_CI" then begin_group () { need_to_end_group=t - printf "\e[0Ksection_start:$(date +%s):$(echo "$1" | tr ' ' _)[collapsed=true]\r\e[0K$1\n" + printf '\e[0Ksection_start:%s:%s[collapsed=true]\r\e[0K%s\n' \ + "$(date +%s)" "$(echo "$1" | tr ' ' _)" "$1" trap "end_group '$1'" EXIT set -x } @@ -27,7 +28,8 @@ then test -n "$need_to_end_group" || return 0 set +x need_to_end_group= - printf "\e[0Ksection_end:$(date +%s):$(echo "$1" | tr ' ' _)\r\e[0K\n" + printf '\e[0Ksection_end:%s:%s\r\e[0K\n' \ + "$(date +%s)" "$(echo "$1" | tr ' ' _)" trap - EXIT } else @@ -55,14 +57,13 @@ group () { return $res } -begin_group "CI setup" -trap "end_group 'CI setup'" EXIT +begin_group "CI setup via $(basename $0)" # Set 'exit on error' for all CI scripts to let the caller know that # something went wrong. # # We already enabled tracing executed commands earlier. This helps by showing -# how # environment variables are set and and dependencies are installed. +# how # environment variables are set and dependencies are installed. set -e skip_branch_tip_with_tag () { @@ -180,9 +181,9 @@ handle_failed_tests () { } create_failed_test_artifacts () { - mkdir -p t/failed-test-artifacts + mkdir -p "${TEST_OUTPUT_DIRECTORY:-t}"/failed-test-artifacts - for test_exit in t/test-results/*.exit + for test_exit in "${TEST_OUTPUT_DIRECTORY:-t}"/test-results/*.exit do test 0 != "$(cat "$test_exit")" || continue @@ -191,11 +192,11 @@ create_failed_test_artifacts () { 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" + cat "${TEST_OUTPUT_DIRECTORY:-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" + trash_dir="${TEST_OUTPUT_DIRECTORY:-t}/trash directory.$test_name" + cp "${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.out" "${TEST_OUTPUT_DIRECTORY:-t}"/failed-test-artifacts/ + tar czf "${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts/$test_name.trash.tar.gz" "$trash_dir" done } @@ -205,26 +206,7 @@ export TERM=${TERM:-dumb} # Clear MAKEFLAGS that may come from the outside world. export MAKEFLAGS= -if test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI" -then - CI_TYPE=azure-pipelines - # We are running in Azure Pipelines - CI_BRANCH="$BUILD_SOURCEBRANCH" - CI_COMMIT="$BUILD_SOURCEVERSION" - CI_JOB_ID="$BUILD_BUILDID" - CI_JOB_NUMBER="$BUILD_BUILDNUMBER" - CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" - test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx - CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" - CC="${CC:-gcc}" - - # use a subdirectory of the cache dir (because the file share is shared - # among *all* phases) - cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME" - - GIT_TEST_OPTS="--write-junit-xml" - JOBS=10 -elif test true = "$GITHUB_ACTIONS" +if test true = "$GITHUB_ACTIONS" then CI_TYPE=github-actions CI_BRANCH="$GITHUB_REF" @@ -236,7 +218,7 @@ then CC="${CC_PACKAGE:-${CC:-gcc}}" DONT_SKIP_TAGS=t handle_failed_tests () { - echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV + echo "FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts" >>$GITHUB_ENV create_failed_test_artifacts return 1 } @@ -245,13 +227,20 @@ then GIT_TEST_OPTS="--github-workflow-markup" JOBS=10 + + distro=$(echo "$CI_JOB_IMAGE" | tr : -) 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-*) + + case "$OS,$CI_JOB_IMAGE" in + Windows_NT,*) + CI_OS_NAME=windows + JOBS=$NUMBER_OF_PROCESSORS + ;; + *,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 @@ -259,9 +248,12 @@ then export PATH="$(brew --prefix)/bin:$PATH" CI_OS_NAME=osx + JOBS=$(nproc) + ;; + *,alpine:*|*,fedora:*|*,ubuntu:*|*,i386/ubuntu:*) + CI_OS_NAME=linux + JOBS=$(nproc) ;; - alpine:*|fedora:*|ubuntu:*) - CI_OS_NAME=linux;; *) echo "Could not identify OS image" >&2 env >&2 @@ -272,6 +264,7 @@ then CI_JOB_ID="$CI_JOB_ID" CC="${CC_PACKAGE:-${CC:-gcc}}" DONT_SKIP_TAGS=t + handle_failed_tests () { create_failed_test_artifacts return 1 @@ -280,7 +273,6 @@ then cache_dir="$HOME/none" distro=$(echo "$CI_JOB_IMAGE" | tr : -) - JOBS=$(nproc) else echo "Could not identify CI type" >&2 env >&2 @@ -320,11 +312,6 @@ export SKIP_DASHED_BUILT_INS=YesPlease case "$distro" in ubuntu-*) - if test "$jobname" = "linux-gcc-default" - then - break - fi - # Python 2 is end of life, and Ubuntu 23.04 and newer don't actually # have it anymore. We thus only test with Python 2 on older LTS # releases. @@ -336,14 +323,7 @@ ubuntu-*) fi MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/$PYTHON_PACKAGE" - case "$distro" in - ubuntu-16.04) - # Apache is too old for HTTP/2. - ;; - *) - export GIT_TEST_HTTPD=true - ;; - esac + export GIT_TEST_HTTPD=true # The Linux build installs the defined dependency versions below. # The OS X build installs much more recent versions, whichever @@ -368,24 +348,26 @@ case "$jobname" in linux32) CC=gcc ;; -linux-musl) - CC=gcc - MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python3 USE_LIBPCRE2=Yes" - MAKEFLAGS="$MAKEFLAGS NO_REGEX=Yes ICONV_OMITS_BOM=Yes" - MAKEFLAGS="$MAKEFLAGS GIT_TEST_UTF8_LOCALE=C.UTF-8" +linux-meson) + MESONFLAGS="$MESONFLAGS -Dcredential_helpers=libsecret,netrc" + ;; +linux-musl-meson) + MESONFLAGS="$MESONFLAGS -Dtest_utf8_locale=C.UTF-8" ;; linux-leaks|linux-reftable-leaks) export SANITIZE=leak - export GIT_TEST_PASSING_SANITIZE_LEAK=true ;; linux-asan-ubsan) export SANITIZE=address,undefined export NO_SVN_TESTS=LetsSaveSomeTime MAKEFLAGS="$MAKEFLAGS NO_PYTHON=YepBecauseP4FlakesTooOften" ;; +osx-meson) + MESONFLAGS="$MESONFLAGS -Dcredential_helpers=osxkeychain" + ;; esac MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}" -end_group "CI setup" +end_group "CI setup via $(basename $0)" set -x diff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh index b1f80aeac345dd..dc910e51609cd7 100755 --- a/ci/print-test-failures.sh +++ b/ci/print-test-failures.sh @@ -39,14 +39,9 @@ do test_name="${test_name##*/}" trash_dir="trash directory.$test_name" case "$CI_TYPE" in - azure-pipelines) - mkdir -p failed-test-artifacts - mv "$trash_dir" failed-test-artifacts - continue - ;; github-actions) mkdir -p failed-test-artifacts - echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV + echo "FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts" >>$GITHUB_ENV cp "${TEST_EXIT%.exit}.out" failed-test-artifacts/ tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir" continue diff --git a/ci/run-build-and-minimal-fuzzers.sh b/ci/run-build-and-minimal-fuzzers.sh index af8065f34992f8..e7b97952e7d485 100755 --- a/ci/run-build-and-minimal-fuzzers.sh +++ b/ci/run-build-and-minimal-fuzzers.sh @@ -13,7 +13,18 @@ group "Build fuzzers" make \ LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \ fuzz-all -for fuzzer in commit-graph config date pack-headers pack-idx ; do +fuzzers=" +commit-graph +config +credential-from-url-gently +date +pack-headers +pack-idx +parse-attr-line +url-decode-mem +" + +for fuzzer in $fuzzers; do begin_group "fuzz-$fuzzer" ./oss-fuzz/fuzz-$fuzzer -verbosity=0 -runs=1 || exit 1 end_group "fuzz-$fuzzer" diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh index 2e28d02b20f246..1c698467235943 100755 --- a/ci/run-build-and-tests.sh +++ b/ci/run-build-and-tests.sh @@ -13,10 +13,12 @@ esac run_tests=t case "$jobname" in -linux-gcc) +linux-breaking-changes) export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main + export WITH_BREAKING_CHANGES=YesPlease ;; linux-TEST-vars) + export OPENSSL_SHA1_UNSAFE=YesPlease export GIT_TEST_SPLIT_INDEX=yes export GIT_TEST_MERGE_ALGORITHM=recursive export GIT_TEST_FULL_IN_PACK_ARRAY=true @@ -48,12 +50,32 @@ pedantic) ;; esac -group Build make -if test -n "$run_tests" -then - group "Run tests" make test || - handle_failed_tests -fi -check_unignored_build_artifacts +case "$jobname" in +*-meson) + group "Configure" meson setup build . \ + --fatal-meson-warnings \ + --warnlevel 2 --werror \ + --wrap-mode nofallback \ + -Dfuzzers=true \ + $MESONFLAGS + group "Build" meson compile -C build -- + if test -n "$run_tests" + then + group "Run tests" meson test -C build --print-errorlogs --test-args="$GIT_TEST_OPTS" || ( + ./t/aggregate-results.sh "${TEST_OUTPUT_DIRECTORY:-t}/test-results" + handle_failed_tests + ) + fi + ;; +*) + group Build make + if test -n "$run_tests" + then + group "Run tests" make test || + handle_failed_tests + fi + ;; +esac +check_unignored_build_artifacts save_good_tree diff --git a/ci/test-documentation.sh b/ci/test-documentation.sh index 02b3af394117f8..6c018b673e0563 100755 --- a/ci/test-documentation.sh +++ b/ci/test-documentation.sh @@ -6,7 +6,7 @@ . ${0%/*}/lib.sh filter_log () { - sed -e '/^GIT_VERSION = /d' \ + sed -e '/^GIT_VERSION=/d' \ -e "/constant Gem::ConfigMap is deprecated/d" \ -e '/^ \* new asciidoc flags$/d' \ -e '/stripped namespace before processing/d' \ diff --git a/color.c b/color.c index 227a5ab2f42ef9..7df8862c710794 100644 --- a/color.c +++ b/color.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "color.h" diff --git a/column.c b/column.c index 50bbccc92ee86c..93fae316b454ad 100644 --- a/column.c +++ b/column.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "column.h" diff --git a/combine-diff.c b/combine-diff.c index 829a44e4167300..9527f3160d8c22 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "object-store-ll.h" @@ -46,31 +47,20 @@ static struct combine_diff_path *intersect_paths( if (!n) { for (i = 0; i < q->nr; i++) { - int len; - const char *path; if (diff_unmodified_pair(q->queue[i])) continue; - path = q->queue[i]->two->path; - len = strlen(path); - p = xmalloc(combine_diff_path_size(num_parent, len)); - p->path = (char *) &(p->parent[num_parent]); - memcpy(p->path, path, len); - p->path[len] = 0; - p->next = NULL; - memset(p->parent, 0, - sizeof(p->parent[0]) * num_parent); - - oidcpy(&p->oid, &q->queue[i]->two->oid); - p->mode = q->queue[i]->two->mode; + p = combine_diff_path_new(q->queue[i]->two->path, + strlen(q->queue[i]->two->path), + q->queue[i]->two->mode, + &q->queue[i]->two->oid, + num_parent); oidcpy(&p->parent[n].oid, &q->queue[i]->one->oid); p->parent[n].mode = q->queue[i]->one->mode; p->parent[n].status = q->queue[i]->status; if (combined_all_paths && filename_changed(p->parent[n].status)) { - strbuf_init(&p->parent[n].path, 0); - strbuf_addstr(&p->parent[n].path, - q->queue[i]->one->path); + p->parent[n].path = xstrdup(q->queue[i]->one->path); } *tail = p; tail = &p->next; @@ -91,9 +81,7 @@ static struct combine_diff_path *intersect_paths( /* p->path not in q->queue[]; drop it */ *tail = p->next; for (j = 0; j < num_parent; j++) - if (combined_all_paths && - filename_changed(p->parent[j].status)) - strbuf_release(&p->parent[j].path); + free(p->parent[j].path); free(p); continue; } @@ -109,8 +97,7 @@ static struct combine_diff_path *intersect_paths( p->parent[n].status = q->queue[i]->status; if (combined_all_paths && filename_changed(p->parent[n].status)) - strbuf_addstr(&p->parent[n].path, - q->queue[i]->one->path); + p->parent[n].path = xstrdup(q->queue[i]->one->path); tail = &p->next; i++; @@ -995,8 +982,9 @@ static void show_combined_header(struct combine_diff_path *elem, if (rev->combined_all_paths) { for (i = 0; i < num_parent; i++) { - char *path = filename_changed(elem->parent[i].status) - ? elem->parent[i].path.buf : elem->path; + const char *path = elem->parent[i].path ? + elem->parent[i].path : + elem->path; if (elem->parent[i].status == DIFF_STATUS_ADDED) dump_quoted_path("--- ", "", "/dev/null", line_prefix, c_meta, c_reset); @@ -1185,7 +1173,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, result_file.ptr = result; result_file.size = result_size; - /* Even p_lno[cnt+1] is valid -- that is for the end line number + /* + * Even p_lno[cnt+1] is valid -- that is for the end line number * for deletion hunk at the end. */ CALLOC_ARRAY(sline[0].p_lno, st_mult(st_add(cnt, 2), num_parent)); @@ -1220,7 +1209,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, } free(result); - for (lno = 0; lno < cnt; lno++) { + for (lno = 0; lno < cnt + 2; lno++) { if (sline[lno].lost) { struct lline *ll = sline[lno].lost; while (ll) { @@ -1276,12 +1265,10 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re for (i = 0; i < num_parent; i++) if (rev->combined_all_paths) { - if (filename_changed(p->parent[i].status)) - write_name_quoted(p->parent[i].path.buf, stdout, - inter_name_termination); - else - write_name_quoted(p->path, stdout, - inter_name_termination); + const char *path = p->parent[i].path ? + p->parent[i].path : + p->path; + write_name_quoted(path, stdout, inter_name_termination); } write_name_quoted(p->path, stdout, line_termination); } @@ -1393,9 +1380,8 @@ static struct combine_diff_path *find_paths_generic(const struct object_id *oid, { struct combine_diff_path *paths = NULL; int i, num_parent = parents->nr; - int output_format = opt->output_format; - const char *orderfile = opt->orderfile; + char *orderfile = opt->orderfile; opt->output_format = DIFF_FORMAT_NO_OUTPUT; /* tell diff_tree to emit paths in sorted (=tree) order */ @@ -1442,22 +1428,19 @@ static struct combine_diff_path *find_paths_multitree( { int i, nparent = parents->nr; const struct object_id **parents_oid; - struct combine_diff_path paths_head; + struct combine_diff_path *paths; struct strbuf base; ALLOC_ARRAY(parents_oid, nparent); for (i = 0; i < nparent; i++) parents_oid[i] = &parents->oid[i]; - /* fake list head, so worker can assume it is non-NULL */ - paths_head.next = NULL; - strbuf_init(&base, PATH_MAX); - diff_tree_paths(&paths_head, oid, parents_oid, nparent, &base, opt); + paths = diff_tree_paths(oid, parents_oid, nparent, &base, opt); strbuf_release(&base); free(parents_oid); - return paths_head.next; + return paths; } static int match_objfind(struct combine_diff_path *path, @@ -1644,9 +1627,7 @@ void diff_tree_combined(const struct object_id *oid, struct combine_diff_path *tmp = paths; paths = paths->next; for (i = 0; i < num_parent; i++) - if (rev->combined_all_paths && - filename_changed(tmp->parent[i].status)) - strbuf_release(&tmp->parent[i].path); + free(tmp->parent[i].path); free(tmp); } @@ -1666,3 +1647,25 @@ void diff_tree_combined_merge(const struct commit *commit, diff_tree_combined(&commit->object.oid, &parents, rev); oid_array_clear(&parents); } + +struct combine_diff_path *combine_diff_path_new(const char *path, + size_t path_len, + unsigned int mode, + const struct object_id *oid, + size_t num_parents) +{ + struct combine_diff_path *p; + size_t parent_len = st_mult(sizeof(p->parent[0]), num_parents); + + p = xmalloc(st_add4(sizeof(*p), path_len, 1, parent_len)); + p->path = (char *)&(p->parent[num_parents]); + memcpy(p->path, path, path_len); + p->path[path_len] = 0; + p->next = NULL; + p->mode = mode; + oidcpy(&p->oid, oid); + + memset(p->parent, 0, parent_len); + + return p; +} diff --git a/command-list.txt b/command-list.txt index e0bb87b3b5c278..ecc9d2281a0909 100644 --- a/command-list.txt +++ b/command-list.txt @@ -60,6 +60,7 @@ git-annotate ancillaryinterrogators git-apply plumbingmanipulators complete git-archimport foreignscminterface git-archive mainporcelain +git-backfill mainporcelain history git-bisect mainporcelain info git-blame ancillaryinterrogators complete git-branch mainporcelain history @@ -186,6 +187,7 @@ git-stash mainporcelain git-status mainporcelain info git-stripspace purehelpers git-submodule mainporcelain +git-survey mainporcelain git-svn foreignscminterface git-switch mainporcelain history git-symbolic-ref plumbingmanipulators diff --git a/commit-graph.c b/commit-graph.c index 5bd89c0acdd03d..1021ccb983d4ee 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -1533,6 +1534,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( + the_repository, _("Loading known commits in commit graph"), ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { @@ -1550,6 +1552,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) */ if (ctx->report_progress) ctx->progress = start_delayed_progress( + the_repository, _("Expanding reachable commits in commit graph"), 0); for (i = 0; i < ctx->oids.nr; i++) { @@ -1570,6 +1573,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( + the_repository, _("Clearing commit marks in commit graph"), ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { @@ -1687,6 +1691,7 @@ static void compute_topological_levels(struct write_commit_graph_context *ctx) if (ctx->report_progress) info.progress = ctx->progress = start_delayed_progress( + the_repository, _("Computing commit graph topological levels"), ctx->commits.nr); @@ -1721,6 +1726,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx) if (ctx->report_progress) info.progress = ctx->progress = start_delayed_progress( + the_repository, _("Computing commit graph generation numbers"), ctx->commits.nr); @@ -1797,6 +1803,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx) if (ctx->report_progress) progress = start_delayed_progress( + the_repository, _("Computing commit changed paths Bloom filters"), ctx->commits.nr); @@ -1876,6 +1883,7 @@ int write_commit_graph_reachable(struct object_directory *odb, data.commits = &commits; if (flags & COMMIT_GRAPH_WRITE_PROGRESS) data.progress = start_delayed_progress( + the_repository, _("Collecting referenced commits"), 0); refs_for_each_ref(get_main_ref_store(the_repository), add_ref_to_set, @@ -1907,14 +1915,15 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx, "Finding commits for commit graph in %"PRIuMAX" packs", pack_indexes->nr), (uintmax_t)pack_indexes->nr); - ctx->progress = start_delayed_progress(progress_title.buf, 0); + ctx->progress = start_delayed_progress(the_repository, + progress_title.buf, 0); ctx->progress_done = 0; } for (i = 0; i < pack_indexes->nr; i++) { struct packed_git *p; strbuf_setlen(&packname, dirlen); strbuf_addstr(&packname, pack_indexes->items[i].string); - p = add_packed_git(packname.buf, packname.len, 1); + p = add_packed_git(ctx->r, packname.buf, packname.len, 1); if (!p) { ret = error(_("error adding pack %s"), packname.buf); goto cleanup; @@ -1958,9 +1967,10 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx) { if (ctx->report_progress) ctx->progress = start_delayed_progress( + the_repository, _("Finding commits for commit graph among packed objects"), ctx->approx_nr_objects); - for_each_packed_object(add_packed_commits, ctx, + for_each_packed_object(ctx->r, add_packed_commits, ctx, FOR_EACH_OBJECT_PACK_ORDER); if (ctx->progress_done < ctx->approx_nr_objects) display_progress(ctx->progress, ctx->approx_nr_objects); @@ -1976,6 +1986,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx) ctx->num_extra_edges = 0; if (ctx->report_progress) ctx->progress = start_delayed_progress( + the_repository, _("Finding extra edges in commit graph"), ctx->oids.nr); oid_array_sort(&ctx->oids); @@ -2073,7 +2084,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) return -1; } - if (adjust_shared_perm(get_tempfile_path(graph_layer))) { + if (adjust_shared_perm(the_repository, get_tempfile_path(graph_layer))) { error(_("unable to adjust shared permissions for '%s'"), get_tempfile_path(graph_layer)); return -1; @@ -2135,6 +2146,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) get_num_chunks(cf)), get_num_chunks(cf)); ctx->progress = start_delayed_progress( + the_repository, progress_title.buf, st_mult(get_num_chunks(cf), ctx->commits.nr)); } @@ -2347,6 +2359,7 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( + the_repository, _("Scanning merged commits"), ctx->commits.nr); @@ -2391,7 +2404,8 @@ static void merge_commit_graphs(struct write_commit_graph_context *ctx) current_graph_number--; if (ctx->report_progress) - ctx->progress = start_delayed_progress(_("Merging commit-graph"), 0); + ctx->progress = start_delayed_progress(the_repository, + _("Merging commit-graph"), 0); merge_commit_graph(ctx, g); stop_progress(&ctx->progress); @@ -2873,7 +2887,8 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) if (!(flags & COMMIT_GRAPH_VERIFY_SHALLOW)) total += g->num_commits_in_base; - progress = start_progress(_("Verifying commits in commit graph"), + progress = start_progress(the_repository, + _("Verifying commits in commit graph"), total); } diff --git a/commit-reach.c b/commit-reach.c index c3518aa3606f36..a339e41aa4ed1e 100644 --- a/commit-reach.c +++ b/commit-reach.c @@ -41,8 +41,7 @@ static int compare_commits_by_gen(const void *_a, const void *_b) static int queue_has_nonstale(struct prio_queue *queue) { - int i; - for (i = 0; i < queue->nr; i++) { + for (size_t i = 0; i < queue->nr; i++) { struct commit *commit = queue->array[i].data; if (!(commit->object.flags & STALE)) return 1; @@ -212,12 +211,13 @@ int get_octopus_merge_bases(struct commit_list *in, struct commit_list **result) } static int remove_redundant_no_gen(struct repository *r, - struct commit **array, int cnt) + struct commit **array, + size_t cnt, size_t *dedup_cnt) { struct commit **work; unsigned char *redundant; - int *filled_index; - int i, j, filled; + size_t *filled_index; + size_t i, j, filled; CALLOC_ARRAY(work, cnt); redundant = xcalloc(cnt, 1); @@ -267,20 +267,22 @@ static int remove_redundant_no_gen(struct repository *r, for (i = filled = 0; i < cnt; i++) if (!redundant[i]) array[filled++] = work[i]; + *dedup_cnt = filled; free(work); free(redundant); free(filled_index); - return filled; + return 0; } static int remove_redundant_with_gen(struct repository *r, - struct commit **array, int cnt) + struct commit **array, size_t cnt, + size_t *dedup_cnt) { - int i, count_non_stale = 0, count_still_independent = cnt; + size_t i, count_non_stale = 0, count_still_independent = cnt; timestamp_t min_generation = GENERATION_NUMBER_INFINITY; struct commit **walk_start, **sorted; size_t walk_start_nr = 0, walk_start_alloc = cnt; - int min_gen_pos = 0; + size_t min_gen_pos = 0; /* * Sort the input by generation number, ascending. This allows @@ -326,12 +328,12 @@ static int remove_redundant_with_gen(struct repository *r, * terminate early. Otherwise, we will do the same amount of work * as before. */ - for (i = walk_start_nr - 1; i >= 0 && count_still_independent > 1; i--) { + for (i = walk_start_nr; i && count_still_independent > 1; i--) { /* push the STALE bits up to min generation */ struct commit_list *stack = NULL; - commit_list_insert(walk_start[i], &stack); - walk_start[i]->object.flags |= STALE; + commit_list_insert(walk_start[i - 1], &stack); + walk_start[i - 1]->object.flags |= STALE; while (stack) { struct commit_list *parents; @@ -388,10 +390,12 @@ static int remove_redundant_with_gen(struct repository *r, clear_commit_marks_many(walk_start_nr, walk_start, STALE); free(walk_start); - return count_non_stale; + *dedup_cnt = count_non_stale; + return 0; } -static int remove_redundant(struct repository *r, struct commit **array, int cnt) +static int remove_redundant(struct repository *r, struct commit **array, + size_t cnt, size_t *dedup_cnt) { /* * Some commit in the array may be an ancestor of @@ -401,31 +405,30 @@ static int remove_redundant(struct repository *r, struct commit **array, int cnt * that number. */ if (generation_numbers_enabled(r)) { - int i; - /* * If we have a single commit with finite generation * number, then the _with_gen algorithm is preferred. */ - for (i = 0; i < cnt; i++) { + for (size_t i = 0; i < cnt; i++) { if (commit_graph_generation(array[i]) < GENERATION_NUMBER_INFINITY) - return remove_redundant_with_gen(r, array, cnt); + return remove_redundant_with_gen(r, array, cnt, dedup_cnt); } } - return remove_redundant_no_gen(r, array, cnt); + return remove_redundant_no_gen(r, array, cnt, dedup_cnt); } static int get_merge_bases_many_0(struct repository *r, struct commit *one, - int n, + size_t n, struct commit **twos, int cleanup, struct commit_list **result) { struct commit_list *list; struct commit **rslt; - int cnt, i; + size_t cnt, i; + int ret; if (merge_bases_many(r, one, n, twos, result) < 0) return -1; @@ -452,8 +455,8 @@ static int get_merge_bases_many_0(struct repository *r, clear_commit_marks(one, all_flags); clear_commit_marks_many(n, twos, all_flags); - cnt = remove_redundant(r, rslt, cnt); - if (cnt < 0) { + ret = remove_redundant(r, rslt, cnt, &cnt); + if (ret < 0) { free(rslt); return -1; } @@ -465,7 +468,7 @@ static int get_merge_bases_many_0(struct repository *r, int repo_get_merge_bases_many(struct repository *r, struct commit *one, - int n, + size_t n, struct commit **twos, struct commit_list **result) { @@ -474,7 +477,7 @@ int repo_get_merge_bases_many(struct repository *r, int repo_get_merge_bases_many_dirty(struct repository *r, struct commit *one, - int n, + size_t n, struct commit **twos, struct commit_list **result) { @@ -582,7 +585,8 @@ struct commit_list *reduce_heads(struct commit_list *heads) struct commit_list *p; struct commit_list *result = NULL, **tail = &result; struct commit **array; - int num_head, i; + size_t num_head, i; + int ret; if (!heads) return NULL; @@ -603,11 +607,13 @@ struct commit_list *reduce_heads(struct commit_list *heads) p->item->object.flags &= ~STALE; } } - num_head = remove_redundant(the_repository, array, num_head); - if (num_head < 0) { + + ret = remove_redundant(the_repository, array, num_head, &num_head); + if (ret < 0) { free(array); return NULL; } + for (i = 0; i < num_head; i++) tail = &commit_list_insert(array[i], tail)->next; free(array); @@ -780,12 +786,12 @@ int commit_contains(struct ref_filter *filter, struct commit *commit, int can_all_from_reach_with_flag(struct object_array *from, unsigned int with_flag, unsigned int assign_flag, - time_t min_commit_date, + timestamp_t min_commit_date, timestamp_t min_generation) { struct commit **list = NULL; - int i; - int nr_commits; + size_t i; + size_t nr_commits; int result = 1; ALLOC_ARRAY(list, from->nr); @@ -883,9 +889,9 @@ int can_all_from_reach(struct commit_list *from, struct commit_list *to, int cutoff_by_min_date) { struct object_array from_objs = OBJECT_ARRAY_INIT; - time_t min_commit_date = cutoff_by_min_date ? from->item->date : 0; struct commit_list *from_iter = from, *to_iter = to; int result; + timestamp_t min_commit_date = cutoff_by_min_date ? from->item->date : 0; timestamp_t min_generation = GENERATION_NUMBER_INFINITY; while (from_iter) { @@ -937,8 +943,8 @@ int can_all_from_reach(struct commit_list *from, struct commit_list *to, return result; } -struct commit_list *get_reachable_subset(struct commit **from, int nr_from, - struct commit **to, int nr_to, +struct commit_list *get_reachable_subset(struct commit **from, size_t nr_from, + struct commit **to, size_t nr_to, unsigned int reachable_flag) { struct commit **item; diff --git a/commit-reach.h b/commit-reach.h index 9a745b7e176685..6012402dfcfe45 100644 --- a/commit-reach.h +++ b/commit-reach.h @@ -14,12 +14,12 @@ int repo_get_merge_bases(struct repository *r, struct commit *rev2, struct commit_list **result); int repo_get_merge_bases_many(struct repository *r, - struct commit *one, int n, + struct commit *one, size_t n, struct commit **twos, struct commit_list **result); /* To be used only when object flags after this call no longer matter */ int repo_get_merge_bases_many_dirty(struct repository *r, - struct commit *one, int n, + struct commit *one, size_t n, struct commit **twos, struct commit_list **result); @@ -81,7 +81,7 @@ int commit_contains(struct ref_filter *filter, struct commit *commit, int can_all_from_reach_with_flag(struct object_array *from, unsigned int with_flag, unsigned int assign_flag, - time_t min_commit_date, + timestamp_t min_commit_date, timestamp_t min_generation); int can_all_from_reach(struct commit_list *from, struct commit_list *to, int commit_date_cutoff); @@ -95,8 +95,8 @@ int can_all_from_reach(struct commit_list *from, struct commit_list *to, * This method uses the PARENT1 and PARENT2 flags during its operation, * so be sure these flags are not set before calling the method. */ -struct commit_list *get_reachable_subset(struct commit **from, int nr_from, - struct commit **to, int nr_to, +struct commit_list *get_reachable_subset(struct commit **from, size_t nr_from, + struct commit **to, size_t nr_to, unsigned int reachable_flag); struct ahead_behind_count { diff --git a/commit.c b/commit.c index 3a54e4db0d2085..6efdb03997d9a0 100644 --- a/commit.c +++ b/commit.c @@ -276,7 +276,7 @@ static int read_graft_file(struct repository *r, const char *graft_file) "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" - "\"git config advice.graftFileDeprecated false\"")); + "\"git config set advice.graftFileDeprecated false\"")); while (!strbuf_getwholeline(&buf, fp, '\n')) { /* The format is just "Commit Parent1 Parent2 ...\n" */ struct commit_graft *graft = read_graft_line(&buf); @@ -595,7 +595,8 @@ int repo_parse_commit_internal(struct repository *r, } ret = parse_commit_buffer(r, item, buffer, size, 0); - if (save_commit_buffer && !ret) { + if (save_commit_buffer && !ret && + !get_cached_commit_buffer(r, item, NULL)) { set_commit_buffer(r, item, buffer, size); return 0; } @@ -777,16 +778,16 @@ static void clear_commit_marks_1(struct commit_list **plist, } } -void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark) +void clear_commit_marks_many(size_t nr, struct commit **commit, unsigned int mark) { - struct commit_list *list = NULL; + for (size_t i = 0; i < nr; i++) { + struct commit_list *list = NULL; - while (nr--) { clear_commit_marks_1(&list, *commit, mark); + while (list) + clear_commit_marks_1(&list, pop_commit(&list), mark); commit++; } - while (list) - clear_commit_marks_1(&list, pop_commit(&list), mark); } void clear_commit_marks(struct commit *commit, unsigned int mark) @@ -1764,7 +1765,6 @@ int commit_tree_extended(const char *msg, size_t msg_len, { &compat_sig, r->compat_hash_algo }, { &sig, r->hash_algo }, }; - int i; /* * We write algorithms in the order they were implemented in @@ -1778,7 +1778,7 @@ int commit_tree_extended(const char *msg, size_t msg_len, * We traverse each algorithm in order, and apply the signature * to each buffer. */ - for (i = 0; i < ARRAY_SIZE(bufs); i++) { + for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) { if (!bufs[i].algo) continue; add_header_signature(&buffer, bufs[i].sig, bufs[i].algo); diff --git a/commit.h b/commit.h index 943e3d74b2ae02..70c870dae4d4b9 100644 --- a/commit.h +++ b/commit.h @@ -210,7 +210,7 @@ struct commit *pop_most_recent_commit(struct commit_list **list, struct commit *pop_commit(struct commit_list **stack); void clear_commit_marks(struct commit *commit, unsigned int mark); -void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark); +void clear_commit_marks_many(size_t nr, struct commit **commit, unsigned int mark); enum rev_sort_order { diff --git a/common-exit.c b/common-exit.c new file mode 100644 index 00000000000000..1aaa538be3ed67 --- /dev/null +++ b/common-exit.c @@ -0,0 +1,26 @@ +#include "git-compat-util.h" +#include "trace2.h" + +static void check_bug_if_BUG(void) +{ + if (!bug_called_must_BUG) + return; + BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()"); +} + +/* We wrap exit() to call common_exit() in git-compat-util.h */ +int common_exit(const char *file, int line, int code) +{ + /* + * For non-POSIX systems: Take the lowest 8 bits of the "code" + * to e.g. turn -1 into 255. On a POSIX system this is + * redundant, see exit(3) and wait(2), but as it doesn't harm + * anything there we don't need to guard this with an "ifdef". + */ + code &= 0xff; + + check_bug_if_BUG(); + trace2_cmd_exit_fl(file, line, code); + + return code; +} diff --git a/common-init.c b/common-init.c new file mode 100644 index 00000000000000..5cc73f058c222b --- /dev/null +++ b/common-init.c @@ -0,0 +1,63 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "git-compat-util.h" +#include "common-init.h" +#include "exec-cmd.h" +#include "gettext.h" +#include "attr.h" +#include "repository.h" +#include "setup.h" +#include "strbuf.h" +#include "trace2.h" + +/* + * Many parts of Git have subprograms communicate via pipe, expect the + * upstream of a pipe to die with SIGPIPE when the downstream of a + * pipe does not need to read all that is written. Some third-party + * programs that ignore or block SIGPIPE for their own reason forget + * to restore SIGPIPE handling to the default before spawning Git and + * break this carefully orchestrated machinery. + * + * Restore the way SIGPIPE is handled to default, which is what we + * expect. + */ +static void restore_sigpipe_to_default(void) +{ + sigset_t unblock; + + sigemptyset(&unblock); + sigaddset(&unblock, SIGPIPE); + sigprocmask(SIG_UNBLOCK, &unblock, NULL); + signal(SIGPIPE, SIG_DFL); +} + +void init_git(const char **argv) +{ + struct strbuf tmp = STRBUF_INIT; + + trace2_initialize_clock(); + + /* + * Always open file descriptors 0/1/2 to avoid clobbering files + * in die(). It also avoids messing up when the pipes are dup'ed + * onto stdin/stdout/stderr in the child processes we spawn. + */ + sanitize_stdfds(); + restore_sigpipe_to_default(); + + git_resolve_executable_dir(argv[0]); + + setlocale(LC_CTYPE, ""); + git_setup_gettext(); + + initialize_repository(the_repository); + + attr_start(); + + trace2_initialize(); + trace2_cmd_start(argv); + trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP); + + if (!strbuf_getcwd(&tmp)) + tmp_original_cwd = strbuf_detach(&tmp, NULL); +} diff --git a/common-init.h b/common-init.h new file mode 100644 index 00000000000000..3e6db20cae9b2d --- /dev/null +++ b/common-init.h @@ -0,0 +1,6 @@ +#ifndef COMMON_INIT_H +#define COMMON_INIT_H + +void init_git(const char **argv); + +#endif /* COMMON_INIT_H */ diff --git a/common-main.c b/common-main.c index 8e68ac9e42993d..6b7ab077b0ab85 100644 --- a/common-main.c +++ b/common-main.c @@ -1,92 +1,13 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" -#include "exec-cmd.h" -#include "gettext.h" -#include "attr.h" -#include "repository.h" -#include "setup.h" -#include "strbuf.h" -#include "trace2.h" - -/* - * Many parts of Git have subprograms communicate via pipe, expect the - * upstream of a pipe to die with SIGPIPE when the downstream of a - * pipe does not need to read all that is written. Some third-party - * programs that ignore or block SIGPIPE for their own reason forget - * to restore SIGPIPE handling to the default before spawning Git and - * break this carefully orchestrated machinery. - * - * Restore the way SIGPIPE is handled to default, which is what we - * expect. - */ -static void restore_sigpipe_to_default(void) -{ - sigset_t unblock; - - sigemptyset(&unblock); - sigaddset(&unblock, SIGPIPE); - sigprocmask(SIG_UNBLOCK, &unblock, NULL); - signal(SIGPIPE, SIG_DFL); -} +#include "common-init.h" int main(int argc, const char **argv) { int result; - struct strbuf tmp = STRBUF_INIT; - - trace2_initialize_clock(); - - /* - * Always open file descriptors 0/1/2 to avoid clobbering files - * in die(). It also avoids messing up when the pipes are dup'ed - * onto stdin/stdout/stderr in the child processes we spawn. - */ - sanitize_stdfds(); - restore_sigpipe_to_default(); - - git_resolve_executable_dir(argv[0]); - - setlocale(LC_CTYPE, ""); - git_setup_gettext(); - - initialize_repository(the_repository); - - attr_start(); - - trace2_initialize(); - trace2_cmd_start(argv); - trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP); - - if (!strbuf_getcwd(&tmp)) - tmp_original_cwd = strbuf_detach(&tmp, NULL); + init_git(argv); result = cmd_main(argc, argv); /* Not exit(3), but a wrapper calling our common_exit() */ exit(result); } - -static void check_bug_if_BUG(void) -{ - if (!bug_called_must_BUG) - return; - BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()"); -} - -/* We wrap exit() to call common_exit() in git-compat-util.h */ -int common_exit(const char *file, int line, int code) -{ - /* - * For non-POSIX systems: Take the lowest 8 bits of the "code" - * to e.g. turn -1 into 255. On a POSIX system this is - * redundant, see exit(3) and wait(2), but as it doesn't harm - * anything there we don't need to guard this with an "ifdef". - */ - code &= 0xff; - - check_bug_if_BUG(); - trace2_cmd_exit_fl(file, line, code); - - return code; -} diff --git a/compat/bswap.h b/compat/bswap.h index 512f6f4b9937c8..b34054f2bd7284 100644 --- a/compat/bswap.h +++ b/compat/bswap.h @@ -171,23 +171,23 @@ static inline uint64_t get_be64(const void *ptr) static inline void put_be32(void *ptr, uint32_t value) { unsigned char *p = ptr; - p[0] = value >> 24; - p[1] = value >> 16; - p[2] = value >> 8; - p[3] = value >> 0; + p[0] = (value >> 24) & 0xff; + p[1] = (value >> 16) & 0xff; + p[2] = (value >> 8) & 0xff; + p[3] = (value >> 0) & 0xff; } static inline void put_be64(void *ptr, uint64_t value) { unsigned char *p = ptr; - p[0] = value >> 56; - p[1] = value >> 48; - p[2] = value >> 40; - p[3] = value >> 32; - p[4] = value >> 24; - p[5] = value >> 16; - p[6] = value >> 8; - p[7] = value >> 0; + p[0] = (value >> 56) & 0xff; + p[1] = (value >> 48) & 0xff; + p[2] = (value >> 40) & 0xff; + p[3] = (value >> 32) & 0xff; + p[4] = (value >> 24) & 0xff; + p[5] = (value >> 16) & 0xff; + p[6] = (value >> 8) & 0xff; + p[7] = (value >> 0) & 0xff; } #endif /* COMPAT_BSWAP_H */ diff --git a/compat/compiler.h b/compat/compiler.h index e9ad9db84f2279..e12e426404ab0c 100644 --- a/compat/compiler.h +++ b/compat/compiler.h @@ -9,7 +9,7 @@ static inline void get_compiler_info(struct strbuf *info) { - int len = info->len; + size_t len = info->len; #ifdef __clang__ strbuf_addf(info, "clang: %s\n", __clang_version__); #elif defined(__GNUC__) @@ -27,7 +27,7 @@ static inline void get_compiler_info(struct strbuf *info) static inline void get_libc_info(struct strbuf *info) { - int len = info->len; + size_t len = info->len; #ifdef __GLIBC__ strbuf_addf(info, "glibc: %s\n", gnu_get_libc_version()); diff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c index 2fc67442eb5e87..43c3a915a0edfc 100644 --- a/compat/fsmonitor/fsm-listen-darwin.c +++ b/compat/fsmonitor/fsm-listen-darwin.c @@ -208,13 +208,12 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef UNUSED, const char *slash; char *resolved = NULL; struct strbuf tmp = STRBUF_INIT; - int k; /* * Build a list of all filesystem changes into a private/local * list and without holding any locks. */ - for (k = 0; k < num_of_events; k++) { + for (size_t k = 0; k < num_of_events; k++) { /* * On Mac, we receive an array of absolute paths. */ @@ -516,6 +515,12 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state) } data->stream_started = 1; + /* + * Our fs event listener is now running, so it's safe to start + * serving client requests. + */ + ipc_server_start_async(state->ipc_server_data); + pthread_mutex_lock(&data->dq_lock); pthread_cond_wait(&data->dq_finished, &data->dq_lock); pthread_mutex_unlock(&data->dq_lock); diff --git a/compat/fsmonitor/fsm-listen-win32.c b/compat/fsmonitor/fsm-listen-win32.c index 5a21dade7b8659..9a6efc9bea340b 100644 --- a/compat/fsmonitor/fsm-listen-win32.c +++ b/compat/fsmonitor/fsm-listen-win32.c @@ -431,9 +431,9 @@ static int recv_rdcw_watch(struct one_watch *watch) * but I observed ERROR_ACCESS_DENIED (0x05) errors during * testing. * - * Note that we only get notificaiton events for events + * Note that we only get notification events for events * *within* the directory, not *on* the directory itself. - * (These might be properies of the parent directory, for + * (These might be properties of the parent directory, for * example). * * NEEDSWORK: We might try to check for the deleted directory @@ -741,6 +741,12 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state) start_rdcw_watch(data->watch_gitdir) == -1) goto force_error_stop; + /* + * Now that we've established the rdcw watches, we can start + * serving clients. + */ + ipc_server_start_async(state->ipc_server_data); + for (;;) { dwWait = WaitForMultipleObjects(data->nr_listener_handles, data->hListener, diff --git a/compat/mingw.c b/compat/mingw.c index 0e851ecae29b90..f524c54d06d965 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "../git-compat-util.h" #include "win32.h" @@ -502,7 +503,7 @@ static int mingw_open_append(wchar_t const *wfilename, int oflags, ...) * to append to the file. */ handle = CreateFileW(wfilename, FILE_APPEND_DATA, - FILE_SHARE_WRITE | FILE_SHARE_READ, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); @@ -532,6 +533,70 @@ static int mingw_open_append(wchar_t const *wfilename, int oflags, ...) return fd; } +/* + * Ideally, we'd use `_wopen()` to implement this functionality so that we + * don't have to reimplement it, but unfortunately we do not have tight control + * over the share mode there. And while `_wsopen()` and friends exist that give + * us _some_ control over the share mode, this family of functions doesn't give + * us the ability to enable FILE_SHARE_DELETE, either. But this is a strict + * requirement for us though so that we can unlink or rename over files that + * are held open by another process. + * + * We are thus forced to implement our own emulation of `open()`. To make our + * life simpler we only implement basic support for this, namely opening + * existing files for reading and/or writing. This means that newly created + * files won't have their sharing mode set up correctly, but for now I couldn't + * find any case where this matters. We may have to revisit that in the future + * though based on our needs. + */ +static int mingw_open_existing(const wchar_t *filename, int oflags, ...) +{ + SECURITY_ATTRIBUTES security_attributes = { + .nLength = sizeof(security_attributes), + .bInheritHandle = !(oflags & O_NOINHERIT), + }; + HANDLE handle; + DWORD access; + int fd; + + /* We only support basic flags. */ + if (oflags & ~(O_ACCMODE | O_NOINHERIT)) { + errno = ENOSYS; + return -1; + } + + switch (oflags & O_ACCMODE) { + case O_RDWR: + access = GENERIC_READ | GENERIC_WRITE; + break; + case O_WRONLY: + access = GENERIC_WRITE; + break; + default: + access = GENERIC_READ; + break; + } + + handle = CreateFileW(filename, access, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (handle == INVALID_HANDLE_VALUE) { + DWORD err = GetLastError(); + + /* See `mingw_open_append()` for why we have this conversion. */ + if (err == ERROR_INVALID_PARAMETER) + err = ERROR_PATH_NOT_FOUND; + + errno = err_win_to_posix(err); + return -1; + } + + fd = _open_osfhandle((intptr_t)handle, oflags | O_BINARY); + if (fd < 0) + CloseHandle(handle); + return fd; +} + /* * Does the pathname map to the local named pipe filesystem? * That is, does it have a "//./pipe/" prefix? @@ -567,6 +632,8 @@ int mingw_open (const char *filename, int oflags, ...) if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename)) open_fn = mingw_open_append; + else if (!(oflags & ~(O_ACCMODE | O_NOINHERIT))) + open_fn = mingw_open_existing; else open_fn = _wopen; @@ -782,7 +849,7 @@ static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts) */ static int has_valid_directory_prefix(wchar_t *wfilename) { - int n = wcslen(wfilename); + size_t n = wcslen(wfilename); while (n > 0) { wchar_t c = wfilename[--n]; @@ -891,7 +958,7 @@ static int do_lstat(int follow, const char *file_name, struct stat *buf) */ static int do_stat_internal(int follow, const char *file_name, struct stat *buf) { - int namelen; + size_t namelen; char alt_name[PATH_MAX]; if (!do_lstat(follow, file_name, buf)) @@ -1006,7 +1073,7 @@ int mingw_utime (const char *file_name, const struct utimbuf *times) osfilehandle = CreateFileW(wfilename, FILE_WRITE_ATTRIBUTES, - 0 /*FileShare.None*/, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, (attrs != INVALID_FILE_ATTRIBUTES && @@ -1274,7 +1341,8 @@ static const char *parse_interpreter(const char *cmd) { static char buf[100]; char *p, *opt; - int n, fd; + ssize_t n; /* read() can return negative values */ + int fd; /* don't even try a .exe */ n = strlen(cmd); @@ -1339,7 +1407,7 @@ static char *path_lookup(const char *cmd, int exe_only) { const char *path; char *prog = NULL; - int len = strlen(cmd); + size_t len = strlen(cmd); int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe"); if (strpbrk(cmd, "/\\")) @@ -1956,7 +2024,7 @@ char *mingw_getenv(const char *name) #define GETENV_MAX_RETAIN 64 static char *values[GETENV_MAX_RETAIN]; static int value_counter; - int len_key, len_value; + size_t len_key, len_value; wchar_t *w_key; char *value; wchar_t w_value[32768]; @@ -1968,7 +2036,8 @@ char *mingw_getenv(const char *name) /* We cannot use xcalloc() here because that uses getenv() itself */ w_key = calloc(len_key, sizeof(wchar_t)); if (!w_key) - die("Out of memory, (tried to allocate %u wchar_t's)", len_key); + die("Out of memory, (tried to allocate %"PRIuMAX" wchar_t's)", + (uintmax_t)len_key); xutftowcs(w_key, name, len_key); /* GetEnvironmentVariableW() only sets the last error upon failure */ SetLastError(ERROR_SUCCESS); @@ -1983,7 +2052,8 @@ char *mingw_getenv(const char *name) /* We cannot use xcalloc() here because that uses getenv() itself */ value = calloc(len_value, sizeof(char)); if (!value) - die("Out of memory, (tried to allocate %u bytes)", len_value); + die("Out of memory, (tried to allocate %"PRIuMAX" bytes)", + (uintmax_t)len_value); xwcstoutf(value, w_value, len_value); /* @@ -2001,7 +2071,7 @@ char *mingw_getenv(const char *name) int mingw_putenv(const char *namevalue) { - int size; + size_t size; wchar_t *wide, *equal; BOOL result; @@ -2011,7 +2081,8 @@ int mingw_putenv(const char *namevalue) size = strlen(namevalue) * 2 + 1; wide = calloc(size, sizeof(wchar_t)); if (!wide) - die("Out of memory, (tried to allocate %u wchar_t's)", size); + die("Out of memory, (tried to allocate %" PRIuMAX " wchar_t's)", + (uintmax_t)size); xutftowcs(wide, namevalue, size); equal = wcschr(wide, L'='); if (!equal) @@ -2151,10 +2222,16 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz) #undef rename int mingw_rename(const char *pold, const char *pnew) { + static int supports_file_rename_info_ex = 1; DWORD attrs, gle; int tries = 0; wchar_t wpold[MAX_PATH], wpnew[MAX_PATH]; - if (xutftowcs_path(wpold, pold) < 0 || xutftowcs_path(wpnew, pnew) < 0) + int wpnew_len; + + if (xutftowcs_path(wpold, pold) < 0) + return -1; + wpnew_len = xutftowcs_path(wpnew, pnew); + if (wpnew_len < 0) return -1; /* @@ -2165,11 +2242,86 @@ int mingw_rename(const char *pold, const char *pnew) return 0; if (errno != EEXIST) return -1; + repeat: - if (MoveFileExW(wpold, wpnew, MOVEFILE_REPLACE_EXISTING)) - return 0; + if (supports_file_rename_info_ex) { + /* + * Our minimum required Windows version is still set to Windows + * Vista. We thus have to declare required infrastructure for + * FileRenameInfoEx ourselves until we bump _WIN32_WINNT to + * 0x0A00. Furthermore, we have to handle cases where the + * FileRenameInfoEx call isn't supported yet. + */ +#define FILE_RENAME_FLAG_REPLACE_IF_EXISTS 0x00000001 +#define FILE_RENAME_FLAG_POSIX_SEMANTICS 0x00000002 + FILE_INFO_BY_HANDLE_CLASS FileRenameInfoEx = 22; + struct { + /* + * This is usually an unnamed union, but that is not + * part of ISO C99. We thus inline the field, as we + * really only care for the Flags field anyway. + */ + DWORD Flags; + HANDLE RootDirectory; + DWORD FileNameLength; + /* + * The actual structure is defined with a single-character + * flex array so that the structure has to be allocated on + * the heap. As we declare this structure ourselves though + * we can avoid the allocation and define FileName to have + * MAX_PATH bytes. + */ + WCHAR FileName[MAX_PATH]; + } rename_info = { 0 }; + HANDLE old_handle = INVALID_HANDLE_VALUE; + BOOL success; + + old_handle = CreateFileW(wpold, DELETE, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, + NULL); + if (old_handle == INVALID_HANDLE_VALUE) { + errno = err_win_to_posix(GetLastError()); + return -1; + } + + rename_info.Flags = FILE_RENAME_FLAG_REPLACE_IF_EXISTS | + FILE_RENAME_FLAG_POSIX_SEMANTICS; + rename_info.FileNameLength = wpnew_len * sizeof(WCHAR); + memcpy(rename_info.FileName, wpnew, wpnew_len * sizeof(WCHAR)); + + success = SetFileInformationByHandle(old_handle, FileRenameInfoEx, + &rename_info, sizeof(rename_info)); + gle = GetLastError(); + CloseHandle(old_handle); + if (success) + return 0; + + /* + * When we see ERROR_INVALID_PARAMETER we can assume that the + * current system doesn't support FileRenameInfoEx. Keep us + * from using it in future calls and retry. + */ + if (gle == ERROR_INVALID_PARAMETER) { + supports_file_rename_info_ex = 0; + goto repeat; + } + + /* + * In theory, we shouldn't get ERROR_ACCESS_DENIED because we + * always open files with FILE_SHARE_DELETE But in practice we + * cannot assume that Git is the only one accessing files, and + * other applications may not set FILE_SHARE_DELETE. So we have + * to retry. + */ + } else { + if (MoveFileExW(wpold, wpnew, MOVEFILE_REPLACE_EXISTING)) + return 0; + gle = GetLastError(); + } + /* TODO: translate more errors */ - gle = GetLastError(); if (gle == ERROR_ACCESS_DENIED && (attrs = GetFileAttributesW(wpnew)) != INVALID_FILE_ATTRIBUTES) { if (attrs & FILE_ATTRIBUTE_DIRECTORY) { @@ -3085,7 +3237,8 @@ static void maybe_redirect_std_handles(void) */ int wmain(int argc, const wchar_t **wargv) { - int i, maxlen, exit_status; + int i, exit_status; + size_t maxlen; char *buffer, **save; const char **argv; diff --git a/compat/poll/poll.c b/compat/poll/poll.c index afa6d245846a41..a2becd16cd0bd0 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -18,6 +18,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#define DISABLE_SIGN_COMPARE_WARNINGS + /* To bump the minimum Windows version to Windows Vista */ #include "git-compat-util.h" diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index f7cc7b3be59751..12e38e0ea3c570 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -50,15 +50,15 @@ void probe_utf8_pathname_composition(void) int output_fd; if (precomposed_unicode != -1) return; /* We found it defined in the global config, respect it */ - git_path_buf(&path, "%s", auml_nfc); + repo_git_path_replace(the_repository, &path, "%s", auml_nfc); output_fd = open(path.buf, O_CREAT|O_EXCL|O_RDWR, 0600); if (output_fd >= 0) { close(output_fd); - git_path_buf(&path, "%s", auml_nfd); + repo_git_path_replace(the_repository, &path, "%s", auml_nfd); precomposed_unicode = access(path.buf, R_OK) ? 0 : 1; git_config_set("core.precomposeunicode", precomposed_unicode ? "true" : "false"); - git_path_buf(&path, "%s", auml_nfc); + repo_git_path_replace(the_repository, &path, "%s", auml_nfc); if (unlink(path.buf)) die_errno(_("failed to unlink '%s'"), path.buf); } diff --git a/compat/regex/regex.c b/compat/regex/regex.c index e6f4a5d177bb7d..4b09cc4e1457dc 100644 --- a/compat/regex/regex.c +++ b/compat/regex/regex.c @@ -17,6 +17,8 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#pragma GCC diagnostic ignored "-Wsign-compare" + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/compat/regex/regexec.c b/compat/regex/regexec.c index e92be5741d14c5..2eeec82f4077b7 100644 --- a/compat/regex/regexec.c +++ b/compat/regex/regexec.c @@ -292,7 +292,7 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); concerned. If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match - and all groups is stroed in REGS. (For the "_2" variants, the offsets are + and all groups are stored in REGS. (For the "_2" variants, the offsets are computed relative to the concatenation, not relative to the individual strings.) diff --git a/compat/simple-ipc/ipc-shared.c b/compat/simple-ipc/ipc-shared.c index cb176d966f287d..d1c21b49bdba8d 100644 --- a/compat/simple-ipc/ipc-shared.c +++ b/compat/simple-ipc/ipc-shared.c @@ -16,11 +16,12 @@ int ipc_server_run(const char *path, const struct ipc_server_opts *opts, struct ipc_server_data *server_data = NULL; int ret; - ret = ipc_server_run_async(&server_data, path, opts, - application_cb, application_data); + ret = ipc_server_init_async(&server_data, path, opts, + application_cb, application_data); if (ret) return ret; + ipc_server_start_async(server_data); ret = ipc_server_await(server_data); ipc_server_free(server_data); diff --git a/compat/simple-ipc/ipc-unix-socket.c b/compat/simple-ipc/ipc-unix-socket.c index 9b3f2cdf8c9608..7db3b2a89755c6 100644 --- a/compat/simple-ipc/ipc-unix-socket.c +++ b/compat/simple-ipc/ipc-unix-socket.c @@ -328,6 +328,7 @@ struct ipc_server_data { int back_pos; int front_pos; + int started; int shutdown_requested; int is_stopped; }; @@ -712,7 +713,7 @@ static int accept_thread__wait_for_connection( * Block SIGPIPE in this thread for the life of the thread. This * avoids any stray SIGPIPE signals when closing pipe fds under * extremely heavy loads (such as when the fifo queue is full and we - * drop incomming connections). + * drop incoming connections). */ static void *accept_thread_proc(void *_accept_thread_data) { @@ -824,10 +825,10 @@ static int setup_listener_socket( /* * Start IPC server in a pool of background threads. */ -int ipc_server_run_async(struct ipc_server_data **returned_server_data, - const char *path, const struct ipc_server_opts *opts, - ipc_server_application_cb *application_cb, - void *application_data) +int ipc_server_init_async(struct ipc_server_data **returned_server_data, + const char *path, const struct ipc_server_opts *opts, + ipc_server_application_cb *application_cb, + void *application_data) { struct unix_ss_socket *server_socket = NULL; struct ipc_server_data *server_data; @@ -888,6 +889,12 @@ int ipc_server_run_async(struct ipc_server_data **returned_server_data, server_data->accept_thread->fd_send_shutdown = sv[0]; server_data->accept_thread->fd_wait_shutdown = sv[1]; + /* + * Hold work-available mutex so that no work can start until + * we unlock it. + */ + pthread_mutex_lock(&server_data->work_available_mutex); + if (pthread_create(&server_data->accept_thread->pthread_id, NULL, accept_thread_proc, server_data->accept_thread)) die_errno(_("could not start accept_thread '%s'"), path); @@ -918,6 +925,15 @@ int ipc_server_run_async(struct ipc_server_data **returned_server_data, return 0; } +void ipc_server_start_async(struct ipc_server_data *server_data) +{ + if (!server_data || server_data->started) + return; + + server_data->started = 1; + pthread_mutex_unlock(&server_data->work_available_mutex); +} + /* * Gently tell the IPC server treads to shutdown. * Can be run on any thread. @@ -933,7 +949,9 @@ int ipc_server_stop_async(struct ipc_server_data *server_data) trace2_region_enter("ipc-server", "server-stop-async", NULL); - pthread_mutex_lock(&server_data->work_available_mutex); + /* If we haven't started yet, we are already holding lock. */ + if (server_data->started) + pthread_mutex_lock(&server_data->work_available_mutex); server_data->shutdown_requested = 1; diff --git a/compat/simple-ipc/ipc-win32.c b/compat/simple-ipc/ipc-win32.c index 8bfe51248e552e..a8fc812adfcbd3 100644 --- a/compat/simple-ipc/ipc-win32.c +++ b/compat/simple-ipc/ipc-win32.c @@ -371,6 +371,9 @@ struct ipc_server_data { HANDLE hEventStopRequested; struct ipc_server_thread_data *thread_list; int is_stopped; + + pthread_mutex_t startup_barrier; + int started; }; enum connect_result { @@ -526,6 +529,16 @@ static int use_connection(struct ipc_server_thread_data *server_thread_data) return ret; } +static void wait_for_startup_barrier(struct ipc_server_data *server_data) +{ + /* + * Temporarily hold the startup_barrier mutex before starting, + * which lets us know that it's OK to start serving requests. + */ + pthread_mutex_lock(&server_data->startup_barrier); + pthread_mutex_unlock(&server_data->startup_barrier); +} + /* * Thread proc for an IPC server worker thread. It handles a series of * connections from clients. It cleans and reuses the hPipe between each @@ -550,6 +563,8 @@ static void *server_thread_proc(void *_server_thread_data) memset(&oConnect, 0, sizeof(oConnect)); oConnect.hEvent = hEventConnected; + wait_for_startup_barrier(server_thread_data->server_data); + for (;;) { cr = wait_for_connection(server_thread_data, &oConnect); @@ -752,10 +767,10 @@ static HANDLE create_new_pipe(wchar_t *wpath, int is_first) return hPipe; } -int ipc_server_run_async(struct ipc_server_data **returned_server_data, - const char *path, const struct ipc_server_opts *opts, - ipc_server_application_cb *application_cb, - void *application_data) +int ipc_server_init_async(struct ipc_server_data **returned_server_data, + const char *path, const struct ipc_server_opts *opts, + ipc_server_application_cb *application_cb, + void *application_data) { struct ipc_server_data *server_data; wchar_t wpath[MAX_PATH]; @@ -787,6 +802,13 @@ int ipc_server_run_async(struct ipc_server_data **returned_server_data, strbuf_addstr(&server_data->buf_path, path); wcscpy(server_data->wpath, wpath); + /* + * Hold the startup_barrier lock so that no threads will progress + * until ipc_server_start_async() is called. + */ + pthread_mutex_init(&server_data->startup_barrier, NULL); + pthread_mutex_lock(&server_data->startup_barrier); + if (nr_threads < 1) nr_threads = 1; @@ -837,6 +859,15 @@ int ipc_server_run_async(struct ipc_server_data **returned_server_data, return 0; } +void ipc_server_start_async(struct ipc_server_data *server_data) +{ + if (!server_data || server_data->started) + return; + + server_data->started = 1; + pthread_mutex_unlock(&server_data->startup_barrier); +} + int ipc_server_stop_async(struct ipc_server_data *server_data) { if (!server_data) @@ -850,6 +881,13 @@ int ipc_server_stop_async(struct ipc_server_data *server_data) * We DO NOT attempt to force them to drop an active connection. */ SetEvent(server_data->hEventStopRequested); + + /* + * If we haven't yet told the threads they are allowed to run, + * do so now, so they can receive the shutdown event. + */ + ipc_server_start_async(server_data); + return 0; } @@ -900,5 +938,7 @@ void ipc_server_free(struct ipc_server_data *server_data) free(std); } + pthread_mutex_destroy(&server_data->startup_barrier); + free(server_data); } diff --git a/compat/terminal.c b/compat/terminal.c index d54efa1c5d6ebf..584f27bf7e1078 100644 --- a/compat/terminal.c +++ b/compat/terminal.c @@ -259,14 +259,13 @@ static DWORD cmode_in, cmode_out; void restore_term(void) { if (use_stty) { - int i; struct child_process cp = CHILD_PROCESS_INIT; if (stty_restore.nr == 0) return; strvec_push(&cp.args, "stty"); - for (i = 0; i < stty_restore.nr; i++) + for (size_t i = 0; i < stty_restore.nr; i++) strvec_push(&cp.args, stty_restore.items[i].string); run_command(&cp); string_list_clear(&stty_restore, 0); diff --git a/compat/vcbuild/include/unistd.h b/compat/vcbuild/include/unistd.h index 3a959d124ca794..a261a925b7f850 100644 --- a/compat/vcbuild/include/unistd.h +++ b/compat/vcbuild/include/unistd.h @@ -14,7 +14,11 @@ typedef _mode_t mode_t; #ifndef _SSIZE_T_ #define _SSIZE_T_ +#ifdef _WIN64 +typedef __int64 _ssize_t; +#else typedef long _ssize_t; +#endif /* _WIN64 */ #ifndef _OFF_T_ #define _OFF_T_ diff --git a/compat/win32/headless.c b/compat/win32/headless.c index 11392a0b9a6dac..a6eb116ddc7b58 100644 --- a/compat/win32/headless.c +++ b/compat/win32/headless.c @@ -53,7 +53,8 @@ int WINAPI wWinMain(_In_ HINSTANCE instance, wchar_t git_command_line[32768]; size_t size = sizeof(git_command_line) / sizeof(wchar_t); const wchar_t *needs_quotes = L""; - int slash = 0, i; + size_t slash = 0; + int len; STARTUPINFO startup_info = { .cb = sizeof(STARTUPINFO), @@ -66,7 +67,7 @@ int WINAPI wWinMain(_In_ HINSTANCE instance, DWORD exit_code; /* First, determine the full path of argv[0] */ - for (i = 0; _wpgmptr[i]; i++) + for (size_t i = 0; _wpgmptr[i]; i++) if (_wpgmptr[i] == L' ') needs_quotes = L"\""; else if (_wpgmptr[i] == L'\\') @@ -79,16 +80,16 @@ int WINAPI wWinMain(_In_ HINSTANCE instance, extend_path(_wpgmptr, slash); /* Then, add the full path of `git.exe` as argv[0] */ - i = swprintf_s(git_command_line, size, L"%ls%.*ls\\git.exe%ls", - needs_quotes, slash, _wpgmptr, needs_quotes); - if (i < 0) + len = swprintf_s(git_command_line, size, L"%ls%.*ls\\git.exe%ls", + needs_quotes, (int) slash, _wpgmptr, needs_quotes); + if (len < 0) return 127; /* Too long path */ if (*command_line) { /* Now, append the command-line arguments */ - i = swprintf_s(git_command_line + i, size - i, - L" %ls", command_line); - if (i < 0) + len = swprintf_s(git_command_line + len, size - len, + L" %ls", command_line); + if (len < 0) return 127; } diff --git a/compat/win32mmap.c b/compat/win32mmap.c index a4ab4cb939399b..e9519343167be1 100644 --- a/compat/win32mmap.c +++ b/compat/win32mmap.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "../git-compat-util.h" void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) diff --git a/compat/winansi.c b/compat/winansi.c index 1b3f916b9fc409..ac2ffb78691a7d 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -4,6 +4,8 @@ #undef NOGDI +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "../git-compat-util.h" #include <wingdi.h> #include <winreg.h> diff --git a/compat/zlib-compat.h b/compat/zlib-compat.h new file mode 100644 index 00000000000000..0c60e3af331fb5 --- /dev/null +++ b/compat/zlib-compat.h @@ -0,0 +1,53 @@ +#ifndef COMPAT_ZLIB_H +#define COMPAT_ZLIB_H + +#ifdef HAVE_ZLIB_NG +# include <zlib-ng.h> + +# define z_stream zng_stream +#define gz_header_s zng_gz_header_s + +# define crc32(crc, buf, len) zng_crc32(crc, buf, len) + +# define inflate(strm, bits) zng_inflate(strm, bits) +# define inflateEnd(strm) zng_inflateEnd(strm) +# define inflateInit(strm) zng_inflateInit(strm) +# define inflateInit2(strm, bits) zng_inflateInit2(strm, bits) +# define inflateReset(strm) zng_inflateReset(strm) + +# define deflate(strm, flush) zng_deflate(strm, flush) +# define deflateBound(strm, source_len) zng_deflateBound(strm, source_len) +# define deflateEnd(strm) zng_deflateEnd(strm) +# define deflateInit(strm, level) zng_deflateInit(strm, level) +# define deflateInit2(stream, level, method, window_bits, mem_level, strategy) zng_deflateInit2(stream, level, method, window_bits, mem_level, strategy) +# define deflateReset(strm) zng_deflateReset(strm) +# define deflateSetHeader(strm, head) zng_deflateSetHeader(strm, head) + +#else +# include <zlib.h> + +# if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200 +# define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11) +# endif + +/* + * zlib only gained support for setting up the gzip header in v1.2.2.1. In + * Git we only set the header to make archives reproducible across different + * operating systems, so it's fine to simply make this a no-op when using a + * zlib version that doesn't support this yet. + */ +# if ZLIB_VERNUM < 0x1221 +struct gz_header_s { + int os; +}; + +static int deflateSetHeader(z_streamp strm, struct gz_header_s *head) +{ + (void)(strm); + (void)(head); + return Z_OK; +} +# endif +#endif /* HAVE_ZLIB_NG */ + +#endif /* COMPAT_ZLIB_H */ diff --git a/compat/zlib-uncompress2.c b/compat/zlib-uncompress2.c deleted file mode 100644 index 77a1b08048463d..00000000000000 --- a/compat/zlib-uncompress2.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "git-compat-util.h" - -#if ZLIB_VERNUM < 0x1290 -/* taken from zlib's uncompr.c - - commit cacf7f1d4e3d44d871b605da3b647f07d718623f - Author: Mark Adler <madler@alumni.caltech.edu> - Date: Sun Jan 15 09:18:46 2017 -0800 - - zlib 1.2.11 - -*/ - -/* - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* clang-format off */ - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2 ( - Bytef *dest, - uLongf *destLen, - const Bytef *source, - uLong *sourceLen) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} -#else -static void *dummy_variable = &dummy_variable; -#endif diff --git a/config.c b/config.c index a11bb85da303a7..658569af084897 100644 --- a/config.c +++ b/config.c @@ -7,6 +7,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -18,6 +19,7 @@ #include "convert.h" #include "environment.h" #include "gettext.h" +#include "git-zlib.h" #include "ident.h" #include "repository.h" #include "lockfile.h" @@ -1435,11 +1437,6 @@ static int git_default_core_config(const char *var, const char *value, return git_config_pathname(&git_attributes_file, var, value); } - if (!strcmp(var, "core.hookspath")) { - FREE_AND_NULL(git_hooks_path); - return git_config_pathname(&git_hooks_path, var, value); - } - if (!strcmp(var, "core.bare")) { is_bare_repository_cfg = git_config_bool(var, value); return 0; @@ -1493,33 +1490,11 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.packedgitwindowsize")) { - int pgsz_x2 = getpagesize() * 2; - packed_git_window_size = git_config_ulong(var, value, ctx->kvi); - - /* This value must be multiple of (pagesize * 2) */ - packed_git_window_size /= pgsz_x2; - if (packed_git_window_size < 1) - packed_git_window_size = 1; - packed_git_window_size *= pgsz_x2; - return 0; - } - if (!strcmp(var, "core.bigfilethreshold")) { big_file_threshold = git_config_ulong(var, value, ctx->kvi); return 0; } - if (!strcmp(var, "core.packedgitlimit")) { - packed_git_limit = git_config_ulong(var, value, ctx->kvi); - return 0; - } - - if (!strcmp(var, "core.deltabasecachelimit")) { - delta_base_cache_limit = git_config_ulong(var, value, ctx->kvi); - return 0; - } - if (!strcmp(var, "core.autocrlf")) { if (value && !strcasecmp(value, "input")) { auto_crlf = AUTO_CRLF_INPUT; @@ -1672,7 +1647,7 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - /* Add other config variables here and to Documentation/config.txt. */ + /* Add other config variables here and to Documentation/config.adoc. */ return platform_core_config(var, value, ctx, cb); } @@ -1683,7 +1658,7 @@ static int git_default_sparse_config(const char *var, const char *value) return 0; } - /* Add other config variables here and to Documentation/config/sparse.txt. */ + /* Add other config variables here and to Documentation/config/sparse.adoc. */ return 0; } @@ -1699,7 +1674,7 @@ static int git_default_i18n_config(const char *var, const char *value) return git_config_string(&git_log_output_encoding, var, value); } - /* Add other config variables here and to Documentation/config.txt. */ + /* Add other config variables here and to Documentation/config.adoc. */ return 0; } @@ -1735,7 +1710,7 @@ static int git_default_branch_config(const char *var, const char *value) return 0; } - /* Add other config variables here and to Documentation/config.txt. */ + /* Add other config variables here and to Documentation/config.adoc. */ return 0; } @@ -1764,7 +1739,7 @@ static int git_default_push_config(const char *var, const char *value) return 0; } - /* Add other config variables here and to Documentation/config.txt. */ + /* Add other config variables here and to Documentation/config.adoc. */ return 0; } @@ -1780,7 +1755,7 @@ static int git_default_mailmap_config(const char *var, const char *value) return git_config_string(&git_mailmap_blob, var, value); } - /* Add other config variables here and to Documentation/config.txt. */ + /* Add other config variables here and to Documentation/config.adoc. */ return 0; } @@ -1793,7 +1768,7 @@ static int git_default_attr_config(const char *var, const char *value) /* * Add other attribute related config variables here and to - * Documentation/config/attr.txt. + * Documentation/config/attr.adoc. */ return 0; } @@ -1851,7 +1826,7 @@ int git_default_config(const char *var, const char *value, if (starts_with(var, "sparse.")) return git_default_sparse_config(var, value); - /* Add other config variables here and to Documentation/config.txt. */ + /* Add other config variables here and to Documentation/config.adoc. */ return 0; } diff --git a/config.mak.dev b/config.mak.dev index 8eca7fa22823b4..0fd8cc4d355ebb 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -53,7 +53,6 @@ ifeq ($(filter extra-all,$(DEVOPTS)),) # These are disabled because we have these all over the place. DEVELOPER_CFLAGS += -Wno-empty-body DEVELOPER_CFLAGS += -Wno-missing-field-initializers -DEVELOPER_CFLAGS += -Wno-sign-compare endif endif diff --git a/config.mak.uname b/config.mak.uname index d5112168a4cbfd..b12d4e168ae119 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -819,10 +819,6 @@ vcxproj: sed -i 's|\(git\)-\([-a-z]*\)\.exe"|\1.exe" \2|g' \ bin-wrappers/git-{receive-pack,upload-archive} git add -f $(test_bindir_programs) - # remote-ext is a builtin, but invoked as if it were external - sed 's|receive-pack|remote-ext|g' \ - <bin-wrappers/git-receive-pack >bin-wrappers/git-remote-ext - git add -f bin-wrappers/git-remote-ext # Add templates $(MAKE) -C templates diff --git a/configure.ac b/configure.ac index d1a96da14eb567..5923edc44aa7b6 100644 --- a/configure.ac +++ b/configure.ac @@ -142,7 +142,7 @@ fi ## Configure body starts here. AC_PREREQ(2.59) -AC_INIT([git], [@@GIT_VERSION@@], [git@vger.kernel.org]) +AC_INIT([git], [@GIT_VERSION@], [git@vger.kernel.org]) AC_CONFIG_SRCDIR([git.c]) diff --git a/connect.c b/connect.c index 6829ab397455c4..3280435331038e 100644 --- a/connect.c +++ b/connect.c @@ -22,6 +22,7 @@ #include "protocol.h" #include "alias.h" #include "bundle-uri.h" +#include "promisor-remote.h" static char *server_capabilities_v1; static struct strvec server_capabilities_v2 = STRVEC_INIT; @@ -76,7 +77,7 @@ static NORETURN void die_initial_contact(int unexpected) /* Checks if the server supports the capability 'c' */ int server_supports_v2(const char *c) { - int i; + size_t i; for (i = 0; i < server_capabilities_v2.nr; i++) { const char *out; @@ -95,7 +96,7 @@ void ensure_server_supports_v2(const char *c) int server_feature_v2(const char *c, const char **v) { - int i; + size_t i; for (i = 0; i < server_capabilities_v2.nr; i++) { const char *out; @@ -111,7 +112,7 @@ int server_feature_v2(const char *c, const char **v) int server_supports_feature(const char *c, const char *feature, int die_on_error) { - int i; + size_t i; for (i = 0; i < server_capabilities_v2.nr; i++) { const char *out; @@ -231,12 +232,12 @@ static void annotate_refs_with_symref_info(struct ref *ref) string_list_clear(&symref, 0); } -static void process_capabilities(struct packet_reader *reader, int *linelen) +static void process_capabilities(struct packet_reader *reader, size_t *linelen) { const char *feat_val; size_t feat_len; const char *line = reader->line; - int nul_location = strlen(line); + size_t nul_location = strlen(line); if (nul_location == *linelen) return; server_capabilities_v1 = xstrdup(line + nul_location + 1); @@ -270,14 +271,14 @@ static int process_dummy_ref(const struct packet_reader *reader) !strcmp(name, "capabilities^{}"); } -static void check_no_capabilities(const char *line, int len) +static void check_no_capabilities(const char *line, size_t len) { if (strlen(line) != len) warning(_("ignoring capabilities after first line '%s'"), line + strlen(line)); } -static int process_ref(const struct packet_reader *reader, int len, +static int process_ref(const struct packet_reader *reader, size_t len, struct ref ***list, unsigned int flags, struct oid_array *extra_have) { @@ -305,7 +306,7 @@ static int process_ref(const struct packet_reader *reader, int len, return 1; } -static int process_shallow(const struct packet_reader *reader, int len, +static int process_shallow(const struct packet_reader *reader, size_t len, struct oid_array *shallow_points) { const char *line = reader->line; @@ -340,7 +341,7 @@ struct ref **get_remote_heads(struct packet_reader *reader, struct oid_array *shallow_points) { struct ref **orig_list = list; - int len = 0; + size_t len = 0; enum get_remote_heads_state state = EXPECTING_FIRST_REF; *list = NULL; @@ -393,7 +394,7 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list, const char **unborn_head_target) { int ret = 1; - int i = 0; + size_t i = 0; struct object_id old_oid; struct ref *ref; struct string_list line_sections = STRING_LIST_INIT_DUP; @@ -487,6 +488,7 @@ void check_stateless_delimiter(int stateless_rpc, static void send_capabilities(int fd_out, struct packet_reader *reader) { const char *hash_name; + const char *promisor_remote_info; if (server_supports_v2("agent")) packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized()); @@ -500,6 +502,13 @@ static void send_capabilities(int fd_out, struct packet_reader *reader) } else { reader->hash_algo = &hash_algos[GIT_HASH_SHA1]; } + if (server_feature_v2("promisor-remote", &promisor_remote_info)) { + char *reply = promisor_remote_reply(promisor_remote_info); + if (reply) { + packet_write_fmt(fd_out, "promisor-remote=%s", reply); + free(reply); + } + } } int get_remote_bundle_uri(int fd_out, struct packet_reader *reader, @@ -551,7 +560,7 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, const struct string_list *server_options, int stateless_rpc) { - int i; + size_t i; struct strvec *ref_prefixes = transport_options ? &transport_options->ref_prefixes : NULL; const char **unborn_head_target = transport_options ? @@ -624,7 +633,7 @@ const char *parse_feature_value(const char *feature_list, const char *feature, s *offset = found + len - orig_start; return value; } - /* feature with a value (e.g., "agent=git/1.2.3") */ + /* feature with a value (e.g., "agent=git/1.2.3-Linux") */ else if (*value == '=') { size_t end; @@ -1485,6 +1494,7 @@ struct child_process *git_connect(int fd[2], const char *url, free(hostandport); free(path); + child_process_clear(conn); free(conn); strbuf_release(&cmd); return NULL; diff --git a/connected.c b/connected.c index 87cc4b57a17ce5..3099da84f3397f 100644 --- a/connected.c +++ b/connected.c @@ -54,7 +54,8 @@ int check_connected(oid_iterate_fn fn, void *cb_data, strbuf_add(&idx_file, transport->pack_lockfiles.items[0].string, base_len); strbuf_addstr(&idx_file, ".idx"); - new_pack = add_packed_git(idx_file.buf, idx_file.len, 1); + new_pack = add_packed_git(the_repository, idx_file.buf, + idx_file.len, 1); strbuf_release(&idx_file); } @@ -78,7 +79,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data, for (p = get_all_packs(the_repository); p; p = p->next) { if (!p->pack_promisor) continue; - if (find_pack_entry_one(oid->hash, p)) + if (find_pack_entry_one(oid, p)) goto promisor_pack_found; } /* @@ -144,7 +145,7 @@ int check_connected(oid_iterate_fn fn, void *cb_data, * are sure the ref is good and not sending it to * rev-list for verification. */ - if (new_pack && find_pack_entry_one(oid->hash, new_pack)) + if (new_pack && find_pack_entry_one(oid, new_pack)) continue; if (fprintf(rev_list_in, "%s\n", oid_to_hex(oid)) < 0) diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 62af7b33d2fa14..25b495fa737d07 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -83,23 +83,12 @@ if(NOT SH_EXE) "On Windows, you can get it as part of 'Git for Windows' install at https://gitforwindows.org/") endif() -#Create GIT-VERSION-FILE using GIT-VERSION-GEN -if(NOT EXISTS ${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE) - message("Generating GIT-VERSION-FILE") - execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) -endif() - -#Parse GIT-VERSION-FILE to get the version -file(STRINGS ${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE git_version REGEX "GIT_VERSION = (.*)") -string(REPLACE "GIT_VERSION = " "" git_version ${git_version}) -string(FIND ${git_version} "GIT" location) -if(location EQUAL -1) - string(REGEX MATCH "[0-9]*\\.[0-9]*\\.[0-9]*" git_version ${git_version}) -else() - string(REGEX MATCH "[0-9]*\\.[0-9]*" git_version ${git_version}) - string(APPEND git_version ".0") #for building from a snapshot -endif() +message("Generating Git version") +execute_process(COMMAND ${SH_EXE} "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/contrib/buildsystems/git-version.in" + "${CMAKE_BINARY_DIR}/git-version") +file(STRINGS "${CMAKE_BINARY_DIR}/git-version" git_version) project(git VERSION ${git_version} @@ -110,8 +99,8 @@ project(git #TODO Enable NLS on windows natively #macros for parsing the Makefile for sources and scripts -macro(parse_makefile_for_sources list_var regex) - file(STRINGS ${CMAKE_SOURCE_DIR}/Makefile ${list_var} REGEX "^${regex} \\+=(.*)") +macro(parse_makefile_for_sources list_var makefile regex) + file(STRINGS ${makefile} ${list_var} REGEX "^${regex} \\+=(.*)") string(REPLACE "${regex} +=" "" ${list_var} ${${list_var}}) string(REPLACE "$(COMPAT_OBJS)" "" ${list_var} ${${list_var}}) #remove "$(COMPAT_OBJS)" This is only for libgit. string(STRIP ${${list_var}} ${list_var}) #remove trailing/leading whitespaces @@ -240,10 +229,7 @@ add_compile_definitions(PAGER_ENV="LESS=FRX LV=-c" GIT_HTML_PATH="share/doc/git-doc" DEFAULT_HELP_FORMAT="html" DEFAULT_GIT_TEMPLATE_DIR="share/git-core/templates" - GIT_VERSION="${PROJECT_VERSION}.GIT" - GIT_USER_AGENT="git/${PROJECT_VERSION}.GIT" - BINDIR="bin" - GIT_BUILT_FROM_COMMIT="") + BINDIR="bin") if(WIN32) set(FALLBACK_RUNTIME_PREFIX /mingw64) @@ -652,60 +638,79 @@ set(EXCLUSION_PROGS_CACHE ${EXCLUSION_PROGS} CACHE STRING "Programs not built" F if(NOT EXISTS ${CMAKE_BINARY_DIR}/command-list.h OR NOT EXCLUSION_PROGS_CACHE STREQUAL EXCLUSION_PROGS) list(REMOVE_ITEM EXCLUSION_PROGS empty) message("Generating command-list.h") - execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/generate-cmdlist.sh ${EXCLUSION_PROGS} command-list.txt - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_FILE ${CMAKE_BINARY_DIR}/command-list.h) + execute_process(COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/generate-cmdlist.sh" + ${EXCLUSION_PROGS} + "${CMAKE_SOURCE_DIR}" + "${CMAKE_BINARY_DIR}/command-list.h") endif() if(NOT EXISTS ${CMAKE_BINARY_DIR}/config-list.h) message("Generating config-list.h") - execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/generate-configlist.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_FILE ${CMAKE_BINARY_DIR}/config-list.h) + execute_process(COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/generate-configlist.sh" + "${CMAKE_SOURCE_DIR}" + "${CMAKE_BINARY_DIR}/config-list.h") endif() if(NOT EXISTS ${CMAKE_BINARY_DIR}/hook-list.h) message("Generating hook-list.h") - execute_process(COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/generate-hooklist.sh - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_FILE ${CMAKE_BINARY_DIR}/hook-list.h) + execute_process(COMMAND "${SH_EXE}" ${CMAKE_SOURCE_DIR}/generate-hooklist.sh + "${CMAKE_SOURCE_DIR}" + "${CMAKE_BINARY_DIR}/hook-list.h") endif() include_directories(${CMAKE_BINARY_DIR}) #build #libgit -parse_makefile_for_sources(libgit_SOURCES "LIB_OBJS") +parse_makefile_for_sources(libgit_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "LIB_OBJS") list(TRANSFORM libgit_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") list(TRANSFORM compat_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") + +add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/version-def.h" + COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/version-def.h.in" + "${CMAKE_BINARY_DIR}/version-def.h" + DEPENDS "${SH_EXE}" "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}/version-def.h.in" + VERBATIM) +list(APPEND libgit_SOURCES "${CMAKE_BINARY_DIR}/version-def.h") + add_library(libgit ${libgit_SOURCES} ${compat_SOURCES}) #libxdiff -parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS") +parse_makefile_for_sources(libxdiff_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "XDIFF_OBJS") list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_library(xdiff STATIC ${libxdiff_SOURCES}) #reftable -parse_makefile_for_sources(reftable_SOURCES "REFTABLE_OBJS") +parse_makefile_for_sources(reftable_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "REFTABLE_OBJS") list(TRANSFORM reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_library(reftable STATIC ${reftable_SOURCES}) if(WIN32) + add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.rc + COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/git.rc.in" + "${CMAKE_BINARY_DIR}/git.rc" + DEPENDS "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}/git.rc.in" + VERBATIM) + if(NOT MSVC)#use windres when compiling with gcc and clang add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res - COMMAND ${WINDRES_EXE} -O coff -DMAJOR=${PROJECT_VERSION_MAJOR} -DMINOR=${PROJECT_VERSION_MINOR} - -DMICRO=${PROJECT_VERSION_PATCH} -DPATCHLEVEL=0 -DGIT_VERSION="\\\"${PROJECT_VERSION}.GIT\\\"" - -i ${CMAKE_SOURCE_DIR}/git.rc -o ${CMAKE_BINARY_DIR}/git.res + COMMAND ${WINDRES_EXE} -O coff -i ${CMAKE_BINARY_DIR}/git.rc -o ${CMAKE_BINARY_DIR}/git.res + DEPENDS "${CMAKE_BINARY_DIR}/git.rc" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} VERBATIM) else()#MSVC use rc add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res - COMMAND ${CMAKE_RC_COMPILER} /d MAJOR=${PROJECT_VERSION_MAJOR} /d MINOR=${PROJECT_VERSION_MINOR} - /d MICRO=${PROJECT_VERSION_PATCH} /d PATCHLEVEL=0 /d GIT_VERSION="${PROJECT_VERSION}.GIT" - /fo ${CMAKE_BINARY_DIR}/git.res ${CMAKE_SOURCE_DIR}/git.rc + COMMAND ${CMAKE_RC_COMPILER} /fo ${CMAKE_BINARY_DIR}/git.res ${CMAKE_BINARY_DIR}/git.rc + DEPENDS "${CMAKE_BINARY_DIR}/git.rc" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} VERBATIM) endif() @@ -752,7 +757,7 @@ elseif(UNIX) endif() #git -parse_makefile_for_sources(git_SOURCES "BUILTIN_OBJS") +parse_makefile_for_sources(git_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "BUILTIN_OBJS") list(TRANSFORM git_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") add_executable(git ${CMAKE_SOURCE_DIR}/git.c ${git_SOURCES}) @@ -834,70 +839,91 @@ set(git_shell_scripts ${git_sh_scripts} ${git_shlib_scripts} git-instaweb) foreach(script ${git_shell_scripts}) - file(STRINGS ${CMAKE_SOURCE_DIR}/${script}.sh content NEWLINE_CONSUME) - string(REPLACE "@SHELL_PATH@" "${SHELL_PATH}" content "${content}") - string(REPLACE "@@DIFF@@" "diff" content "${content}") - string(REPLACE "@LOCALEDIR@" "${LOCALEDIR}" content "${content}") - string(REPLACE "@GITWEBDIR@" "${GITWEBDIR}" content "${content}") - string(REPLACE "@@NO_CURL@@" "" content "${content}") - string(REPLACE "@@USE_GETTEXT_SCHEME@@" "" content "${content}") - string(REPLACE "# @@BROKEN_PATH_FIX@@" "" content "${content}") - string(REPLACE "@@PERL@@" "${PERL_PATH}" content "${content}") - string(REPLACE "@@PAGER_ENV@@" "LESS=FRX LV=-c" content "${content}") - file(WRITE ${CMAKE_BINARY_DIR}/${script} ${content}) -endforeach() - -#perl scripts -parse_makefile_for_scripts(git_perl_scripts "SCRIPT_PERL" ".perl") + if ("${script}" IN_LIST git_sh_scripts) + string(REPLACE ".sh" "" shell_gen_path "${script}") + else() + set(shell_gen_path "${script}") + endif() -#create perl header -file(STRINGS ${CMAKE_SOURCE_DIR}/perl/header_templates/fixed_prefix.template.pl perl_header ) -string(REPLACE "@@PATHSEP@@" ":" perl_header "${perl_header}") -string(REPLACE "@@INSTLIBDIR@@" "${INSTLIBDIR}" perl_header "${perl_header}") - -foreach(script ${git_perl_scripts}) - file(STRINGS ${CMAKE_SOURCE_DIR}/${script}.perl content NEWLINE_CONSUME) - string(REPLACE "#!/usr/bin/perl" "#!/usr/bin/perl\n${perl_header}\n" content "${content}") - string(REPLACE "@@GIT_VERSION@@" "${PROJECT_VERSION}" content "${content}") - file(WRITE ${CMAKE_BINARY_DIR}/${script} ${content}) + add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/${shell_gen_path}" + COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/generate-script.sh" + "${CMAKE_SOURCE_DIR}/${script}.sh" + "${CMAKE_BINARY_DIR}/${shell_gen_path}" + "${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS" + DEPENDS "${CMAKE_SOURCE_DIR}/generate-script.sh" + "${CMAKE_SOURCE_DIR}/${script}.sh" + VERBATIM) + list(APPEND shell_gen ${CMAKE_BINARY_DIR}/${shell_gen_path}) endforeach() +add_custom_target(shell-gen ALL DEPENDS ${shell_gen}) -#python script -file(STRINGS ${CMAKE_SOURCE_DIR}/git-p4.py content NEWLINE_CONSUME) -string(REPLACE "#!/usr/bin/env python" "#!/usr/bin/python" content "${content}") -file(WRITE ${CMAKE_BINARY_DIR}/git-p4 ${content}) - +#perl scripts +parse_makefile_for_scripts(git_perl_scripts "SCRIPT_PERL" "") #perl modules file(GLOB_RECURSE perl_modules "${CMAKE_SOURCE_DIR}/perl/*.pm") +list(TRANSFORM perl_modules REPLACE "${CMAKE_SOURCE_DIR}/" "") -foreach(pm ${perl_modules}) - string(REPLACE "${CMAKE_SOURCE_DIR}/perl/" "" file_path ${pm}) - file(STRINGS ${pm} content NEWLINE_CONSUME) - string(REPLACE "@@LOCALEDIR@@" "${LOCALEDIR}" content "${content}") - string(REPLACE "@@NO_PERL_CPAN_FALLBACKS@@" "" content "${content}") - file(WRITE ${CMAKE_BINARY_DIR}/perl/build/lib/${file_path} ${content}) -#test-lib.sh requires perl/build/lib to be the build directory of perl modules +#create perl header +file(STRINGS ${CMAKE_SOURCE_DIR}/perl/header_templates/fixed_prefix.template.pl perl_header ) +string(REPLACE "@PATHSEP@" ":" perl_header "${perl_header}") +string(REPLACE "@INSTLIBDIR@" "${INSTLIBDIR}" perl_header "${perl_header}") +file(WRITE ${CMAKE_BINARY_DIR}/GIT-PERL-HEADER ${perl_header}) + +add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/GIT-VERSION-FILE" + COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}" + "${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE.in" + "${CMAKE_BINARY_DIR}/GIT-VERSION-FILE" + DEPENDS ${SH_EXE} "${CMAKE_SOURCE_DIR}/GIT-VERSION-GEN" + "${CMAKE_SOURCE_DIR}/GIT-VERSION-FILE.in" + VERBATIM) + +foreach(script ${git_perl_scripts} ${perl_modules}) + string(REPLACE ".perl" "" perl_gen_path "${script}") + + get_filename_component(perl_gen_dir "${perl_gen_path}" DIRECTORY) + if(script MATCHES "\.pm$") + string(REGEX REPLACE "^perl" "perl/build/lib" perl_gen_dir "${perl_gen_dir}") + string(REGEX REPLACE "^perl" "perl/build/lib" perl_gen_path "${perl_gen_path}") + endif() + file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/${perl_gen_dir}") + + add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/${perl_gen_path}" + COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/generate-perl.sh" + "${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS" + "${CMAKE_BINARY_DIR}/GIT-VERSION-FILE" + "${CMAKE_BINARY_DIR}/GIT-PERL-HEADER" + "${CMAKE_SOURCE_DIR}/${script}" + "${CMAKE_BINARY_DIR}/${perl_gen_path}" + DEPENDS "${CMAKE_SOURCE_DIR}/generate-perl.sh" + "${CMAKE_SOURCE_DIR}/${script}" + "${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS" + "${CMAKE_BINARY_DIR}/GIT-VERSION-FILE" + VERBATIM) + list(APPEND perl_gen ${CMAKE_BINARY_DIR}/${perl_gen_path}) endforeach() - - -#templates -file(GLOB templates "${CMAKE_SOURCE_DIR}/templates/*") -list(TRANSFORM templates REPLACE "${CMAKE_SOURCE_DIR}/templates/" "") -list(REMOVE_ITEM templates ".gitignore") -list(REMOVE_ITEM templates "Makefile") -list(REMOVE_ITEM templates "blt")# Prevents an error when reconfiguring for in source builds - -list(REMOVE_ITEM templates "branches--") -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/templates/blt/branches) #create branches - +add_custom_target(perl-gen ALL DEPENDS ${perl_gen}) + +# Python script +add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/git-p4" + COMMAND "${SH_EXE}" "${CMAKE_SOURCE_DIR}/generate-python.sh" + "${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS" + "${CMAKE_SOURCE_DIR}/git-p4.py" + "${CMAKE_BINARY_DIR}/git-p4" + DEPENDS "${CMAKE_SOURCE_DIR}/generate-python.sh" + "${CMAKE_SOURCE_DIR}/git-p4.py" + "${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS" + VERBATIM) +add_custom_target(python-gen ALL DEPENDS "${CMAKE_BINARY_DIR}/git-p4") + +#${CMAKE_SOURCE_DIR}/Makefile templates +parse_makefile_for_sources(templates ${CMAKE_SOURCE_DIR}/templates/Makefile "TEMPLATES") +string(REPLACE " " ";" templates ${templates}) #templates have @.*@ replacement so use configure_file instead foreach(tm ${templates}) - string(REPLACE "--" "/" blt_tm ${tm}) - string(REPLACE "this" "" blt_tm ${blt_tm})# for this-- - configure_file(${CMAKE_SOURCE_DIR}/templates/${tm} ${CMAKE_BINARY_DIR}/templates/blt/${blt_tm} @ONLY) + configure_file(${CMAKE_SOURCE_DIR}/templates/${tm} ${CMAKE_BINARY_DIR}/templates/blt/${tm} @ONLY) endforeach() - #translations if(MSGFMT_EXE) file(GLOB po_files "${CMAKE_SOURCE_DIR}/po/*.po") @@ -971,14 +997,18 @@ add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) #unit-tests -parse_makefile_for_sources(unit-test_SOURCES "UNIT_TEST_OBJS") +parse_makefile_for_sources(unit-test_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "UNIT_TEST_OBJS") list(TRANSFORM unit-test_SOURCES REPLACE "\\$\\(UNIT_TEST_DIR\\)/" "${CMAKE_SOURCE_DIR}/t/unit-tests/") add_library(unit-test-lib STATIC ${unit-test_SOURCES}) +parse_makefile_for_sources(clar-test_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "CLAR_TEST_OBJS") +list(TRANSFORM clar-test_SOURCES REPLACE "\\$\\(UNIT_TEST_DIR\\)/" "${CMAKE_SOURCE_DIR}/t/unit-tests/") +add_library(clar-test-lib STATIC ${clar-test_SOURCES}) + parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "") foreach(unit_test ${unit_test_PROGRAMS}) add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c") - target_link_libraries("${unit_test}" unit-test-lib common-main) + target_link_libraries("${unit_test}" unit-test-lib clar-test-lib common-main) set_target_properties("${unit_test}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) if(MSVC) @@ -1002,49 +1032,31 @@ foreach(unit_test ${unit_test_PROGRAMS}) endforeach() parse_makefile_for_scripts(clar_test_SUITES "CLAR_TEST_SUITES" "") - -set(clar_decls "") -set(clar_cbs "") -set(clar_cbs_count 0) -set(clar_suites "static struct clar_suite _clar_suites[] = {\n") -list(LENGTH clar_test_SUITES clar_suites_count) -foreach(suite ${clar_test_SUITES}) - file(STRINGS "${CMAKE_SOURCE_DIR}/t/unit-tests/${suite}.c" decls - REGEX "^void test_${suite}__[a-zA-Z_0-9][a-zA-Z_0-9]*\\(void\\)$") - - list(LENGTH decls decls_count) - string(REGEX REPLACE "void (test_${suite}__([a-zA-Z_0-9]*))\\(void\\)" " { \"\\2\", &\\1 },\n" cbs ${decls}) - string(JOIN "" cbs ${cbs}) - list(TRANSFORM decls PREPEND "extern ") - string(JOIN ";\n" decls ${decls}) - - string(APPEND clar_decls "${decls};\n") - string(APPEND clar_cbs - "static const struct clar_func _clar_cb_${suite}[] = {\n" - ${cbs} - "};\n") - string(APPEND clar_suites - " {\n" - " \"${suite}\",\n" - " { NULL, NULL },\n" - " { NULL, NULL },\n" - " _clar_cb_${suite}, ${decls_count}, 1\n" - " },\n") - math(EXPR clar_cbs_count "${clar_cbs_count}+${decls_count}") -endforeach() -string(APPEND clar_suites - "};\n" - "static const size_t _clar_suite_count = ${clar_suites_count};\n" - "static const size_t _clar_callback_count = ${clar_cbs_count};\n") -file(WRITE "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" "${clar_decls}") -file(WRITE "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" "${clar_decls}" "${clar_cbs}" "${clar_suites}") - list(TRANSFORM clar_test_SUITES PREPEND "${CMAKE_SOURCE_DIR}/t/unit-tests/") list(TRANSFORM clar_test_SUITES APPEND ".c") -add_library(unit-tests-lib ${clar_test_SUITES} "${CMAKE_SOURCE_DIR}/t/unit-tests/clar/clar.c") -target_include_directories(unit-tests-lib PRIVATE "${CMAKE_SOURCE_DIR}/t/unit-tests") -add_executable(unit-tests "${CMAKE_SOURCE_DIR}/t/unit-tests/unit-test.c") -target_link_libraries(unit-tests unit-tests-lib common-main) +add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" + COMMAND ${SH_EXE} ${CMAKE_SOURCE_DIR}/t/unit-tests/generate-clar-decls.sh + "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" + ${clar_test_SUITES} + DEPENDS ${CMAKE_SOURCE_DIR}/t/unit-tests/generate-clar-decls.sh + ${clar_test_SUITES} + VERBATIM) +add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" + COMMAND ${SH_EXE} "${CMAKE_SOURCE_DIR}/t/unit-tests/generate-clar-suites.sh" + "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" + "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" + DEPENDS "${CMAKE_SOURCE_DIR}/t/unit-tests/generate-clar-suites.sh" + "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" + VERBATIM) + +add_library(unit-tests-lib ${clar_test_SUITES} + "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" + "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" +) +target_include_directories(clar-test-lib PUBLIC "${CMAKE_BINARY_DIR}/t/unit-tests") +target_include_directories(unit-tests-lib PUBLIC "${CMAKE_BINARY_DIR}/t/unit-tests") +add_executable(unit-tests) +target_link_libraries(unit-tests unit-tests-lib clar-test-lib common-main) set_target_properties(unit-tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) if(MSVC) @@ -1055,7 +1067,7 @@ if(MSVC) endif() #test-tool -parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS") +parse_makefile_for_sources(test-tool_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "TEST_BUILTINS_OBJS") add_library(test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c) list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/") @@ -1074,29 +1086,35 @@ endif() #wrapper scripts set(wrapper_scripts - git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext scalar) + git git-upload-pack git-receive-pack git-upload-archive git-shell scalar) set(wrapper_test_scripts test-fake-ssh test-tool) foreach(script ${wrapper_scripts}) - file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME) - string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}") - string(REPLACE "@@PROG@@" "${script}${EXE_EXTENSION}" content "${content}") + file(STRINGS ${CMAKE_SOURCE_DIR}/bin-wrappers/wrap-for-bin.sh content NEWLINE_CONSUME) + string(REPLACE "@BUILD_DIR@" "${CMAKE_BINARY_DIR}" content "${content}") + string(REPLACE "@TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" content "${content}") + string(REPLACE "@PROG@" "${CMAKE_BINARY_DIR}/${script}${EXE_EXTENSION}" content "${content}") file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content}) endforeach() foreach(script ${wrapper_test_scripts}) - file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME) - string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}") - string(REPLACE "@@PROG@@" "t/helper/${script}${EXE_EXTENSION}" content "${content}") + file(STRINGS ${CMAKE_SOURCE_DIR}/bin-wrappers/wrap-for-bin.sh content NEWLINE_CONSUME) + string(REPLACE "@BUILD_DIR@" "${CMAKE_BINARY_DIR}" content "${content}") + string(REPLACE "@TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" content "${content}") + string(REPLACE "@PROG@" "${CMAKE_BINARY_DIR}/t/helper/${script}${EXE_EXTENSION}" content "${content}") file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/${script} ${content}) endforeach() -file(STRINGS ${CMAKE_SOURCE_DIR}/wrap-for-bin.sh content NEWLINE_CONSUME) -string(REPLACE "@@BUILD_DIR@@" "${CMAKE_BINARY_DIR}" content "${content}") -string(REPLACE "@@PROG@@" "git-cvsserver" content "${content}") +file(STRINGS ${CMAKE_SOURCE_DIR}/bin-wrappers/wrap-for-bin.sh content NEWLINE_CONSUME) +string(REPLACE "@BUILD_DIR@" "${CMAKE_BINARY_DIR}" content "${content}") +string(REPLACE "@TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" content "${content}") +string(REPLACE "@GIT_TEXTDOMAINDIR@" "${CMAKE_BINARY_DIR}/po/build/locale" content "${content}") +string(REPLACE "@GITPERLLIB@" "${CMAKE_BINARY_DIR}/perl/build/lib" content "${content}") +string(REPLACE "@MERGE_TOOLS_DIR@" "${CMAKE_SOURCE_DIR}/mergetools" content "${content}") +string(REPLACE "@PROG@" "${CMAKE_BINARY_DIR}/git-cvsserver" content "${content}") file(WRITE ${CMAKE_BINARY_DIR}/bin-wrappers/git-cvsserver ${content}) #options for configuring test options @@ -1109,6 +1127,7 @@ set(DIFF diff) set(PYTHON_PATH /usr/bin/python) set(TAR tar) set(NO_CURL ) +set(NO_ICONV ) set(NO_EXPAT ) set(USE_LIBPCRE2 ) set(NO_PERL ) @@ -1122,6 +1141,10 @@ if(NOT CURL_FOUND) set(NO_CURL 1) endif() +if(NOT Iconv_FOUND) + SET(NO_ICONV 1) +endif() + if(NOT EXPAT_FOUND) set(NO_EXPAT 1) endif() @@ -1138,26 +1161,59 @@ if(NOT PYTHON_TESTS) set(NO_PYTHON 1) endif() -file(WRITE ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "SHELL_PATH='${SHELL_PATH}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "TEST_SHELL_PATH='${TEST_SHELL_PATH}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PERL_PATH='${PERL_PATH}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "DIFF='${DIFF}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PYTHON_PATH='${PYTHON_PATH}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "TAR='${TAR}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_CURL='${NO_CURL}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_EXPAT='${NO_EXPAT}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PERL='${NO_PERL}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PTHREADS='${NO_PTHREADS}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_UNIX_SOCKETS='${NO_UNIX_SOCKETS}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PAGER_ENV='${PAGER_ENV}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "X='${EXE_EXTENSION}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_GETTEXT='${NO_GETTEXT}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "RUNTIME_PREFIX='${RUNTIME_PREFIX}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "NO_PYTHON='${NO_PYTHON}'\n") -file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "SUPPORTS_SIMPLE_IPC='${SUPPORTS_SIMPLE_IPC}'\n") +file(STRINGS ${CMAKE_SOURCE_DIR}/GIT-BUILD-OPTIONS.in git_build_options NEWLINE_CONSUME) +string(REPLACE "@BROKEN_PATH_FIX@" "" git_build_options "${git_build_options}") +string(REPLACE "@DIFF@" "'${DIFF}'" git_build_options "${git_build_options}") +string(REPLACE "@FSMONITOR_DAEMON_BACKEND@" "win32" git_build_options "${git_build_options}") +string(REPLACE "@FSMONITOR_OS_SETTINGS@" "win32" git_build_options "${git_build_options}") +string(REPLACE "@GITWEBDIR@" "'${GITWEBDIR}'" git_build_options "${git_build_options}") +string(REPLACE "@GIT_INTEROP_MAKE_OPTS@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_LARGE_REPO@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_MAKE_COMMAND@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_MAKE_OPTS@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_REPEAT_COUNT@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_REPO@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_SOURCE_DIR@" "${CMAKE_SOURCE_DIR}" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_CMP@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_CMP_USE_COPIED_CONTEXT@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_GITPERLLIB@" "'${CMAKE_BINARY_DIR}/perl/build/lib'" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_INDEX_VERSION@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_OPTS@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_PERL_FATAL_WARNINGS@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_TEXTDOMAINDIR@" "'${CMAKE_BINARY_DIR}/po/build/locale'" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_UTF8_LOCALE@" "" git_build_options "${git_build_options}") +string(REPLACE "@LOCALEDIR@" "'${LOCALEDIR}'" git_build_options "${git_build_options}") +string(REPLACE "@NO_CURL@" "${NO_CURL}" git_build_options "${git_build_options}") +string(REPLACE "@NO_EXPAT@" "${NO_EXPAT}" git_build_options "${git_build_options}") +string(REPLACE "@NO_GETTEXT@" "${NO_GETTEXT}" git_build_options "${git_build_options}") +string(REPLACE "@NO_GITWEB@" "1" git_build_options "${git_build_options}") +string(REPLACE "@NO_ICONV@" "${NO_ICONV}" git_build_options "${git_build_options}") +string(REPLACE "@NO_PERL@" "${NO_PERL}" git_build_options "${git_build_options}") +string(REPLACE "@NO_PERL_CPAN_FALLBACKS@" "" git_build_options "${git_build_options}") +string(REPLACE "@NO_PTHREADS@" "${NO_PTHREADS}" git_build_options "${git_build_options}") +string(REPLACE "@NO_PYTHON@" "${NO_PYTHON}" git_build_options "${git_build_options}") +string(REPLACE "@NO_REGEX@" "" git_build_options "${git_build_options}") +string(REPLACE "@NO_UNIX_SOCKETS@" "${NO_UNIX_SOCKETS}" git_build_options "${git_build_options}") +string(REPLACE "@PAGER_ENV@" "'${PAGER_ENV}'" git_build_options "${git_build_options}") +string(REPLACE "@PERL_LOCALEDIR@" "'${LOCALEDIR}'" git_build_options "${git_build_options}") +string(REPLACE "@PERL_PATH@" "'${PERL_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@PYTHON_PATH@" "'${PYTHON_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@RUNTIME_PREFIX@" "'${RUNTIME_PREFIX}'" git_build_options "${git_build_options}") +string(REPLACE "@SANITIZE_ADDRESS@" "" git_build_options "${git_build_options}") +string(REPLACE "@SANITIZE_LEAK@" "" git_build_options "${git_build_options}") +string(REPLACE "@SHELL_PATH@" "'${SHELL_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@TAR@" "'${TAR}'" git_build_options "${git_build_options}") +string(REPLACE "@TEST_OUTPUT_DIRECTORY@" "" git_build_options "${git_build_options}") +string(REPLACE "@TEST_SHELL_PATH@" "'${TEST_SHELL_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@USE_GETTEXT_SCHEME@" "" git_build_options "${git_build_options}") +string(REPLACE "@USE_LIBPCRE2@" "" git_build_options "${git_build_options}") +string(REPLACE "@WITH_BREAKING_CHANGES@" "" git_build_options "${git_build_options}") +string(REPLACE "@X@" "${EXE_EXTENSION}" git_build_options "${git_build_options}") if(USE_VCPKG) - file(APPEND ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n") + string(APPEND git_build_options "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n") endif() +file(WRITE ${CMAKE_BINARY_DIR}/GIT-BUILD-OPTIONS ${git_build_options}) #Make the tests work when building out of the source tree get_filename_component(CACHE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../CMakeCache.txt ABSOLUTE) diff --git a/contrib/buildsystems/git-version.in b/contrib/buildsystems/git-version.in new file mode 100644 index 00000000000000..9750505ae77685 --- /dev/null +++ b/contrib/buildsystems/git-version.in @@ -0,0 +1 @@ +@GIT_MAJOR_VERSION@.@GIT_MINOR_VERSION@.@GIT_MICRO_VERSION@ diff --git a/contrib/coccinelle/meson.build b/contrib/coccinelle/meson.build new file mode 100644 index 00000000000000..5d76a7fee6fbb6 --- /dev/null +++ b/contrib/coccinelle/meson.build @@ -0,0 +1,89 @@ +spatch = find_program('spatch', required: get_option('coccinelle')) +if not spatch.found() + subdir_done() +endif + +third_party_sources = [ + ':!contrib', + ':!compat/inet_ntop.c', + ':!compat/inet_pton.c', + ':!compat/nedmalloc', + ':!compat/obstack.*', + ':!compat/poll', + ':!compat/regex', + ':!sha1collisiondetection', + ':!sha1dc', + ':!t/unit-tests/clar', + ':!t/unit-tests/clar', + ':!t/t[0-9][0-9][0-9][0-9]*', +] + +rules = [ + 'array.cocci', + 'commit.cocci', + 'config_fn_ctx.pending.cocci', + 'equals-null.cocci', + 'flex_alloc.cocci', + 'free.cocci', + 'git_config_number.cocci', + 'hashmap.cocci', + 'index-compatibility.cocci', + 'object_id.cocci', + 'preincr.cocci', + 'qsort.cocci', + 'refs.cocci', + 'strbuf.cocci', + 'swap.cocci', + 'the_repository.cocci', + 'xcalloc.cocci', + 'xopen.cocci', + 'xstrdup_or_null.cocci', + 'xstrncmpz.cocci', +] + +concatenated_rules = custom_target( + command: [ + 'cat', '@INPUT@', + ], + input: rules, + output: 'rules.cocci', + capture: true, +) + +sources = [ ] +foreach source : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.c', third_party_sources, check: true).stdout().split() + sources += source +endforeach + +headers = [ ] +foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_sources, check: true).stdout().split() + headers += meson.project_source_root() / header +endforeach + +patches = [ ] +foreach source : sources + patches += custom_target( + command: [ + spatch, + '--all-includes', + '--sp-file', concatenated_rules, + '--patch', meson.project_source_root(), + '@INPUT@', + ], + input: meson.project_source_root() / source, + output: source.underscorify() + '.patch', + capture: true, + depend_files: headers, + ) +endforeach + +concatenated_patch = custom_target( + command: [ + 'cat', '@INPUT@', + ], + input: patches, + output: 'cocci.patch', + capture: true, +) + +alias_target('coccicheck', concatenated_patch) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 60a22d619a85cc..413911be3be313 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -2331,7 +2331,7 @@ _git_mergetool () return ;; --*) - __gitcomp "--tool= --prompt --no-prompt --gui --no-gui" + __gitcomp "--tool= --tool-help --prompt --no-prompt --gui --no-gui" return ;; esac @@ -2737,12 +2737,17 @@ __git_compute_config_vars_all () __git_config_vars_all="$(git --no-pager help --config)" } +__git_indirect() +{ + eval printf '%s' "\"\$$1\"" +} + __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}" || + test -n "$(__git_indirect "${this_section}")" || printf -v "__git_first_level_config_vars_for_section_${section}" %s \ "$(echo "$__git_config_vars" | awk -F. "/^${section}\.[a-z]/ { print \$2 }")" } @@ -2752,7 +2757,7 @@ __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}" || + test -n "$(__git_indirect "${this_section}")" || printf -v "__git_second_level_config_vars_for_section_${section}" %s \ "$(echo "$__git_config_vars_all" | awk -F. "/^${section}\.</ { print \$3 }")" } @@ -2907,7 +2912,7 @@ __git_complete_config_variable_name () 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" + __gitcomp "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "$sfx" return ;; branch.*) @@ -2917,7 +2922,7 @@ __git_complete_config_variable_name () __gitcomp_direct "$(__git_heads "$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:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; pager.*) @@ -2934,7 +2939,7 @@ __git_complete_config_variable_name () __gitcomp_nl "$(__git_remotes)" "$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:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; submodule.*) @@ -2944,7 +2949,7 @@ __git_complete_config_variable_name () __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:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; *.*) @@ -3296,7 +3301,7 @@ __gitcomp_directories () # 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 + # sparse-checkout add" and is also problematic for # "git sparse-checkout set" unless using it to # strictly narrow the checkout. COMPREPLY=( "" ) @@ -3698,7 +3703,7 @@ _git_worktree () # Here we are not completing an --option, it's either the # path or a ref. case "$prev" in - -b|-B) # Complete refs for branch to be created/reseted. + -b|-B) # Complete refs for branch to be created/reset. __git_complete_refs ;; -*) # The previous word is an -o|--option without an diff --git a/contrib/completion/meson.build b/contrib/completion/meson.build new file mode 100644 index 00000000000000..3a9ddab5940d84 --- /dev/null +++ b/contrib/completion/meson.build @@ -0,0 +1,16 @@ +foreach script : [ + 'git-completion.bash', + 'git-completion.tcsh', + 'git-completion.zsh', + 'git-prompt.sh' +] + if meson.version().version_compare('>=1.3.0') + test_dependencies += fs.copyfile(script) + else + configure_file( + input: script, + output: script, + copy: true, + ) + endif +endforeach diff --git a/contrib/contacts/Makefile b/contrib/contacts/Makefile index a2990f0dcb53b1..9c4ca4f3bcc7c2 100644 --- a/contrib/contacts/Makefile +++ b/contrib/contacts/Makefile @@ -34,7 +34,7 @@ GIT_CONTACTS := git-contacts GIT_CONTACTS_DOC := git-contacts.1 GIT_CONTACTS_XML := git-contacts.xml -GIT_CONTACTS_TXT := git-contacts.txt +GIT_CONTACTS_TXT := git-contacts.adoc GIT_CONTACTS_HTML := git-contacts.html doc: $(GIT_CONTACTS_DOC) $(GIT_CONTACTS_HTML) diff --git a/contrib/contacts/git-contacts.txt b/contrib/contacts/git-contacts.adoc similarity index 100% rename from contrib/contacts/git-contacts.txt rename to contrib/contacts/git-contacts.adoc diff --git a/contrib/contacts/meson.build b/contrib/contacts/meson.build new file mode 100644 index 00000000000000..73d82dfe52b85f --- /dev/null +++ b/contrib/contacts/meson.build @@ -0,0 +1,55 @@ +custom_target( + input: 'git-contacts', + output: 'git-contacts', + command: generate_perl_command, + depends: [git_version_file], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('docs').contains('man') + contacts_xml = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-contacts.adoc', + output: 'git-contacts.xml', + ) + + custom_target( + command: [ + xmlto, + '-m', '@INPUT@', + 'man', + contacts_xml, + '-o', + meson.current_build_dir(), + ] + xmlto_extra, + input: [ + '../../Documentation/manpage-normal.xsl', + ], + output: 'git-contacts.1', + install: true, + install_dir: get_option('mandir') / 'man1', + ) +endif + +if get_option('docs').contains('html') + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-contacts.adoc', + output: 'git-contacts.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) +endif diff --git a/contrib/credential/libsecret/Makefile b/contrib/credential/libsecret/Makefile index 3e67552cc5b5ba..97ce9c92fb8ae5 100644 --- a/contrib/credential/libsecret/Makefile +++ b/contrib/credential/libsecret/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + MAIN:=git-credential-libsecret all:: $(MAIN) diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c index 90034d0cf1eb3d..941b2afd5eed5d 100644 --- a/contrib/credential/libsecret/git-credential-libsecret.c +++ b/contrib/credential/libsecret/git-credential-libsecret.c @@ -59,10 +59,10 @@ static void credential_clear(struct credential *c); /* ----------------- Secret Service functions ----------------- */ static const SecretSchema schema = { - "org.git.Password", + .name = "org.git.Password", /* Ignore schema name during search for backwards compatibility */ - SECRET_SCHEMA_DONT_MATCH_NAME, - { + .flags = SECRET_SCHEMA_DONT_MATCH_NAME, + .attributes = { /* * libsecret assumes attribute values are non-confidential and * unchanging, so we can't include oauth_refresh_token or @@ -168,7 +168,7 @@ static int keyring_get(struct credential *c) g_free(c->password); c->password = g_strdup(""); } - for (int i = 1; i < g_strv_length(parts); i++) { + for (guint i = 1; i < g_strv_length(parts); i++) { if (g_str_has_prefix(parts[i], "password_expiry_utc=")) { g_free(c->password_expiry_utc); c->password_expiry_utc = g_strdup(&parts[i][20]); @@ -424,7 +424,7 @@ int main(int argc, char *argv[]) struct credential_operation const *try_op = credential_helper_ops; struct credential cred = CREDENTIAL_INIT; - if (!argv[1]) { + if (argc < 2 || !*argv[1]) { usage(argv[0]); exit(EXIT_FAILURE); } diff --git a/contrib/credential/libsecret/meson.build b/contrib/credential/libsecret/meson.build new file mode 100644 index 00000000000000..0137660fe02cb9 --- /dev/null +++ b/contrib/credential/libsecret/meson.build @@ -0,0 +1,9 @@ +executable('git-credential-libsecret', + sources: 'git-credential-libsecret.c', + dependencies: [ + dependency('glib-2.0'), + dependency('libsecret-1'), + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/credential/meson.build b/contrib/credential/meson.build new file mode 100644 index 00000000000000..4216296ae05a9e --- /dev/null +++ b/contrib/credential/meson.build @@ -0,0 +1,3 @@ +foreach helper : get_option('credential_helpers') + subdir(helper) +endforeach diff --git a/contrib/credential/netrc/meson.build b/contrib/credential/netrc/meson.build new file mode 100644 index 00000000000000..a990dbb86da2f1 --- /dev/null +++ b/contrib/credential/netrc/meson.build @@ -0,0 +1,20 @@ +credential_netrc = custom_target( + input: 'git-credential-netrc.perl', + output: 'git-credential-netrc', + command: generate_perl_command, + depends: [git_version_file], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +credential_netrc_testenv = test_environment +credential_netrc_testenv.set('CREDENTIAL_NETRC_PATH', credential_netrc.full_path()) + +test('t-git-credential-netrc', + shell, + args: [ meson.current_source_dir() / 't-git-credential-netrc.sh' ], + workdir: meson.current_source_dir(), + env: credential_netrc_testenv, + depends: test_dependencies + bin_wrappers + [credential_netrc], + timeout: 0, +) diff --git a/contrib/credential/netrc/t-git-credential-netrc.sh b/contrib/credential/netrc/t-git-credential-netrc.sh index bf2777308a56b6..1b7b8b3a9aa8e0 100755 --- a/contrib/credential/netrc/t-git-credential-netrc.sh +++ b/contrib/credential/netrc/t-git-credential-netrc.sh @@ -15,7 +15,7 @@ export PERL5LIB="$GITPERLLIB" test_expect_success 'git-credential-netrc' ' - perl "$GIT_BUILD_DIR"/contrib/credential/netrc/test.pl + perl "$GIT_SOURCE_DIR"/contrib/credential/netrc/test.pl ' test_done diff --git a/contrib/credential/netrc/test.pl b/contrib/credential/netrc/test.pl index c0fb3718b280c7..67a0ede5644dd2 100755 --- a/contrib/credential/netrc/test.pl +++ b/contrib/credential/netrc/test.pl @@ -15,10 +15,11 @@ BEGIN my @global_credential_args = @ARGV; my $scriptDir = dirname rel2abs $0; -my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; } +my ($netrc, $netrcGpg) = map { catfile $scriptDir, $_; } qw(test.netrc - test.netrc.gpg - git-credential-netrc); + test.netrc.gpg); +my $gcNetrc = $ENV{CREDENTIAL_NETRC_PATH} || catfile $scriptDir, qw(git-credential-netrc); + local $ENV{PATH} = join ':' , $scriptDir , $ENV{PATH} diff --git a/contrib/credential/osxkeychain/Makefile b/contrib/credential/osxkeychain/Makefile index 238f5f8c36fd63..0948297e20f196 100644 --- a/contrib/credential/osxkeychain/Makefile +++ b/contrib/credential/osxkeychain/Makefile @@ -1,3 +1,4 @@ +# The default target of this Makefile is... all:: git-credential-osxkeychain CC = gcc diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c index 1c8310d7fefca0..611c9798b3ae5c 100644 --- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c +++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c @@ -422,7 +422,7 @@ int main(int argc, const char **argv) const char *usage = "usage: git credential-osxkeychain <get|store|erase>"; - if (!argv[1]) + if (argc < 2 || !*argv[1]) die("%s", usage); if (open(argv[0], O_RDONLY | O_EXLOCK) == -1) diff --git a/contrib/credential/osxkeychain/meson.build b/contrib/credential/osxkeychain/meson.build new file mode 100644 index 00000000000000..3c7677f736c684 --- /dev/null +++ b/contrib/credential/osxkeychain/meson.build @@ -0,0 +1,9 @@ +executable('git-credential-osxkeychain', + sources: 'git-credential-osxkeychain.c', + dependencies: [ + dependency('CoreFoundation'), + dependency('Security'), + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/credential/wincred/Makefile b/contrib/credential/wincred/Makefile index 6e992c08667d0b..5b795fc9fe0cc8 100644 --- a/contrib/credential/wincred/Makefile +++ b/contrib/credential/wincred/Makefile @@ -1,4 +1,5 @@ -all: git-credential-wincred.exe +# The default target of this Makefile is... +all:: git-credential-wincred.exe -include ../../../config.mak.autogen -include ../../../config.mak diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index 4be0d58cd89ad7..04145b511839a5 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -12,7 +12,9 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#ifndef _MSC_VER __attribute__((format (printf, 1, 2))) +#endif static void die(const char *err, ...) { char msg[4096]; diff --git a/contrib/credential/wincred/meson.build b/contrib/credential/wincred/meson.build new file mode 100644 index 00000000000000..6de23ca17d49af --- /dev/null +++ b/contrib/credential/wincred/meson.build @@ -0,0 +1,5 @@ +executable('git-credential-wincred', + sources: 'git-credential-wincred.c', + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm index 636add69680675..3d061bc0b7da35 100644 --- a/contrib/diff-highlight/DiffHighlight.pm +++ b/contrib/diff-highlight/DiffHighlight.pm @@ -1,6 +1,6 @@ package DiffHighlight; -use 5.008001; +require v5.26; use warnings FATAL => 'all'; use strict; diff --git a/contrib/diff-highlight/Makefile b/contrib/diff-highlight/Makefile index f2be7cc9243719..33c2ccc9f70d8b 100644 --- a/contrib/diff-highlight/Makefile +++ b/contrib/diff-highlight/Makefile @@ -1,4 +1,5 @@ -all: diff-highlight +# The default target of this Makefile is... +all:: diff-highlight PERL_PATH = /usr/bin/perl -include ../../config.mak diff --git a/contrib/diff-highlight/t/Makefile b/contrib/diff-highlight/t/Makefile index 5ff5275496c556..2a985414774c4b 100644 --- a/contrib/diff-highlight/t/Makefile +++ b/contrib/diff-highlight/t/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + -include ../../../config.mak.autogen -include ../../../config.mak @@ -6,7 +9,7 @@ SHELL_PATH ?= $(SHELL) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh) -all: test +all:: test test: $(T) .PHONY: help clean all test $(T) diff --git a/contrib/libgit-rs/Cargo.lock b/contrib/libgit-rs/Cargo.lock new file mode 100644 index 00000000000000..a30c7c8d33ee30 --- /dev/null +++ b/contrib/libgit-rs/Cargo.lock @@ -0,0 +1,77 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libgit" +version = "0.1.0" +dependencies = [ + "autocfg", + "libgit-sys", +] + +[[package]] +name = "libgit-sys" +version = "0.1.0" +dependencies = [ + "autocfg", + "libz-sys", + "make-cmd", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "make-cmd" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" diff --git a/contrib/libgit-rs/Cargo.toml b/contrib/libgit-rs/Cargo.toml new file mode 100644 index 00000000000000..c3289e69db5939 --- /dev/null +++ b/contrib/libgit-rs/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "libgit" +version = "0.1.0" +edition = "2021" +build = "build.rs" +rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from + # version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/ + + +[lib] +path = "src/lib.rs" + +[dependencies] +libgit-sys = { version = "0.1.0", path = "../libgit-sys" } + +[build-dependencies] +autocfg = "1.4.0" diff --git a/contrib/libgit-rs/README.md b/contrib/libgit-rs/README.md new file mode 100644 index 00000000000000..ff945e1ce207e5 --- /dev/null +++ b/contrib/libgit-rs/README.md @@ -0,0 +1,13 @@ +# libgit-rs + +Proof-of-concept Git bindings for Rust. + +```toml +[dependencies] +libgit = "0.1.0" +``` + +## Rust version requirements + +libgit-rs should support Rust versions at least as old as the version included +in Debian stable (currently 1.63). diff --git a/contrib/libgit-rs/build.rs b/contrib/libgit-rs/build.rs new file mode 100644 index 00000000000000..f8bd01a690b1eb --- /dev/null +++ b/contrib/libgit-rs/build.rs @@ -0,0 +1,4 @@ +pub fn main() { + let ac = autocfg::new(); + ac.emit_has_path("std::ffi::c_char"); +} diff --git a/contrib/libgit-rs/src/config.rs b/contrib/libgit-rs/src/config.rs new file mode 100644 index 00000000000000..6bf04845c8f01b --- /dev/null +++ b/contrib/libgit-rs/src/config.rs @@ -0,0 +1,106 @@ +use std::ffi::{c_void, CStr, CString}; +use std::path::Path; + +#[cfg(has_std__ffi__c_char)] +use std::ffi::{c_char, c_int}; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +type c_char = i8; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +type c_int = i32; + +use libgit_sys::*; + +/// A ConfigSet is an in-memory cache for config-like files such as `.gitmodules` or `.gitconfig`. +/// It does not support all config directives; notably, it will not process `include` or +/// `includeIf` directives (but it will store them so that callers can choose whether and how to +/// handle them). +pub struct ConfigSet(*mut libgit_config_set); +impl ConfigSet { + /// Allocate a new ConfigSet + pub fn new() -> Self { + unsafe { ConfigSet(libgit_configset_alloc()) } + } + + /// Load the given files into the ConfigSet; conflicting directives in later files will + /// override those given in earlier files. + pub fn add_files(&mut self, files: &[&Path]) { + for file in files { + let pstr = file.to_str().expect("Invalid UTF-8"); + let rs = CString::new(pstr).expect("Couldn't convert to CString"); + unsafe { + libgit_configset_add_file(self.0, rs.as_ptr()); + } + } + } + + /// Load the value for the given key and attempt to parse it as an i32. Dies with a fatal error + /// if the value cannot be parsed. Returns None if the key is not present. + pub fn get_int(&mut self, key: &str) -> Option<i32> { + let key = CString::new(key).expect("Couldn't convert to CString"); + let mut val: c_int = 0; + unsafe { + if libgit_configset_get_int(self.0, key.as_ptr(), &mut val as *mut c_int) != 0 { + return None; + } + } + + Some(val.into()) + } + + /// Clones the value for the given key. Dies with a fatal error if the value cannot be + /// converted to a String. Returns None if the key is not present. + pub fn get_string(&mut self, key: &str) -> Option<String> { + let key = CString::new(key).expect("Couldn't convert key to CString"); + let mut val: *mut c_char = std::ptr::null_mut(); + unsafe { + if libgit_configset_get_string(self.0, key.as_ptr(), &mut val as *mut *mut c_char) != 0 + { + return None; + } + let borrowed_str = CStr::from_ptr(val); + let owned_str = + String::from(borrowed_str.to_str().expect("Couldn't convert val to str")); + free(val as *mut c_void); // Free the xstrdup()ed pointer from the C side + Some(owned_str) + } + } +} + +impl Default for ConfigSet { + fn default() -> Self { + Self::new() + } +} + +impl Drop for ConfigSet { + fn drop(&mut self) { + unsafe { + libgit_configset_free(self.0); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn load_configs_via_configset() { + let mut cs = ConfigSet::new(); + cs.add_files(&[ + Path::new("testdata/config1"), + Path::new("testdata/config2"), + Path::new("testdata/config3"), + ]); + // ConfigSet retrieves correct value + assert_eq!(cs.get_int("trace2.eventTarget"), Some(1)); + // ConfigSet respects last config value set + assert_eq!(cs.get_int("trace2.eventNesting"), Some(3)); + // ConfigSet returns None for missing key + assert_eq!(cs.get_string("foo.bar"), None); + } +} diff --git a/contrib/libgit-rs/src/lib.rs b/contrib/libgit-rs/src/lib.rs new file mode 100644 index 00000000000000..ef68c36943d46d --- /dev/null +++ b/contrib/libgit-rs/src/lib.rs @@ -0,0 +1 @@ +pub mod config; diff --git a/contrib/libgit-rs/testdata/config1 b/contrib/libgit-rs/testdata/config1 new file mode 100644 index 00000000000000..4e9a9d25d1ffe8 --- /dev/null +++ b/contrib/libgit-rs/testdata/config1 @@ -0,0 +1,2 @@ +[trace2] + eventNesting = 1 diff --git a/contrib/libgit-rs/testdata/config2 b/contrib/libgit-rs/testdata/config2 new file mode 100644 index 00000000000000..b8d1eca4235f20 --- /dev/null +++ b/contrib/libgit-rs/testdata/config2 @@ -0,0 +1,2 @@ +[trace2] + eventTarget = 1 diff --git a/contrib/libgit-rs/testdata/config3 b/contrib/libgit-rs/testdata/config3 new file mode 100644 index 00000000000000..ca7b9a7c38039c --- /dev/null +++ b/contrib/libgit-rs/testdata/config3 @@ -0,0 +1,2 @@ +[trace2] + eventNesting = 3 diff --git a/contrib/libgit-sys/Cargo.lock b/contrib/libgit-sys/Cargo.lock new file mode 100644 index 00000000000000..427a4c66b7e2cd --- /dev/null +++ b/contrib/libgit-sys/Cargo.lock @@ -0,0 +1,69 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "cc" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +dependencies = [ + "shlex", +] + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libgit-sys" +version = "0.1.0" +dependencies = [ + "autocfg", + "libz-sys", + "make-cmd", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "make-cmd" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3" + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" diff --git a/contrib/libgit-sys/Cargo.toml b/contrib/libgit-sys/Cargo.toml new file mode 100644 index 00000000000000..e0623022c35f01 --- /dev/null +++ b/contrib/libgit-sys/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "libgit-sys" +version = "0.1.0" +edition = "2021" +build = "build.rs" +links = "gitpub" +rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from + # version control. See https://lore.kernel.org/git/Z47jgK-oMjFRSslr@tapette.crustytoothpaste.net/ +description = "Native bindings to a portion of libgit" + +[lib] +path = "src/lib.rs" + +[dependencies] +libz-sys = "1.1.19" + +[build-dependencies] +autocfg = "1.4.0" +make-cmd = "0.1.0" diff --git a/contrib/libgit-sys/README.md b/contrib/libgit-sys/README.md new file mode 100644 index 00000000000000..c061cfcaf58f4d --- /dev/null +++ b/contrib/libgit-sys/README.md @@ -0,0 +1,4 @@ +# libgit-sys + +A small proof-of-concept crate showing how to provide a Rust FFI to Git +internals. diff --git a/contrib/libgit-sys/build.rs b/contrib/libgit-sys/build.rs new file mode 100644 index 00000000000000..3ffd80ad91075c --- /dev/null +++ b/contrib/libgit-sys/build.rs @@ -0,0 +1,35 @@ +use std::env; +use std::path::PathBuf; + +pub fn main() -> std::io::Result<()> { + let ac = autocfg::new(); + ac.emit_has_path("std::ffi::c_char"); + + let crate_root = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()); + let git_root = crate_root.join("../.."); + let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + let make_output = make_cmd::gnu_make() + .env("DEVELOPER", "1") + .env_remove("PROFILE") + .current_dir(git_root.clone()) + .args([ + "INCLUDE_LIBGIT_RS=YesPlease", + "contrib/libgit-sys/libgitpub.a", + ]) + .output() + .expect("Make failed to run"); + if !make_output.status.success() { + panic!( + "Make failed:\n stdout = {}\n stderr = {}\n", + String::from_utf8(make_output.stdout).unwrap(), + String::from_utf8(make_output.stderr).unwrap() + ); + } + std::fs::copy(crate_root.join("libgitpub.a"), dst.join("libgitpub.a"))?; + println!("cargo:rustc-link-search=native={}", dst.display()); + println!("cargo:rustc-link-lib=gitpub"); + println!("cargo:rerun-if-changed={}", git_root.display()); + + Ok(()) +} diff --git a/contrib/libgit-sys/public_symbol_export.c b/contrib/libgit-sys/public_symbol_export.c new file mode 100644 index 00000000000000..dfbb2571152d6e --- /dev/null +++ b/contrib/libgit-sys/public_symbol_export.c @@ -0,0 +1,59 @@ +/* + * Shim to publicly export Git symbols. These must be renamed so that the + * original symbols can be hidden. Renaming these with a "libgit_" prefix also + * avoids conflicts with other libraries such as libgit2. + */ + +#include "git-compat-util.h" +#include "config.h" +#include "contrib/libgit-sys/public_symbol_export.h" +#include "version.h" + +#pragma GCC visibility push(default) + +struct libgit_config_set { + struct config_set cs; +}; + +struct libgit_config_set *libgit_configset_alloc(void) +{ + struct libgit_config_set *cs = + xmalloc(sizeof(struct libgit_config_set)); + git_configset_init(&cs->cs); + return cs; +} + +void libgit_configset_free(struct libgit_config_set *cs) +{ + git_configset_clear(&cs->cs); + free(cs); +} + +int libgit_configset_add_file(struct libgit_config_set *cs, const char *filename) +{ + return git_configset_add_file(&cs->cs, filename); +} + +int libgit_configset_get_int(struct libgit_config_set *cs, const char *key, + int *dest) +{ + return git_configset_get_int(&cs->cs, key, dest); +} + +int libgit_configset_get_string(struct libgit_config_set *cs, const char *key, + char **dest) +{ + return git_configset_get_string(&cs->cs, key, dest); +} + +const char *libgit_user_agent(void) +{ + return git_user_agent(); +} + +const char *libgit_user_agent_sanitized(void) +{ + return git_user_agent_sanitized(); +} + +#pragma GCC visibility pop diff --git a/contrib/libgit-sys/public_symbol_export.h b/contrib/libgit-sys/public_symbol_export.h new file mode 100644 index 00000000000000..701db92d53461d --- /dev/null +++ b/contrib/libgit-sys/public_symbol_export.h @@ -0,0 +1,18 @@ +#ifndef PUBLIC_SYMBOL_EXPORT_H +#define PUBLIC_SYMBOL_EXPORT_H + +struct libgit_config_set *libgit_configset_alloc(void); + +void libgit_configset_free(struct libgit_config_set *cs); + +int libgit_configset_add_file(struct libgit_config_set *cs, const char *filename); + +int libgit_configset_get_int(struct libgit_config_set *cs, const char *key, int *dest); + +int libgit_configset_get_string(struct libgit_config_set *cs, const char *key, char **dest); + +const char *libgit_user_agent(void); + +const char *libgit_user_agent_sanitized(void); + +#endif /* PUBLIC_SYMBOL_EXPORT_H */ diff --git a/contrib/libgit-sys/src/lib.rs b/contrib/libgit-sys/src/lib.rs new file mode 100644 index 00000000000000..4bfc65045026cf --- /dev/null +++ b/contrib/libgit-sys/src/lib.rs @@ -0,0 +1,79 @@ +use std::ffi::c_void; + +#[cfg(has_std__ffi__c_char)] +use std::ffi::{c_char, c_int}; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +pub type c_char = i8; + +#[cfg(not(has_std__ffi__c_char))] +#[allow(non_camel_case_types)] +pub type c_int = i32; + +extern crate libz_sys; + +#[allow(non_camel_case_types)] +#[repr(C)] +pub struct libgit_config_set { + _data: [u8; 0], + _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>, +} + +extern "C" { + pub fn free(ptr: *mut c_void); + + pub fn libgit_user_agent() -> *const c_char; + pub fn libgit_user_agent_sanitized() -> *const c_char; + + pub fn libgit_configset_alloc() -> *mut libgit_config_set; + pub fn libgit_configset_free(cs: *mut libgit_config_set); + + pub fn libgit_configset_add_file(cs: *mut libgit_config_set, filename: *const c_char) -> c_int; + + pub fn libgit_configset_get_int( + cs: *mut libgit_config_set, + key: *const c_char, + int: *mut c_int, + ) -> c_int; + + pub fn libgit_configset_get_string( + cs: *mut libgit_config_set, + key: *const c_char, + dest: *mut *mut c_char, + ) -> c_int; + +} + +#[cfg(test)] +mod tests { + use std::ffi::CStr; + + use super::*; + + #[test] + fn user_agent_starts_with_git() { + let c_str = unsafe { CStr::from_ptr(libgit_user_agent()) }; + let agent = c_str + .to_str() + .expect("User agent contains invalid UTF-8 data"); + assert!( + agent.starts_with("git/"), + r#"Expected user agent to start with "git/", got: {}"#, + agent + ); + } + + #[test] + fn sanitized_user_agent_starts_with_git() { + let c_str = unsafe { CStr::from_ptr(libgit_user_agent_sanitized()) }; + let agent = c_str + .to_str() + .expect("Sanitized user agent contains invalid UTF-8 data"); + assert!( + agent.starts_with("git/"), + r#"Expected user agent to start with "git/", got: {}"#, + agent + ); + } +} diff --git a/contrib/long-running-filter/example.pl b/contrib/long-running-filter/example.pl index a677569ddd95f4..4b83e4c5e89427 100755 --- a/contrib/long-running-filter/example.pl +++ b/contrib/long-running-filter/example.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Example implementation for the Git filter protocol version 2 -# See Documentation/gitattributes.txt, section "Filter Protocol" +# See Documentation/gitattributes.adoc, section "Filter Protocol" # # Please note, this pass-thru filter is a minimal skeleton. No proper # error handling was implemented. diff --git a/contrib/meson.build b/contrib/meson.build new file mode 100644 index 00000000000000..a88c5dfe09ed62 --- /dev/null +++ b/contrib/meson.build @@ -0,0 +1,6 @@ +foreach feature : get_option('contrib') + subdir(feature) +endforeach + +subdir('coccinelle') +subdir('credential') diff --git a/contrib/mw-to-git/Git/Mediawiki.pm b/contrib/mw-to-git/Git/Mediawiki.pm index ff7811225ee671..629c0cea44234e 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.008001; +require v5.26; use strict; use POSIX; use Git; diff --git a/contrib/mw-to-git/Makefile b/contrib/mw-to-git/Makefile index 4e603512a39fe2..497ac434d608a2 100644 --- a/contrib/mw-to-git/Makefile +++ b/contrib/mw-to-git/Makefile @@ -12,6 +12,9 @@ # # make install +# The default target of this Makefile is... +all:: + GIT_MEDIAWIKI_PM=Git/Mediawiki.pm SCRIPT_PERL=git-remote-mediawiki.perl SCRIPT_PERL+=git-mw.perl @@ -27,7 +30,7 @@ INSTLIBDIR=$(shell $(MAKE) -C $(GIT_ROOT_DIR)/ \ DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) INSTLIBDIR_SQ = $(subst ','\'',$(INSTLIBDIR)) -all: build +all:: build test: all $(MAKE) -C t diff --git a/contrib/mw-to-git/t/Makefile b/contrib/mw-to-git/t/Makefile index f422203fa069fc..6c9f377caac330 100644 --- a/contrib/mw-to-git/t/Makefile +++ b/contrib/mw-to-git/t/Makefile @@ -8,7 +8,8 @@ # ## Test git-remote-mediawiki -all: test +# The default target of this Makefile is... +all:: test -include ../../../config.mak.autogen -include ../../../config.mak diff --git a/contrib/persistent-https/Makefile b/contrib/persistent-https/Makefile index 52b84ba3d4396e..691737e76be708 100644 --- a/contrib/persistent-https/Makefile +++ b/contrib/persistent-https/Makefile @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +# The default target of this Makefile is... +all:: + BUILD_LABEL=$(shell cut -d" " -f3 ../../GIT-VERSION-FILE) TAR_OUT=$(shell go env GOOS)_$(shell go env GOARCH).tar.gz -all: git-remote-persistent-https git-remote-persistent-https--proxy \ +all:: git-remote-persistent-https git-remote-persistent-https--proxy \ git-remote-persistent-http git-remote-persistent-https--proxy: git-remote-persistent-https diff --git a/contrib/subtree/.gitignore b/contrib/subtree/.gitignore index 0b9381abcad34e..6deaf177c7a7ef 100644 --- a/contrib/subtree/.gitignore +++ b/contrib/subtree/.gitignore @@ -1,4 +1,6 @@ *~ +asciidoc.conf +asciidoctor-extensions.rb git-subtree git-subtree.1 git-subtree.html diff --git a/contrib/subtree/Makefile b/contrib/subtree/Makefile index 6fa7496bfdb3fd..c0c9f21cb78022 100644 --- a/contrib/subtree/Makefile +++ b/contrib/subtree/Makefile @@ -1,6 +1,7 @@ # The default target of this Makefile is... all:: +-include ../../shared.mak -include ../../config.mak.autogen -include ../../config.mak @@ -13,17 +14,16 @@ htmldir ?= $(prefix)/share/doc/git-doc ../../GIT-VERSION-FILE: FORCE $(MAKE) -C ../../ GIT-VERSION-FILE --include ../../GIT-VERSION-FILE - # this should be set to a 'standard' bsd-type install program INSTALL ?= install RM ?= rm -f ASCIIDOC = asciidoc -ASCIIDOC_CONF = -f ../../Documentation/asciidoc.conf +ASCIIDOC_CONF = -f asciidoc.conf ASCIIDOC_HTML = xhtml11 ASCIIDOC_DOCBOOK = docbook ASCIIDOC_EXTRA = +ASCIIDOC_DEPS = asciidoc.conf XMLTO = xmlto XMLTO_EXTRA = @@ -32,8 +32,9 @@ ASCIIDOC = asciidoctor ASCIIDOC_CONF = ASCIIDOC_HTML = xhtml5 ASCIIDOC_DOCBOOK = docbook -ASCIIDOC_EXTRA += -I../../Documentation -rasciidoctor-extensions +ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;' +ASCIIDOC_DEPS = asciidoctor-extensions.rb XMLTO_EXTRA += --skip-validation endif @@ -49,7 +50,7 @@ GIT_SUBTREE := git-subtree GIT_SUBTREE_DOC := git-subtree.1 GIT_SUBTREE_XML := git-subtree.xml -GIT_SUBTREE_TXT := git-subtree.txt +GIT_SUBTREE_TXT := git-subtree.adoc GIT_SUBTREE_HTML := git-subtree.html GIT_SUBTREE_TEST := ../../git-subtree @@ -82,13 +83,13 @@ install-html: $(GIT_SUBTREE_HTML) $(GIT_SUBTREE_DOC): $(GIT_SUBTREE_XML) $(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $^ -$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT) +$(GIT_SUBTREE_XML): $(GIT_SUBTREE_TXT) $(ASCIIDOC_DEPS) $(ASCIIDOC) -b $(ASCIIDOC_DOCBOOK) -d manpage $(ASCIIDOC_CONF) \ - -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^ + $(ASCIIDOC_EXTRA) $< -$(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT) +$(GIT_SUBTREE_HTML): $(GIT_SUBTREE_TXT) $(ASCIIDOC_DEPS) $(ASCIIDOC) -b $(ASCIIDOC_HTML) -d manpage $(ASCIIDOC_CONF) \ - -agit_version=$(GIT_VERSION) $(ASCIIDOC_EXTRA) $^ + $(ASCIIDOC_EXTRA) $< $(GIT_SUBTREE_TEST): $(GIT_SUBTREE) cp $< $@ @@ -98,6 +99,12 @@ test: $(GIT_SUBTREE_TEST) clean: $(RM) $(GIT_SUBTREE) + $(RM) asciidoc.conf asciidoctor-extensions.rb $(RM) *.xml *.html *.1 +asciidoc.conf: ../../Documentation/asciidoc.conf.in ../../GIT-VERSION-FILE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)/../..",$<,$@) +asciidoctor-extensions.rb: ../../Documentation/asciidoctor-extensions.rb.in ../../GIT-VERSION-FILE + $(QUIET_GEN)$(call version_gen,"$(shell pwd)/../..",$<,$@) + .PHONY: FORCE diff --git a/contrib/subtree/git-subtree.txt b/contrib/subtree/git-subtree.adoc similarity index 100% rename from contrib/subtree/git-subtree.txt rename to contrib/subtree/git-subtree.adoc diff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 5dab3f506c6e08..15ae86db1b277a 100755 --- a/contrib/subtree/git-subtree.sh +++ b/contrib/subtree/git-subtree.sh @@ -946,7 +946,7 @@ cmd_split () { rev=$(git rev-parse -q --verify "$1^{commit}") || die "fatal: '$1' does not refer to a commit" else - die "fatal: you must provide exactly one revision, and optionnally a repository. Got: '$*'" + die "fatal: you must provide exactly one revision, and optionally a repository. Got: '$*'" fi repository="" if test "$#" = 2 diff --git a/contrib/subtree/meson.build b/contrib/subtree/meson.build new file mode 100644 index 00000000000000..9c72b2362595a6 --- /dev/null +++ b/contrib/subtree/meson.build @@ -0,0 +1,71 @@ +git_subtree = custom_target( + input: 'git-subtree.sh', + output: 'git-subtree', + command: [ + shell, + meson.project_source_root() / 'generate-script.sh', + '@INPUT@', + '@OUTPUT@', + meson.project_build_root() / 'GIT-BUILD-OPTIONS', + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +subtree_test_environment = test_environment +subtree_test_environment.prepend('PATH', meson.current_build_dir()) + +test('t7900-subtree', shell, + args: [ 't7900-subtree.sh' ], + env: subtree_test_environment, + workdir: meson.current_source_dir() / 't', + depends: test_dependencies + bin_wrappers + [ git_subtree ], + timeout: 0, +) + +if get_option('docs').contains('man') + subtree_xml = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-subtree.adoc', + output: 'git-subtree.xml', + ) + + custom_target( + command: [ + xmlto, + '-m', '@INPUT@', + 'man', + subtree_xml, + '-o', + meson.current_build_dir(), + ] + xmlto_extra, + input: [ + '../../Documentation/manpage-normal.xsl', + ], + output: 'git-subtree.1', + install: true, + install_dir: get_option('mandir') / 'man1', + ) +endif + +if get_option('docs').contains('html') + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-subtree.adoc', + output: 'git-subtree.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) +endif diff --git a/contrib/subtree/t/Makefile b/contrib/subtree/t/Makefile index 093399c788178f..2a85f5ee849688 100644 --- a/contrib/subtree/t/Makefile +++ b/contrib/subtree/t/Makefile @@ -3,6 +3,9 @@ # Copyright (c) 2005 Junio C Hamano # +# The default target of this Makefile is... +all:: + -include ../../../config.mak.autogen -include ../../../config.mak @@ -31,7 +34,7 @@ TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh)) TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh)) THELPERS = $(sort $(filter-out $(T),$(wildcard *.sh))) -all: $(DEFAULT_TEST_TARGET) +all:: $(DEFAULT_TEST_TARGET) test: pre-clean $(TEST_LINT) $(MAKE) aggregate-results-and-cleanup diff --git a/contrib/subtree/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index c3bd2a58b941f0..3c6103f6d27083 100755 --- a/contrib/subtree/t/t7900-subtree.sh +++ b/contrib/subtree/t/t7900-subtree.sh @@ -47,7 +47,7 @@ last_commit_subject () { # pre-2.32.0 versions of 'git subtree' would write the hash of the tag # (sub1 below), instead of the commit (sub1^{commit}) in the # "git-subtree-split" trailer. -# We immitate this behaviour below using a replace ref. +# We imitate this behaviour below using a replace ref. # This function creates 3 repositories: # - $1 # - $1-sub (added as subtree "sub" in $1) diff --git a/contrib/thunderbird-patch-inline/appp.sh b/contrib/thunderbird-patch-inline/appp.sh index 1053872eea903c..fdcc9483520a27 100755 --- a/contrib/thunderbird-patch-inline/appp.sh +++ b/contrib/thunderbird-patch-inline/appp.sh @@ -31,7 +31,7 @@ BODY=$(sed -e "1,/${SEP}/d" $1) CMT_MSG=$(sed -e '1,/^$/d' -e '/^---$/,$d' "${PATCH}") DIFF=$(sed -e '1,/^---$/d' "${PATCH}") -CCS=$(echo -e "$CMT_MSG\n$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \ +CCS=$(printf '%s\n%s\n' "$CMT_MSG" "$HEADERS" | sed -n -e 's/^Cc: \(.*\)$/\1,/gp' \ -e 's/^Signed-off-by: \(.*\)/\1,/gp') echo "$SUBJECT" > $1 diff --git a/convert.c b/convert.c index c9a31eb4f03d6c..9cc0ca20ca0776 100644 --- a/convert.c +++ b/convert.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "advice.h" diff --git a/copy.c b/copy.c index d9d20920126905..b668209b6c24fd 100644 --- a/copy.c +++ b/copy.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "copy.h" #include "path.h" @@ -57,7 +59,7 @@ int copy_file(const char *dst, const char *src, int mode) if (close(fdo) != 0) return error_errno("%s: close error", dst); - if (!status && adjust_shared_perm(dst)) + if (!status && adjust_shared_perm(the_repository, dst)) return -1; return status; diff --git a/credential.c b/credential.c index 6dea3859ece338..2594c0c4229ba0 100644 --- a/credential.c +++ b/credential.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -12,7 +12,7 @@ #include "sigchain.h" #include "strbuf.h" #include "urlmatch.h" -#include "git-compat-util.h" +#include "environment.h" #include "trace2.h" #include "repository.h" @@ -129,6 +129,10 @@ static int credential_config_callback(const char *var, const char *value, } else if (!strcmp(key, "usehttppath")) c->use_http_path = git_config_bool(var, value); + else if (!strcmp(key, "sanitizeprompt")) + c->sanitize_prompt = git_config_bool(var, value); + else if (!strcmp(key, "protectprotocol")) + c->protect_protocol = git_config_bool(var, value); return 0; } @@ -165,7 +169,7 @@ static int match_partial_url(const char *url, void *cb) return matches; } -static void credential_apply_config(struct credential *c) +static void credential_apply_config(struct repository *r, struct credential *c) { char *normalized_url; struct urlmatch_config config = URLMATCH_CONFIG_INIT; @@ -190,7 +194,7 @@ static void credential_apply_config(struct credential *c) credential_format(c, &url); normalized_url = url_normalize(url.buf, &config.url); - git_config(urlmatch_config_entry, &config); + repo_config(r, urlmatch_config_entry, &config); string_list_clear(&config.vars, 1); free(normalized_url); urlmatch_config_release(&config); @@ -226,7 +230,8 @@ static void credential_format(struct credential *c, struct strbuf *out) strbuf_addch(out, '@'); } if (c->host) - strbuf_addstr(out, c->host); + strbuf_add_percentencode(out, c->host, + STRBUF_ENCODE_HOST_AND_PORT); if (c->path) { strbuf_addch(out, '/'); strbuf_add_percentencode(out, c->path, 0); @@ -240,7 +245,10 @@ static char *credential_ask_one(const char *what, struct credential *c, struct strbuf prompt = STRBUF_INIT; char *r; - credential_describe(c, &desc); + if (c->sanitize_prompt) + credential_format(c, &desc); + else + credential_describe(c, &desc); if (desc.len) strbuf_addf(&prompt, "%s for '%s': ", what, desc.buf); else @@ -253,34 +261,34 @@ static char *credential_ask_one(const char *what, struct credential *c, return xstrdup(r); } -static int credential_getpass(struct credential *c) +static int credential_getpass(struct repository *r, struct credential *c) { int interactive; char *value; - if (!git_config_get_maybe_bool("credential.interactive", &interactive) && + if (!repo_config_get_maybe_bool(r, "credential.interactive", &interactive) && !interactive) { - trace2_data_intmax("credential", the_repository, + trace2_data_intmax("credential", r, "interactive/skipped", 1); return -1; } - if (!git_config_get_string("credential.interactive", &value)) { + if (!repo_config_get_string(r, "credential.interactive", &value)) { int same = !strcmp(value, "never"); free(value); if (same) { - trace2_data_intmax("credential", the_repository, + trace2_data_intmax("credential", r, "interactive/skipped", 1); return -1; } } - trace2_region_enter("credential", "interactive", the_repository); + trace2_region_enter("credential", "interactive", r); if (!c->username) c->username = credential_ask_one("Username", c, PROMPT_ASKPASS|PROMPT_ECHO); if (!c->password) c->password = credential_ask_one("Password", c, PROMPT_ASKPASS); - trace2_region_leave("credential", "interactive", the_repository); + trace2_region_leave("credential", "interactive", r); return 0; } @@ -381,7 +389,8 @@ int credential_read(struct credential *c, FILE *fp, return 0; } -static void credential_write_item(FILE *fp, const char *key, const char *value, +static void credential_write_item(const struct credential *c, + FILE *fp, const char *key, const char *value, int required) { if (!value && required) @@ -390,6 +399,10 @@ static void credential_write_item(FILE *fp, const char *key, const char *value, return; if (strchr(value, '\n')) die("credential value for %s contains newline", key); + if (c->protect_protocol && strchr(value, '\r')) + die("credential value for %s contains carriage return\n" + "If this is intended, set `credential.protectProtocol=false`", + key); fprintf(fp, "%s=%s\n", key, value); } @@ -397,34 +410,34 @@ void credential_write(const struct credential *c, FILE *fp, enum credential_op_type op_type) { if (credential_has_capability(&c->capa_authtype, op_type)) - credential_write_item(fp, "capability[]", "authtype", 0); + credential_write_item(c, fp, "capability[]", "authtype", 0); if (credential_has_capability(&c->capa_state, op_type)) - credential_write_item(fp, "capability[]", "state", 0); + credential_write_item(c, fp, "capability[]", "state", 0); if (credential_has_capability(&c->capa_authtype, op_type)) { - credential_write_item(fp, "authtype", c->authtype, 0); - credential_write_item(fp, "credential", c->credential, 0); + credential_write_item(c, fp, "authtype", c->authtype, 0); + credential_write_item(c, fp, "credential", c->credential, 0); if (c->ephemeral) - credential_write_item(fp, "ephemeral", "1", 0); + credential_write_item(c, fp, "ephemeral", "1", 0); } - credential_write_item(fp, "protocol", c->protocol, 1); - credential_write_item(fp, "host", c->host, 1); - credential_write_item(fp, "path", c->path, 0); - credential_write_item(fp, "username", c->username, 0); - credential_write_item(fp, "password", c->password, 0); - credential_write_item(fp, "oauth_refresh_token", c->oauth_refresh_token, 0); + credential_write_item(c, fp, "protocol", c->protocol, 1); + credential_write_item(c, fp, "host", c->host, 1); + credential_write_item(c, fp, "path", c->path, 0); + credential_write_item(c, fp, "username", c->username, 0); + credential_write_item(c, fp, "password", c->password, 0); + credential_write_item(c, fp, "oauth_refresh_token", c->oauth_refresh_token, 0); if (c->password_expiry_utc != TIME_MAX) { char *s = xstrfmt("%"PRItime, c->password_expiry_utc); - credential_write_item(fp, "password_expiry_utc", s, 0); + credential_write_item(c, fp, "password_expiry_utc", s, 0); free(s); } for (size_t i = 0; i < c->wwwauth_headers.nr; i++) - credential_write_item(fp, "wwwauth[]", c->wwwauth_headers.v[i], 0); + credential_write_item(c, fp, "wwwauth[]", c->wwwauth_headers.v[i], 0); if (credential_has_capability(&c->capa_state, op_type)) { if (c->multistage) - credential_write_item(fp, "continue", "1", 0); + credential_write_item(c, fp, "continue", "1", 0); for (size_t i = 0; i < c->state_headers_to_send.nr; i++) - credential_write_item(fp, "state[]", c->state_headers_to_send.v[i], 0); + credential_write_item(c, fp, "state[]", c->state_headers_to_send.v[i], 0); } } @@ -488,7 +501,8 @@ static int credential_do(struct credential *c, const char *helper, return r; } -void credential_fill(struct credential *c, int all_capabilities) +void credential_fill(struct repository *r, + struct credential *c, int all_capabilities) { int i; @@ -498,7 +512,7 @@ void credential_fill(struct credential *c, int all_capabilities) credential_next_state(c); c->multistage = 0; - credential_apply_config(c); + credential_apply_config(r, c); if (all_capabilities) credential_set_all_capabilities(c, CREDENTIAL_OP_INITIAL); @@ -525,12 +539,12 @@ void credential_fill(struct credential *c, int all_capabilities) c->helpers.items[i].string); } - if (credential_getpass(c) || + if (credential_getpass(r, c) || (!c->username && !c->password && !c->credential)) die("unable to get password from user"); } -void credential_approve(struct credential *c) +void credential_approve(struct repository *r, struct credential *c) { int i; @@ -541,20 +555,20 @@ void credential_approve(struct credential *c) credential_next_state(c); - credential_apply_config(c); + credential_apply_config(r, c); for (i = 0; i < c->helpers.nr; i++) credential_do(c, c->helpers.items[i].string, "store"); c->approved = 1; } -void credential_reject(struct credential *c) +void credential_reject(struct repository *r, struct credential *c) { int i; credential_next_state(c); - credential_apply_config(c); + credential_apply_config(r, c); for (i = 0; i < c->helpers.nr; i++) credential_do(c, c->helpers.items[i].string, "erase"); diff --git a/credential.h b/credential.h index 5f9e6ff2efef55..c78b72d110eaac 100644 --- a/credential.h +++ b/credential.h @@ -4,6 +4,8 @@ #include "string-list.h" #include "strvec.h" +struct repository; + /** * The credentials API provides an abstracted way of gathering * authentication credentials from the user. @@ -65,7 +67,7 @@ * // Fill in the username and password fields by contacting * // helpers and/or asking the user. The function will die if it * // fails. - * credential_fill(&c); + * credential_fill(repo, &c); * * // Otherwise, we have a username and password. Try to use it. * @@ -168,7 +170,9 @@ struct credential { multistage: 1, quit:1, use_http_path:1, - username_from_proto:1; + username_from_proto:1, + sanitize_prompt:1, + protect_protocol:1; struct credential_capability capa_authtype; struct credential_capability capa_state; @@ -195,6 +199,8 @@ struct credential { .wwwauth_headers = STRVEC_INIT, \ .state_headers = STRVEC_INIT, \ .state_headers_to_send = STRVEC_INIT, \ + .sanitize_prompt = 1, \ + .protect_protocol = 1, \ } /* Initialize a credential structure, setting all fields to empty. */ @@ -218,7 +224,8 @@ void credential_clear(struct credential *); * If all_capabilities is set, this is an internal user that is prepared * to deal with all known capabilities, and we should advertise that fact. */ -void credential_fill(struct credential *, int all_capabilities); +void credential_fill(struct repository *, struct credential *, + int all_capabilities); /** * Inform the credential subsystem that the provided credentials @@ -227,7 +234,7 @@ void credential_fill(struct credential *, int all_capabilities); * that they may store the result to be used again. Any errors * from helpers are ignored. */ -void credential_approve(struct credential *); +void credential_approve(struct repository *, struct credential *); /** * Inform the credential subsystem that the provided credentials @@ -239,7 +246,7 @@ void credential_approve(struct credential *); * for another call to `credential_fill`). Any errors from helpers * are ignored. */ -void credential_reject(struct credential *); +void credential_reject(struct repository *, struct credential *); /** * Enable all of the supported credential flags in this credential. diff --git a/csum-file.c b/csum-file.c index bf82ad8f9f5522..b58c183a4f020a 100644 --- a/csum-file.c +++ b/csum-file.c @@ -11,9 +11,10 @@ #define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" -#include "progress.h" #include "csum-file.h" +#include "git-zlib.h" #include "hash.h" +#include "progress.h" static void verify_buffer_or_die(struct hashfile *f, const void *buf, @@ -23,7 +24,7 @@ static void verify_buffer_or_die(struct hashfile *f, if (ret < 0) die_errno("%s: sha1 file read error", f->name); - if (ret != count) + if ((size_t)ret != count) die("%s: sha1 file truncated", f->name); if (memcmp(buf, f->check_buffer, count)) die("sha1 file '%s' validation error", f->name); @@ -50,7 +51,7 @@ void hashflush(struct hashfile *f) if (offset) { if (!f->skip_hash) - the_hash_algo->update_fn(&f->ctx, f->buffer, offset); + git_hash_update(&f->ctx, f->buffer, offset); flush(f, f->buffer, offset); f->offset = 0; } @@ -71,14 +72,14 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result, hashflush(f); if (f->skip_hash) - hashclr(f->buffer, the_repository->hash_algo); + hashclr(f->buffer, f->algop); else - the_hash_algo->final_fn(f->buffer, &f->ctx); + git_hash_final(f->buffer, &f->ctx); if (result) - hashcpy(result, f->buffer, the_repository->hash_algo); + hashcpy(result, f->buffer, f->algop); if (flags & CSUM_HASH_IN_STREAM) - flush(f, f->buffer, the_hash_algo->rawsz); + flush(f, f->buffer, f->algop->rawsz); if (flags & CSUM_FSYNC) fsync_component_or_die(component, f->fd, f->name); if (flags & CSUM_CLOSE) { @@ -128,7 +129,7 @@ void hashwrite(struct hashfile *f, const void *buf, unsigned int count) * f->offset is necessarily zero. */ if (!f->skip_hash) - the_hash_algo->update_fn(&f->ctx, buf, nr); + git_hash_update(&f->ctx, buf, nr); flush(f, buf, nr); } else { /* @@ -174,7 +175,9 @@ static struct hashfile *hashfd_internal(int fd, const char *name, f->name = name; f->do_crc = 0; f->skip_hash = 0; - the_hash_algo->init_fn(&f->ctx); + + f->algop = unsafe_hash_algo(the_hash_algo); + f->algop->init_fn(&f->ctx); f->buffer_len = buffer_len; f->buffer = xmalloc(buffer_len); @@ -204,11 +207,18 @@ struct hashfile *hashfd_throughput(int fd, const char *name, struct progress *tp return hashfd_internal(fd, name, tp, 8 * 1024); } +void hashfile_checkpoint_init(struct hashfile *f, + struct hashfile_checkpoint *checkpoint) +{ + memset(checkpoint, 0, sizeof(*checkpoint)); + f->algop->init_fn(&checkpoint->ctx); +} + void hashfile_checkpoint(struct hashfile *f, struct hashfile_checkpoint *checkpoint) { hashflush(f); checkpoint->offset = f->total; - the_hash_algo->clone_fn(&checkpoint->ctx, &f->ctx); + git_hash_clone(&checkpoint->ctx, &f->ctx); } int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint) @@ -219,7 +229,7 @@ int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint lseek(f->fd, offset, SEEK_SET) != offset) return -1; f->total = offset; - the_hash_algo->clone_fn(&f->ctx, &checkpoint->ctx); + git_hash_clone(&f->ctx, &checkpoint->ctx); f->offset = 0; /* hashflush() was called in checkpoint */ return 0; } @@ -239,15 +249,16 @@ uint32_t crc32_end(struct hashfile *f) int hashfile_checksum_valid(const unsigned char *data, size_t total_len) { unsigned char got[GIT_MAX_RAWSZ]; - git_hash_ctx ctx; - size_t data_len = total_len - the_hash_algo->rawsz; + struct git_hash_ctx ctx; + const struct git_hash_algo *algop = unsafe_hash_algo(the_hash_algo); + size_t data_len = total_len - algop->rawsz; - if (total_len < the_hash_algo->rawsz) + if (total_len < algop->rawsz) return 0; /* say "too short"? */ - the_hash_algo->init_fn(&ctx); - the_hash_algo->update_fn(&ctx, data, data_len); - the_hash_algo->final_fn(got, &ctx); + algop->init_fn(&ctx); + git_hash_update(&ctx, data, data_len); + git_hash_final(got, &ctx); - return hasheq(got, data + data_len, the_repository->hash_algo); + return hasheq(got, data + data_len, algop); } diff --git a/csum-file.h b/csum-file.h index 7c73da0a40a9f3..ffccbf09966c08 100644 --- a/csum-file.h +++ b/csum-file.h @@ -11,7 +11,7 @@ struct hashfile { int fd; int check_fd; unsigned int offset; - git_hash_ctx ctx; + struct git_hash_ctx ctx; off_t total; struct progress *tp; const char *name; @@ -20,6 +20,7 @@ struct hashfile { size_t buffer_len; unsigned char *buffer; unsigned char *check_buffer; + const struct git_hash_algo *algop; /** * If non-zero, skip_hash indicates that we should @@ -32,9 +33,10 @@ struct hashfile { /* Checkpoint */ struct hashfile_checkpoint { off_t offset; - git_hash_ctx ctx; + struct git_hash_ctx ctx; }; +void hashfile_checkpoint_init(struct hashfile *, struct hashfile_checkpoint *); void hashfile_checkpoint(struct hashfile *, struct hashfile_checkpoint *); int hashfile_truncate(struct hashfile *, struct hashfile_checkpoint *); diff --git a/daemon.c b/daemon.c index cb946e3c95f16d..d1be61fd578949 100644 --- a/daemon.c +++ b/daemon.c @@ -4,6 +4,7 @@ #include "abspath.h" #include "config.h" #include "environment.h" +#include "gettext.h" #include "path.h" #include "pkt-line.h" #include "protocol.h" @@ -151,6 +152,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) size_t rlen; const char *path; const char *dir; + unsigned enter_repo_flags; dir = directory; @@ -241,14 +243,15 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) dir = rpath; } - path = enter_repo(dir, strict_paths); + enter_repo_flags = strict_paths ? ENTER_REPO_STRICT : 0; + path = enter_repo(dir, enter_repo_flags); if (!path && base_path && base_path_relaxed) { /* * if we fail and base_path_relaxed is enabled, try without * prefixing the base path */ dir = directory; - path = enter_repo(dir, strict_paths); + path = enter_repo(dir, enter_repo_flags); } if (!path) { @@ -501,8 +504,7 @@ static struct daemon_service daemon_service[] = { static void enable_service(const char *name, int ena) { - int i; - for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { + for (size_t i = 0; i < ARRAY_SIZE(daemon_service); i++) { if (!strcmp(daemon_service[i].name, name)) { daemon_service[i].enabled = ena; return; @@ -513,8 +515,7 @@ static void enable_service(const char *name, int ena) static void make_service_overridable(const char *name, int ena) { - int i; - for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { + for (size_t i = 0; i < ARRAY_SIZE(daemon_service); i++) { if (!strcmp(daemon_service[i].name, name)) { daemon_service[i].overridable = ena; return; @@ -735,7 +736,7 @@ static void set_keep_alive(int sockfd) static int execute(void) { char *line = packet_buffer; - int pktlen, len, i; + int pktlen, len; char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT"); struct hostinfo hi = HOSTINFO_INIT; struct strvec env = STRVEC_INIT; @@ -756,7 +757,7 @@ static int execute(void) if (len != pktlen) parse_extra_args(&hi, &env, line + len + 1, pktlen - len - 1); - for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { + for (size_t i = 0; i < ARRAY_SIZE(daemon_service); i++) { struct daemon_service *s = &(daemon_service[i]); const char *arg; @@ -801,8 +802,7 @@ static int addrcmp(const struct sockaddr_storage *s1, return 0; } -static int max_connections = 32; - +static unsigned int max_connections = 32; static unsigned int live_children; static struct child { @@ -1106,8 +1106,8 @@ static void socksetup(struct string_list *listen_addr, int listen_port, struct s if (!listen_addr->nr) setup_named_sock(NULL, listen_port, socklist); else { - int i, socknum; - for (i = 0; i < listen_addr->nr; i++) { + int socknum; + for (size_t i = 0; i < listen_addr->nr; i++) { socknum = setup_named_sock(listen_addr->items[i].string, listen_port, socklist); @@ -1121,11 +1121,10 @@ static void socksetup(struct string_list *listen_addr, int listen_port, struct s static int service_loop(struct socketlist *socklist) { struct pollfd *pfd; - int i; CALLOC_ARRAY(pfd, socklist->nr); - for (i = 0; i < socklist->nr; i++) { + for (size_t i = 0; i < socklist->nr; i++) { pfd[i].fd = socklist->list[i]; pfd[i].events = POLLIN; } @@ -1133,8 +1132,6 @@ static int service_loop(struct socketlist *socklist) signal(SIGCHLD, child_handler); for (;;) { - int i; - check_dead_children(); if (poll(pfd, socklist->nr, -1) < 0) { @@ -1146,7 +1143,7 @@ static int service_loop(struct socketlist *socklist) continue; } - for (i = 0; i < socklist->nr; i++) { + for (size_t i = 0; i < socklist->nr; i++) { if (pfd[i].revents & POLLIN) { union { struct sockaddr sa; @@ -1308,17 +1305,21 @@ int cmd_main(int argc, const char **argv) continue; } if (skip_prefix(arg, "--timeout=", &v)) { - timeout = atoi(v); + if (strtoul_ui(v, 10, &timeout)) + die(_("invalid timeout '%s', expecting a non-negative integer"), v); continue; } if (skip_prefix(arg, "--init-timeout=", &v)) { - init_timeout = atoi(v); + if (strtoul_ui(v, 10, &init_timeout)) + die(_("invalid init-timeout '%s', expecting a non-negative integer"), v); continue; } if (skip_prefix(arg, "--max-connections=", &v)) { - max_connections = atoi(v); - if (max_connections < 0) - max_connections = 0; /* unlimited */ + int parsed_value; + if (strtol_i(v, 10, &parsed_value)) + die(_("invalid max-connections '%s', expecting an integer"), v); + /* A negative value indicates unlimited children. */ + max_connections = parsed_value < 0 ? 0 : parsed_value; continue; } if (!strcmp(arg, "--strict-paths")) { diff --git a/date.c b/date.c index bee9fe8f102596..17a95077cf5450 100644 --- a/date.c +++ b/date.c @@ -4,6 +4,8 @@ * Copyright (C) Linus Torvalds, 2005 */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "date.h" #include "gettext.h" @@ -1242,7 +1244,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm } for (s = special; s->name; s++) { - int len = strlen(s->name); + size_t len = strlen(s->name); if (match_string(date, s->name) == len) { s->fn(tm, now, num); *touched = 1; @@ -1252,7 +1254,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm if (!*num) { for (i = 1; i < 11; i++) { - int len = strlen(number_name[i]); + size_t len = strlen(number_name[i]); if (match_string(date, number_name[i]) == len) { *num = i; *touched = 1; @@ -1268,7 +1270,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm tl = typelen; while (tl->type) { - int len = strlen(tl->type); + size_t len = strlen(tl->type); if (match_string(date, tl->type) >= len-1) { update_tm(tm, now, tl->length * *num); *num = 0; diff --git a/decorate.c b/decorate.c index 69aeb142b45e9f..e161e13772891f 100644 --- a/decorate.c +++ b/decorate.c @@ -2,6 +2,9 @@ * decorate.c - decorate a git object with some arbitrary * data. */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "object.h" #include "decorate.h" diff --git a/delta-islands.c b/delta-islands.c index 844355125935ad..3aec43fada36f7 100644 --- a/delta-islands.c +++ b/delta-islands.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "object.h" @@ -266,7 +267,8 @@ void resolve_tree_islands(struct repository *r, QSORT(todo, nr, tree_depth_compare); if (progress) - progress_state = start_progress(_("Propagating island marks"), nr); + progress_state = start_progress(the_repository, + _("Propagating island marks"), nr); for (i = 0; i < nr; i++) { struct object_entry *ent = todo[i].entry; diff --git a/diagnose.c b/diagnose.c index cc2d535b60d7c8..bd485effea22ce 100644 --- a/diagnose.c +++ b/diagnose.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "diagnose.h" #include "compat/disk.h" @@ -12,6 +10,7 @@ #include "object-store-ll.h" #include "packfile.h" #include "parse-options.h" +#include "repository.h" #include "write-or-die.h" struct archive_dir { @@ -31,7 +30,6 @@ static struct diagnose_option diagnose_options[] = { int option_parse_diagnose(const struct option *opt, const char *arg, int unset) { - int i; enum diagnose_mode *diagnose = opt->value; if (!arg) { @@ -39,7 +37,7 @@ int option_parse_diagnose(const struct option *opt, const char *arg, int unset) return 0; } - for (i = 0; i < ARRAY_SIZE(diagnose_options); i++) { + for (size_t i = 0; i < ARRAY_SIZE(diagnose_options); i++) { if (!strcmp(arg, diagnose_options[i].option_name)) { *diagnose = diagnose_options[i].mode; return 0; @@ -180,13 +178,15 @@ static int add_directory_to_archiver(struct strvec *archiver_args, return res; } -int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode) +int create_diagnostics_archive(struct repository *r, + struct strbuf *zip_path, + enum diagnose_mode mode) { struct strvec archiver_args = STRVEC_INIT; char **argv_copy = NULL; int stdout_fd = -1, archiver_fd = -1; struct strbuf buf = STRBUF_INIT; - int res, i; + int res; struct archive_dir archive_dirs[] = { { ".git", 0 }, { ".git/hooks", 0 }, @@ -219,7 +219,7 @@ int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode) strbuf_addstr(&buf, "Collecting diagnostic info\n\n"); get_version_info(&buf, 1); - strbuf_addf(&buf, "Repository root: %s\n", the_repository->worktree); + strbuf_addf(&buf, "Repository root: %s\n", r->worktree); get_disk_info(&buf); write_or_die(stdout_fd, buf.buf, buf.len); strvec_pushf(&archiver_args, @@ -228,7 +228,7 @@ int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode) strbuf_reset(&buf); strbuf_addstr(&buf, "--add-virtual-file=packs-local.txt:"); - dir_file_stats(the_repository->objects->odb, &buf); + dir_file_stats(r->objects->odb, &buf); foreach_alt_odb(dir_file_stats, &buf); strvec_push(&archiver_args, buf.buf); @@ -239,7 +239,7 @@ int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode) /* Only include this if explicitly requested */ if (mode == DIAGNOSE_ALL) { - for (i = 0; i < ARRAY_SIZE(archive_dirs); i++) { + for (size_t i = 0; i < ARRAY_SIZE(archive_dirs); i++) { if (add_directory_to_archiver(&archiver_args, archive_dirs[i].path, archive_dirs[i].recursive)) { @@ -251,13 +251,13 @@ int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode) } strvec_pushl(&archiver_args, "--prefix=", - oid_to_hex(the_hash_algo->empty_tree), "--", NULL); + oid_to_hex(r->hash_algo->empty_tree), "--", NULL); /* `write_archive()` modifies the `argv` passed to it. Let it. */ argv_copy = xmemdupz(archiver_args.v, sizeof(char *) * archiver_args.nr); res = write_archive(archiver_args.nr, (const char **)argv_copy, NULL, - the_repository, NULL, 0); + r, NULL, 0); if (res) { error(_("failed to write archive")); goto diagnose_cleanup; diff --git a/diagnose.h b/diagnose.h index f525219ab0cf9b..f7b38f49f5271a 100644 --- a/diagnose.h +++ b/diagnose.h @@ -4,6 +4,7 @@ #include "strbuf.h" struct option; +struct repository; enum diagnose_mode { DIAGNOSE_NONE, @@ -13,6 +14,8 @@ enum diagnose_mode { int option_parse_diagnose(const struct option *opt, const char *arg, int unset); -int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode); +int create_diagnostics_archive(struct repository *r, + struct strbuf *zip_path, + enum diagnose_mode mode); #endif /* DIAGNOSE_H */ diff --git a/diff-delta.c b/diff-delta.c index 77fea08dfb04d3..a4faf73829be00 100644 --- a/diff-delta.c +++ b/diff-delta.c @@ -11,6 +11,8 @@ * published by the Free Software Foundation. */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "delta.h" diff --git a/diff-lib.c b/diff-lib.c index a680768ee7549a..353b473ed52e41 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -3,6 +3,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "commit.h" @@ -152,21 +153,8 @@ void run_diff_files(struct rev_info *revs, unsigned int option) struct diff_filepair *pair; unsigned int wt_mode = 0; int num_compare_stages = 0; - size_t path_len; struct stat st; - path_len = ce_namelen(ce); - - dpath = xmalloc(combine_diff_path_size(5, path_len)); - dpath->path = (char *) &(dpath->parent[5]); - - dpath->next = NULL; - memcpy(dpath->path, ce->name, path_len); - dpath->path[path_len] = '\0'; - oidclr(&dpath->oid, the_repository->hash_algo); - memset(&(dpath->parent[0]), 0, - sizeof(struct combine_diff_parent)*5); - changed = check_removed(ce, &st); if (!changed) wt_mode = ce_mode_from_stat(ce, st.st_mode); @@ -177,7 +165,14 @@ void run_diff_files(struct rev_info *revs, unsigned int option) } wt_mode = 0; } - dpath->mode = wt_mode; + + /* + * Allocate space for two parents, which will come from + * index stages #2 and #3, if present. Below we'll fill + * these from (stage - 2). + */ + dpath = combine_diff_path_new(ce->name, ce_namelen(ce), + wt_mode, null_oid(), 2); while (i < entries) { struct cache_entry *nce = istate->cache[i]; @@ -404,16 +399,10 @@ static int show_modified(struct rev_info *revs, if (revs->combine_merges && !cached && (!oideq(oid, &old_entry->oid) || !oideq(&old_entry->oid, &new_entry->oid))) { struct combine_diff_path *p; - int pathlen = ce_namelen(new_entry); - - p = xmalloc(combine_diff_path_size(2, pathlen)); - p->path = (char *) &p->parent[2]; - p->next = NULL; - memcpy(p->path, new_entry->name, pathlen); - p->path[pathlen] = 0; - p->mode = mode; - oidclr(&p->oid, the_repository->hash_algo); - memset(p->parent, 0, 2 * sizeof(struct combine_diff_parent)); + + p = combine_diff_path_new(new_entry->name, + ce_namelen(new_entry), + mode, null_oid(), 2); p->parent[0].status = DIFF_STATUS_MODIFIED; p->parent[0].mode = new_entry->ce_mode; oidcpy(&p->parent[0].oid, &new_entry->oid); @@ -661,6 +650,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt) repo_init_revisions(opt->repo, &revs, NULL); copy_pathspec(&revs.prune_data, &opt->pathspec); + diff_free(&revs.diffopt); revs.diffopt = *opt; revs.diffopt.no_free = 1; @@ -701,7 +691,7 @@ int index_differs_from(struct repository *r, return (has_changes != 0); } -static struct strbuf *idiff_prefix_cb(struct diff_options *opt UNUSED, void *data) +static const char *idiff_prefix_cb(struct diff_options *opt UNUSED, void *data) { return data; } @@ -716,7 +706,7 @@ void show_interdiff(const struct object_id *oid1, const struct object_id *oid2, opts.output_format = DIFF_FORMAT_PATCH; opts.output_prefix = idiff_prefix_cb; strbuf_addchars(&prefix, ' ', indent); - opts.output_prefix_data = &prefix; + opts.output_prefix_data = prefix.buf; diff_setup_done(&opts); diff_tree_oid(oid1, oid2, "", &opts); diff --git a/diff-no-index.c b/diff-no-index.c index c5fb06e6d1a90d..6f277892d3aef6 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -4,6 +4,8 @@ * Copyright (c) 2008 by Junio C Hamano */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "abspath.h" #include "color.h" diff --git a/diff.c b/diff.c index 84a6bb08681e6d..c89c15d98e0e29 100644 --- a/diff.c +++ b/diff.c @@ -3,6 +3,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -443,8 +444,10 @@ int git_diff_ui_config(const char *var, const char *value, } if (!strcmp(var, "diff.wordregex")) return git_config_string(&diff_word_regex_cfg, var, value); - if (!strcmp(var, "diff.orderfile")) + if (!strcmp(var, "diff.orderfile")) { + FREE_AND_NULL(diff_order_file_cfg); return git_config_pathname(&diff_order_file_cfg, var, value); + } if (!strcmp(var, "diff.ignoresubmodules")) { if (!value) @@ -2315,12 +2318,9 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix) const char *diff_line_prefix(struct diff_options *opt) { - struct strbuf *msgbuf; - if (!opt->output_prefix) - return ""; - - msgbuf = opt->output_prefix(opt, opt->output_prefix_data); - return msgbuf->buf; + return opt->output_prefix ? + opt->output_prefix(opt, opt->output_prefix_data) : + ""; } static unsigned long sane_truncate_line(char *line, unsigned long len) @@ -4042,7 +4042,8 @@ static int reuse_worktree_file(struct index_state *istate, * objects however would tend to be slower as they need * to be individually opened and inflated. */ - if (!FAST_WORKING_DIRECTORY && !want_file && has_object_pack(oid)) + if (!FAST_WORKING_DIRECTORY && !want_file && + has_object_pack(istate->repo, oid)) return 0; /* @@ -4778,7 +4779,7 @@ void repo_diff_setup(struct repository *r, struct diff_options *options) if (diff_indent_heuristic) DIFF_XDL_SET(options, INDENT_HEURISTIC); - options->orderfile = diff_order_file_cfg; + options->orderfile = xstrdup_or_null(diff_order_file_cfg); if (!options->flags.ignore_submodule_set) options->flags.ignore_untracked_in_submodules = 1; @@ -5398,7 +5399,6 @@ static int diff_opt_line_prefix(const struct option *opt, BUG_ON_OPT_NEG(unset); options->line_prefix = optarg; - options->line_prefix_length = strlen(options->line_prefix); graph_setup_line_prefix(options); return 0; } @@ -5493,6 +5493,8 @@ static int diff_opt_pickaxe_regex(const struct option *opt, BUG_ON_OPT_NEG(unset); options->pickaxe = arg; options->pickaxe_opts |= DIFF_PICKAXE_KIND_G; + if (arg && !*arg) + return error(_("-G requires a non-empty argument")); return 0; } @@ -5504,6 +5506,8 @@ static int diff_opt_pickaxe_string(const struct option *opt, BUG_ON_OPT_NEG(unset); options->pickaxe = arg; options->pickaxe_opts |= DIFF_PICKAXE_KIND_S; + if (arg && !*arg) + return error(_("-S requires a non-empty argument")); return 0; } @@ -5981,11 +5985,18 @@ void diff_free_filepair(struct diff_filepair *p) free(p); } -void diff_free_queue(struct diff_queue_struct *q) +void diff_queue_init(struct diff_queue_struct *q) +{ + struct diff_queue_struct blank = DIFF_QUEUE_INIT; + memcpy(q, &blank, sizeof(*q)); +} + +void diff_queue_clear(struct diff_queue_struct *q) { for (int i = 0; i < q->nr; i++) diff_free_filepair(q->queue[i]); free(q->queue); + diff_queue_init(q); } const char *diff_aligned_abbrev(const struct object_id *oid, int len) @@ -6385,7 +6396,7 @@ static void diff_summary(struct diff_options *opt, struct diff_filepair *p) } struct patch_id_t { - git_hash_ctx *ctx; + struct git_hash_ctx *ctx; int patchlen; }; @@ -6402,13 +6413,13 @@ static int remove_space(char *line, int len) return dst - line; } -void flush_one_hunk(struct object_id *result, git_hash_ctx *ctx) +void flush_one_hunk(struct object_id *result, struct git_hash_ctx *ctx) { unsigned char hash[GIT_MAX_RAWSZ]; unsigned short carry = 0; int i; - the_hash_algo->final_fn(hash, ctx); + git_hash_final(hash, ctx); the_hash_algo->init_fn(ctx); /* 20-byte sum, with carry */ for (i = 0; i < the_hash_algo->rawsz; ++i) { @@ -6427,22 +6438,22 @@ static int patch_id_consume(void *priv, char *line, unsigned long len) return 0; new_len = remove_space(line, len); - the_hash_algo->update_fn(data->ctx, line, new_len); + git_hash_update(data->ctx, line, new_len); data->patchlen += new_len; return 0; } -static void patch_id_add_string(git_hash_ctx *ctx, const char *str) +static void patch_id_add_string(struct git_hash_ctx *ctx, const char *str) { - the_hash_algo->update_fn(ctx, str, strlen(str)); + git_hash_update(ctx, str, strlen(str)); } -static void patch_id_add_mode(git_hash_ctx *ctx, unsigned mode) +static void patch_id_add_mode(struct git_hash_ctx *ctx, unsigned mode) { /* large enough for 2^32 in octal */ char buf[12]; int len = xsnprintf(buf, sizeof(buf), "%06o", mode); - the_hash_algo->update_fn(ctx, buf, len); + git_hash_update(ctx, buf, len); } /* returns 0 upon success, and writes result into oid */ @@ -6450,7 +6461,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid { struct diff_queue_struct *q = &diff_queued_diff; int i; - git_hash_ctx ctx; + struct git_hash_ctx ctx; struct patch_id_t data; the_hash_algo->init_fn(&ctx); @@ -6486,9 +6497,9 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid len2 = remove_space(p->two->path, strlen(p->two->path)); patch_id_add_string(&ctx, "diff--git"); patch_id_add_string(&ctx, "a/"); - the_hash_algo->update_fn(&ctx, p->one->path, len1); + git_hash_update(&ctx, p->one->path, len1); patch_id_add_string(&ctx, "b/"); - the_hash_algo->update_fn(&ctx, p->two->path, len2); + git_hash_update(&ctx, p->two->path, len2); if (p->one->mode == 0) { patch_id_add_string(&ctx, "newfilemode"); @@ -6507,24 +6518,24 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid /* don't do anything since we're only populating header info */ } else if (diff_filespec_is_binary(options->repo, p->one) || diff_filespec_is_binary(options->repo, p->two)) { - the_hash_algo->update_fn(&ctx, oid_to_hex(&p->one->oid), + git_hash_update(&ctx, oid_to_hex(&p->one->oid), the_hash_algo->hexsz); - the_hash_algo->update_fn(&ctx, oid_to_hex(&p->two->oid), + git_hash_update(&ctx, oid_to_hex(&p->two->oid), the_hash_algo->hexsz); } else { if (p->one->mode == 0) { patch_id_add_string(&ctx, "---/dev/null"); patch_id_add_string(&ctx, "+++b/"); - the_hash_algo->update_fn(&ctx, p->two->path, len2); + git_hash_update(&ctx, p->two->path, len2); } else if (p->two->mode == 0) { patch_id_add_string(&ctx, "---a/"); - the_hash_algo->update_fn(&ctx, p->one->path, len1); + git_hash_update(&ctx, p->one->path, len1); patch_id_add_string(&ctx, "+++/dev/null"); } else { patch_id_add_string(&ctx, "---a/"); - the_hash_algo->update_fn(&ctx, p->one->path, len1); + git_hash_update(&ctx, p->one->path, len1); patch_id_add_string(&ctx, "+++b/"); - the_hash_algo->update_fn(&ctx, p->two->path, len2); + git_hash_update(&ctx, p->two->path, len2); } if (fill_mmfile(options->repo, &mf1, p->one) < 0 || @@ -6549,8 +6560,7 @@ int diff_flush_patch_id(struct diff_options *options, struct object_id *oid, int struct diff_queue_struct *q = &diff_queued_diff; int result = diff_get_patch_id(options, oid, diff_header_only); - diff_free_queue(q); - DIFF_QUEUE_CLEAR(q); + diff_queue_clear(q); return result; } @@ -6730,6 +6740,7 @@ void diff_free(struct diff_options *options) FREE_AND_NULL(options->objfind); } + FREE_AND_NULL(options->orderfile); for (size_t i = 0; i < options->anchors_nr; i++) free(options->anchors[i]); FREE_AND_NULL(options->anchors); @@ -6832,8 +6843,7 @@ void diff_flush(struct diff_options *options) } free_queue: - diff_free_queue(q); - DIFF_QUEUE_CLEAR(q); + diff_queue_clear(q); diff_free(options); /* @@ -6864,9 +6874,7 @@ static void diffcore_apply_filter(struct diff_options *options) { int i; struct diff_queue_struct *q = &diff_queued_diff; - struct diff_queue_struct outq; - - DIFF_QUEUE_CLEAR(&outq); + struct diff_queue_struct outq = DIFF_QUEUE_INIT; if (!options->filter) return; @@ -6959,8 +6967,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt) { int i; struct diff_queue_struct *q = &diff_queued_diff; - struct diff_queue_struct outq; - DIFF_QUEUE_CLEAR(&outq); + struct diff_queue_struct outq = DIFF_QUEUE_INIT; for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; @@ -7383,6 +7390,6 @@ void setup_diff_pager(struct diff_options *opt) * --exit-code" in hooks and other scripts, we do not do so. */ if (!opt->flags.exit_with_status && - check_pager_config("diff") != 0) - setup_pager(); + check_pager_config(the_repository, "diff") != 0) + setup_pager(the_repository); } diff --git a/diff.h b/diff.h index fb40c6e6d60eb0..ff0348e4a9a022 100644 --- a/diff.h +++ b/diff.h @@ -94,7 +94,7 @@ typedef void (*add_remove_fn_t)(struct diff_options *options, typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, struct diff_options *options, void *data); -typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data); +typedef const char *(*diff_prefix_fn_t)(struct diff_options *opt, void *data); #define DIFF_FORMAT_RAW 0x0001 #define DIFF_FORMAT_DIFFSTAT 0x0002 @@ -205,9 +205,8 @@ static inline void diff_flags_or(struct diff_flags *a, { char *tmp_a = (char *)a; const char *tmp_b = (const char *)b; - int i; - for (i = 0; i < sizeof(struct diff_flags); i++) + for (size_t i = 0; i < sizeof(struct diff_flags); i++) tmp_a[i] |= tmp_b[i]; } @@ -235,7 +234,7 @@ enum diff_submodule_format { * diffcore library with. */ struct diff_options { - const char *orderfile; + char *orderfile; /* * "--rotate-to=<file>" would start showing at <file> and when @@ -274,7 +273,6 @@ struct diff_options { const char *single_follow; const char *a_prefix, *b_prefix; const char *line_prefix; - size_t line_prefix_length; /** * collection of boolean options that affects the operation, but some do @@ -335,7 +333,7 @@ struct diff_options { int xdl_opts; int ignore_driver_algorithm; - /* see Documentation/diff-options.txt */ + /* see Documentation/diff-options.adoc */ char **anchors; size_t anchors_nr, anchors_alloc; @@ -464,7 +462,7 @@ const char *diff_line_prefix(struct diff_options *); extern const char mime_boundary_leader[]; struct combine_diff_path *diff_tree_paths( - struct combine_diff_path *p, const struct object_id *oid, + const struct object_id *oid, const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt); void diff_tree_oid(const struct object_id *old_oid, @@ -482,12 +480,20 @@ struct combine_diff_path { char status; unsigned int mode; struct object_id oid; - struct strbuf path; + /* + * This per-parent path is filled only when doing a combined + * diff with revs.combined_all_paths set, and only if the path + * differs from the post-image (e.g., a rename or copy). + * Otherwise it is left NULL. + */ + char *path; } parent[FLEX_ARRAY]; }; -#define combine_diff_path_size(n, l) \ - st_add4(sizeof(struct combine_diff_path), (l), 1, \ - st_mult(sizeof(struct combine_diff_parent), (n))) +struct combine_diff_path *combine_diff_path_new(const char *path, + size_t path_len, + unsigned int mode, + const struct object_id *oid, + size_t num_parents); void show_combined_diff(struct combine_diff_path *elem, int num_parent, struct rev_info *); @@ -646,7 +652,7 @@ void run_diff_index(struct rev_info *revs, unsigned int option); int do_diff_cache(const struct object_id *, struct diff_options *); int diff_flush_patch_id(struct diff_options *, struct object_id *, int); -void flush_one_hunk(struct object_id *result, git_hash_ctx *ctx); +void flush_one_hunk(struct object_id *result, struct git_hash_ctx *ctx); int diff_result_code(struct rev_info *); diff --git a/diffcore-break.c b/diffcore-break.c index 831b66b5c3e85c..c4c2173f3096bc 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -131,7 +131,7 @@ static int should_break(struct repository *r, void diffcore_break(struct repository *r, int break_score) { struct diff_queue_struct *q = &diff_queued_diff; - struct diff_queue_struct outq; + struct diff_queue_struct outq = DIFF_QUEUE_INIT; /* When the filepair has this much edit (insert and delete), * it is first considered to be a rewrite and broken into a @@ -178,8 +178,6 @@ void diffcore_break(struct repository *r, int break_score) if (!merge_score) merge_score = DEFAULT_MERGE_SCORE; - DIFF_QUEUE_CLEAR(&outq); - for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; int score; @@ -266,8 +264,8 @@ static void merge_broken(struct diff_filepair *p, * in the resulting tree. */ d->one->rename_used++; - diff_free_filespec_data(d->two); - diff_free_filespec_data(c->one); + free_filespec(d->two); + free_filespec(c->one); free(d); free(c); } @@ -275,11 +273,9 @@ static void merge_broken(struct diff_filepair *p, void diffcore_merge_broken(void) { struct diff_queue_struct *q = &diff_queued_diff; - struct diff_queue_struct outq; + struct diff_queue_struct outq = DIFF_QUEUE_INIT; int i, j; - DIFF_QUEUE_CLEAR(&outq); - for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; if (!p) diff --git a/diffcore-order.c b/diffcore-order.c index e7d20ebd2d1b45..f91ef2247145a6 100644 --- a/diffcore-order.c +++ b/diffcore-order.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2005 Junio C Hamano */ + #include "git-compat-util.h" #include "gettext.h" #include "diff.h" @@ -14,8 +15,7 @@ static void prepare_order(const char *orderfile) { int cnt, pass; struct strbuf sb = STRBUF_INIT; - void *map; - char *cp, *endp; + const char *cp, *endp; ssize_t sz; if (order) @@ -24,14 +24,13 @@ static void prepare_order(const char *orderfile) sz = strbuf_read_file(&sb, orderfile, 0); if (sz < 0) die_errno(_("failed to read orderfile '%s'"), orderfile); - map = strbuf_detach(&sb, NULL); - endp = (char *) map + sz; + endp = sb.buf + sz; for (pass = 0; pass < 2; pass++) { cnt = 0; - cp = map; + cp = sb.buf; while (cp < endp) { - char *ep; + const char *ep; for (ep = cp; ep < endp && *ep != '\n'; ep++) ; /* cp to ep has one line */ @@ -40,12 +39,7 @@ static void prepare_order(const char *orderfile) else if (pass == 0) cnt++; else { - if (*ep == '\n') { - *ep = 0; - order[cnt] = cp; - } else { - order[cnt] = xmemdupz(cp, ep - cp); - } + order[cnt] = xmemdupz(cp, ep - cp); cnt++; } if (ep < endp) @@ -57,6 +51,8 @@ static void prepare_order(const char *orderfile) ALLOC_ARRAY(order, cnt); } } + + strbuf_release(&sb); } static int match_order(const char *path) diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c index b195fa4eb3c045..a52d569911c48e 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -2,6 +2,9 @@ * Copyright (C) 2005 Junio C Hamano * Copyright (C) 2010 Google Inc. */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "diff.h" #include "diffcore.h" @@ -182,9 +185,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o, regex_t *regexp, kwset_t kws, pickaxe_fn fn) { int i; - struct diff_queue_struct outq; - - DIFF_QUEUE_CLEAR(&outq); + struct diff_queue_struct outq = DIFF_QUEUE_INIT; if (o->pickaxe_opts & DIFF_PICKAXE_ALL) { /* Showing the whole changeset if needle exists */ diff --git a/diffcore-rename.c b/diffcore-rename.c index 3d6826baa3a30e..91b77993c7827f 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -688,7 +688,6 @@ static void cleanup_dir_rename_info(struct dir_rename_info *info, struct hashmap_iter iter; struct strmap_entry *entry; struct string_list to_remove = STRING_LIST_INIT_NODUP; - int i; if (!info->setup) return; @@ -734,7 +733,7 @@ static void cleanup_dir_rename_info(struct dir_rename_info *info, if (strintmap_contains(counts, UNKNOWN_DIR)) strintmap_remove(counts, UNKNOWN_DIR); } - for (i = 0; i < to_remove.nr; ++i) + for (size_t i = 0; i < to_remove.nr; ++i) strmap_remove(info->dir_rename_count, to_remove.items[i].string, 1); string_list_clear(&to_remove, 0); @@ -1388,7 +1387,7 @@ void diffcore_rename_extended(struct diff_options *options, int detect_rename = options->detect_rename; int minimum_score = options->rename_score; struct diff_queue_struct *q = &diff_queued_diff; - struct diff_queue_struct outq; + struct diff_queue_struct outq = DIFF_QUEUE_INIT; struct diff_score *mx; int i, j, rename_count, skip_unmodified = 0; int num_destinations, dst_cnt; @@ -1568,6 +1567,7 @@ void diffcore_rename_extended(struct diff_options *options, trace2_region_enter("diff", "inexact renames", options->repo); if (options->show_rename_progress) { progress = start_delayed_progress( + the_repository, _("Performing inexact rename detection"), (uint64_t)num_destinations * (uint64_t)num_sources); } @@ -1638,7 +1638,6 @@ void diffcore_rename_extended(struct diff_options *options, * are recorded in rename_dst. The original list is still in *q. */ trace2_region_enter("diff", "write back to queue", options->repo); - DIFF_QUEUE_CLEAR(&outq); for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; struct diff_filepair *pair_to_free = NULL; diff --git a/diffcore-rotate.c b/diffcore-rotate.c index 533986cf632d42..67b591261adcc6 100644 --- a/diffcore-rotate.c +++ b/diffcore-rotate.c @@ -2,6 +2,7 @@ * Copyright (C) 2021, Google LLC. * Based on diffcore-order.c, which is Copyright (C) 2005, Junio C Hamano */ + #include "git-compat-util.h" #include "gettext.h" #include "diff.h" @@ -10,7 +11,7 @@ void diffcore_rotate(struct diff_options *opt) { struct diff_queue_struct *q = &diff_queued_diff; - struct diff_queue_struct outq; + struct diff_queue_struct outq = DIFF_QUEUE_INIT; int rotate_to, i; if (!q->nr) @@ -31,7 +32,6 @@ void diffcore_rotate(struct diff_options *opt) return; } - DIFF_QUEUE_CLEAR(&outq); rotate_to = i; for (i = rotate_to; i < q->nr; i++) diff --git a/diffcore.h b/diffcore.h index 1701ed50b9c823..9c0a0e7aaff85a 100644 --- a/diffcore.h +++ b/diffcore.h @@ -107,7 +107,7 @@ struct diff_filepair { struct diff_filespec *one; struct diff_filespec *two; unsigned short int score; - char status; /* M C R A D U etc. (see Documentation/diff-format.txt or DIFF_STATUS_* in diff.h) */ + char status; /* M C R A D U etc. (see Documentation/diff-format.adoc or DIFF_STATUS_* in diff.h) */ unsigned broken_pair : 1; unsigned renamed_pair : 1; unsigned is_unmerged : 1; @@ -153,18 +153,16 @@ struct diff_queue_struct { int nr; }; -#define DIFF_QUEUE_CLEAR(q) \ - do { \ - (q)->queue = NULL; \ - (q)->nr = (q)->alloc = 0; \ - } while (0) +#define DIFF_QUEUE_INIT { 0 } + +void diff_queue_init(struct diff_queue_struct *q); +void diff_queue_clear(struct diff_queue_struct *q); extern struct diff_queue_struct diff_queued_diff; struct diff_filepair *diff_queue(struct diff_queue_struct *, struct diff_filespec *, struct diff_filespec *); void diff_q(struct diff_queue_struct *, struct diff_filepair *); -void diff_free_queue(struct diff_queue_struct *q); /* dir_rename_relevance: the reason we want rename information for a dir */ enum dir_rename_relevance { diff --git a/dir.c b/dir.c index c43b5e30813a8f..cbd82be6c91637 100644 --- a/dir.c +++ b/dir.c @@ -7,6 +7,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -1056,6 +1057,8 @@ static void do_invalidate_gitignore(struct untracked_cache_dir *dir) { int i; dir->valid = 0; + for (size_t i = 0; i < dir->untracked_nr; i++) + free(dir->untracked[i]); dir->untracked_nr = 0; for (i = 0; i < dir->dirs_nr; i++) do_invalidate_gitignore(dir->dirs[i]); @@ -1083,15 +1086,13 @@ static void invalidate_directory(struct untracked_cache *uc, uc->dir_invalidated++; dir->valid = 0; + for (size_t i = 0; i < dir->untracked_nr; i++) + free(dir->untracked[i]); dir->untracked_nr = 0; for (i = 0; i < dir->dirs_nr; i++) dir->dirs[i]->recurse = 0; } -static int add_patterns_from_buffer(char *buf, size_t size, - const char *base, int baselen, - struct pattern_list *pl); - /* Flags for add_patterns() */ #define PATTERN_NOFOLLOW (1<<0) @@ -1181,9 +1182,9 @@ static int add_patterns(const char *fname, const char *base, int baselen, return 0; } -static int add_patterns_from_buffer(char *buf, size_t size, - const char *base, int baselen, - struct pattern_list *pl) +int add_patterns_from_buffer(char *buf, size_t size, + const char *base, int baselen, + struct pattern_list *pl) { char *orig = buf; int i, lineno = 1; @@ -2136,8 +2137,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir, */ state = path_none; } else { - int i; - for (i = old_ignored_nr + 1; i<dir->ignored_nr; ++i) + for (int i = old_ignored_nr; i < dir->ignored_nr; i++) FREE_AND_NULL(dir->ignored[i]); dir->ignored_nr = old_ignored_nr; } @@ -2149,8 +2149,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir, */ if ((dir->flags & DIR_SHOW_IGNORED_TOO) && !(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) { - int i; - for (i = old_untracked_nr + 1; i<dir->nr; ++i) + for (int i = old_untracked_nr; i < dir->nr; i++) FREE_AND_NULL(dir->entries[i]); dir->nr = old_untracked_nr; } @@ -2870,14 +2869,14 @@ static void set_untracked_ident(struct untracked_cache *uc) static unsigned new_untracked_cache_flags(struct index_state *istate) { struct repository *repo = istate->repo; - char *val; + const char *val; /* * This logic is coordinated with the setting of these flags in * wt-status.c#wt_status_collect_untracked(), and the evaluation * of the config setting in commit.c#git_status_config() */ - if (!repo_config_get_string(repo, "status.showuntrackedfiles", &val) && + if (!repo_config_get_string_tmp(repo, "status.showuntrackedfiles", &val) && !strcmp(val, "all")) return 0; @@ -3452,7 +3451,7 @@ void setup_standard_excludes(struct dir_struct *dir) char *get_sparse_checkout_filename(void) { - return git_pathdup("info/sparse-checkout"); + return repo_git_path(the_repository, "info/sparse-checkout"); } int get_sparse_checkout_patterns(struct pattern_list *pl) @@ -3575,6 +3574,8 @@ static void write_one_dir(struct untracked_cache_dir *untracked, * for safety.. */ if (!untracked->valid) { + for (size_t i = 0; i < untracked->untracked_nr; i++) + free(untracked->untracked[i]); untracked->untracked_nr = 0; untracked->check_only = 0; } @@ -3907,6 +3908,8 @@ static void invalidate_one_directory(struct untracked_cache *uc, { uc->dir_invalidated++; ucd->valid = 0; + for (size_t i = 0; i < ucd->untracked_nr; i++) + free(ucd->untracked[i]); ucd->untracked_nr = 0; } diff --git a/dir.h b/dir.h index a3a2f00f5d9273..6cfef5df66091b 100644 --- a/dir.h +++ b/dir.h @@ -467,6 +467,9 @@ void add_patterns_from_file(struct dir_struct *, const char *fname); int add_patterns_from_blob_to_list(struct object_id *oid, const char *base, int baselen, struct pattern_list *pl); +int add_patterns_from_buffer(char *buf, size_t size, + const char *base, int baselen, + struct pattern_list *pl); void parse_path_pattern(const char **string, int *patternlen, unsigned *flags, int *nowildcardlen); void add_pattern(const char *string, const char *base, int baselen, struct pattern_list *pl, int srcpos); diff --git a/editor.c b/editor.c index 6b9ce81d5fc0fd..b79d97b0e721c2 100644 --- a/editor.c +++ b/editor.c @@ -142,10 +142,8 @@ int strbuf_edit_interactively(struct repository *r, struct strbuf sb = STRBUF_INIT; int fd, res = 0; - if (!is_absolute_path(path)) { - strbuf_repo_git_path(&sb, r, "%s", path); - path = sb.buf; - } + if (!is_absolute_path(path)) + path = repo_git_path_append(r, &sb, "%s", path); fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) diff --git a/entry.c b/entry.c index 3143b9996bf491..81b321e53d1b96 100644 --- a/entry.c +++ b/entry.c @@ -188,7 +188,9 @@ int finish_delayed_checkout(struct checkout *state, int show_progress) dco->state = CE_RETRY; if (show_progress) - progress = start_delayed_progress(_("Filtering content"), dco->paths.nr); + progress = start_delayed_progress(the_repository, + _("Filtering content"), + dco->paths.nr); while (dco->filters.nr > 0) { for_each_string_list_item(filter, &dco->filters) { struct string_list available_paths = STRING_LIST_INIT_DUP; @@ -441,7 +443,7 @@ static int check_path(const char *path, int len, struct stat *st, int skiplen) static void mark_colliding_entries(const struct checkout *state, struct cache_entry *ce, struct stat *st) { - int i, trust_ino = check_stat; + int trust_ino = check_stat; #if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__) trust_ino = 0; @@ -451,7 +453,7 @@ static void mark_colliding_entries(const struct checkout *state, /* TODO: audit for interaction with sparse-index. */ ensure_full_index(state->istate); - for (i = 0; i < state->istate->cache_nr; i++) { + for (size_t i = 0; i < state->istate->cache_nr; i++) { struct cache_entry *dup = state->istate->cache[i]; if (dup == ce) { diff --git a/environment.c b/environment.c index a2ce998081864d..9e4c7781be049a 100644 --- a/environment.c +++ b/environment.c @@ -16,6 +16,7 @@ #include "convert.h" #include "environment.h" #include "gettext.h" +#include "git-zlib.h" #include "repository.h" #include "config.h" #include "refs.h" @@ -42,16 +43,12 @@ char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; char *git_attributes_file; -char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int pack_compression_level = Z_DEFAULT_COMPRESSION; int fsync_object_files = -1; int use_fsync = -1; enum fsync_method fsync_method = FSYNC_METHOD_DEFAULT; enum fsync_component fsync_components = FSYNC_COMPONENTS_DEFAULT; -size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE; -size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT; -size_t delta_base_cache_limit = 96 * 1024 * 1024; unsigned long big_file_threshold = 512 * 1024 * 1024; char *editor_program; char *askpass_program; @@ -210,32 +207,6 @@ const char *get_commit_output_encoding(void) return git_commit_encoding ? git_commit_encoding : "UTF-8"; } -static int the_shared_repository = PERM_UMASK; -static int need_shared_repository_from_config = 1; - -void set_shared_repository(int value) -{ - the_shared_repository = value; - need_shared_repository_from_config = 0; -} - -int get_shared_repository(void) -{ - if (need_shared_repository_from_config) { - const char *var = "core.sharedrepository"; - const char *value; - if (!git_config_get_value(var, &value)) - the_shared_repository = git_config_perm(var, value); - need_shared_repository_from_config = 0; - } - return the_shared_repository; -} - -void reset_shared_repository(void) -{ - need_shared_repository_from_config = 1; -} - int use_optional_locks(void) { return git_env_bool(GIT_OPTIONAL_LOCKS_ENVIRONMENT, 1); diff --git a/environment.h b/environment.h index 923e12661e19e4..45e690f203fd1d 100644 --- a/environment.h +++ b/environment.h @@ -134,16 +134,6 @@ void setup_git_env(const char *git_dir); */ int have_git_dir(void); -/* - * Accessors for the core.sharedrepository config which lazy-load the value - * from the config (if not already set). The "reset" function can be - * used to unset "set" or cached value, meaning that the value will be loaded - * fresh from the config file on the next call to get_shared_repository(). - */ -void set_shared_repository(int value); -int get_shared_repository(void); -void reset_shared_repository(void); - extern int is_bare_repository_cfg; int is_bare_repository(void); extern char *git_work_tree_cfg; @@ -160,12 +150,10 @@ extern int warn_on_object_refname_ambiguity; extern char *apply_default_whitespace; extern char *apply_default_ignorewhitespace; extern char *git_attributes_file; -extern char *git_hooks_path; extern int zlib_compression_level; extern int pack_compression_level; extern size_t packed_git_window_size; extern size_t packed_git_limit; -extern size_t delta_base_cache_limit; extern unsigned long big_file_threshold; extern unsigned long pack_size_limit_cfg; extern int max_allowed_tree_depth; diff --git a/ewah/ewah_bitmap.c b/ewah/ewah_bitmap.c index 8785cbc54a821c..67f8f588e05624 100644 --- a/ewah/ewah_bitmap.c +++ b/ewah/ewah_bitmap.c @@ -16,6 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ + #include "git-compat-util.h" #include "ewok.h" #include "ewok_rlw.h" @@ -255,10 +256,8 @@ void ewah_each_bit(struct ewah_bitmap *self, void (*callback)(size_t, void*), vo ++pointer; for (k = 0; k < rlw_get_literal_words(word); ++k) { - int c; - /* todo: zero count optimization */ - for (c = 0; c < BITS_IN_EWORD; ++c, ++pos) { + for (size_t c = 0; c < BITS_IN_EWORD; ++c, ++pos) { if ((self->buffer[pointer] & ((eword_t)1 << c)) != 0) callback(pos, payload); } diff --git a/ewah/ewah_io.c b/ewah/ewah_io.c index 9035ee65ea8db6..da005523b0531c 100644 --- a/ewah/ewah_io.c +++ b/ewah/ewah_io.c @@ -16,6 +16,9 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "ewok.h" #include "strbuf.h" diff --git a/ewah/ewah_rlw.c b/ewah/ewah_rlw.c index 5093d43e2f00e2..76b4c6c19eda35 100644 --- a/ewah/ewah_rlw.c +++ b/ewah/ewah_rlw.c @@ -16,6 +16,9 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "ewok.h" #include "ewok_rlw.h" diff --git a/fetch-pack.c b/fetch-pack.c index f752da93a80b25..1ed5e11dd56857 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "repository.h" @@ -122,29 +123,41 @@ static void for_each_cached_alternate(struct fetch_negotiator *negotiator, cb(negotiator, cache.items[i]); } -static struct commit *deref_without_lazy_fetch_extended(const struct object_id *oid, - int mark_tags_complete, - enum object_type *type, - unsigned int oi_flags) +static void die_in_commit_graph_only(const struct object_id *oid) { - struct object_info info = { .typep = type }; + die(_("You are attempting to fetch %s, which is in the commit graph file but not in the object database.\n" + "This is probably due to repo corruption.\n" + "If you are attempting to repair this repo corruption by refetching the missing object, use 'git fetch --refetch' with the missing object."), + oid_to_hex(oid)); +} + +static struct commit *deref_without_lazy_fetch(const struct object_id *oid, + int mark_tags_complete_and_check_obj_db) +{ + enum object_type type; + struct object_info info = { .typep = &type }; struct commit *commit; commit = lookup_commit_in_graph(the_repository, oid); - if (commit) + if (commit) { + if (mark_tags_complete_and_check_obj_db) { + if (!has_object(the_repository, oid, 0)) + die_in_commit_graph_only(oid); + } return commit; + } while (1) { if (oid_object_info_extended(the_repository, oid, &info, - oi_flags)) + OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK)) return NULL; - if (*type == OBJ_TAG) { + if (type == OBJ_TAG) { struct tag *tag = (struct tag *) parse_object(the_repository, oid); if (!tag->tagged) return NULL; - if (mark_tags_complete) + if (mark_tags_complete_and_check_obj_db) tag->object.flags |= COMPLETE; oid = &tag->tagged->oid; } else { @@ -152,7 +165,7 @@ static struct commit *deref_without_lazy_fetch_extended(const struct object_id * } } - if (*type == OBJ_COMMIT) { + if (type == OBJ_COMMIT) { struct commit *commit = lookup_commit(the_repository, oid); if (!commit || repo_parse_commit(the_repository, commit)) return NULL; @@ -162,16 +175,6 @@ static struct commit *deref_without_lazy_fetch_extended(const struct object_id * return NULL; } - -static struct commit *deref_without_lazy_fetch(const struct object_id *oid, - int mark_tags_complete) -{ - enum object_type type; - unsigned flags = OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK; - return deref_without_lazy_fetch_extended(oid, mark_tags_complete, - &type, flags); -} - static int rev_list_insert_ref(struct fetch_negotiator *negotiator, const struct object_id *oid) { @@ -1033,7 +1036,9 @@ static int get_pack(struct fetch_pack_args *args, die(_("fetch-pack: unable to fork off %s"), cmd_name); if (do_keep && (pack_lockfiles || fsck_objects)) { int is_well_formed; - char *pack_lockfile = index_pack_lockfile(cmd.out, &is_well_formed); + char *pack_lockfile = index_pack_lockfile(the_repository, + cmd.out, + &is_well_formed); if (!is_well_formed) die(_("fetch-pack: invalid index-pack output")); @@ -1855,8 +1860,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, return ref; } -static int fetch_pack_config_cb(const char *var, const char *value, - const struct config_context *ctx, void *cb) +int fetch_pack_fsck_config(const char *var, const char *value, + struct strbuf *msg_types) { const char *msg_id; @@ -1864,9 +1869,9 @@ static int fetch_pack_config_cb(const char *var, const char *value, char *path ; if (git_config_pathname(&path, var, value)) - return 1; - strbuf_addf(&fsck_msg_types, "%cskiplist=%s", - fsck_msg_types.len ? ',' : '=', path); + return -1; + strbuf_addf(msg_types, "%cskiplist=%s", + msg_types->len ? ',' : '=', path); free(path); return 0; } @@ -1875,14 +1880,24 @@ static int fetch_pack_config_cb(const char *var, const char *value, 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 ? ',' : '=', msg_id, value); + strbuf_addf(msg_types, "%c%s=%s", + msg_types->len ? ',' : '=', msg_id, value); else warning("Skipping unknown msg id '%s'", msg_id); return 0; } - return git_default_config(var, value, ctx, cb); + return 1; +} + +static int fetch_pack_config_cb(const char *var, const char *value, + const struct config_context *ctx, void *cb) +{ + int ret = fetch_pack_fsck_config(var, value, &fsck_msg_types); + if (ret > 0) + return git_default_config(var, value, ctx, cb); + + return ret; } static void fetch_pack_config(void) diff --git a/fetch-pack.h b/fetch-pack.h index b5c579cdae2508..9d3470366f85ec 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -106,4 +106,15 @@ int report_unmatched_refs(struct ref **sought, int nr_sought); */ int fetch_pack_fsck_objects(void); +/* + * Check if the provided config variable pertains to fetch fsck and if so append + * the configuration to the provided strbuf. + * + * When a fetch fsck config option is successfully processed the function + * returns 0. If the provided config option is unrelated to fetch fsck, 1 is + * returned. Errors return -1. + */ +int fetch_pack_fsck_config(const char *var, const char *value, + struct strbuf *msg_types); + #endif diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c index 6acb37b48020c1..5b63c3b088a17a 100644 --- a/fmt-merge-msg.c +++ b/fmt-merge-msg.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" diff --git a/fsck.c b/fsck.c index 3756f52459e771..9fc4c25ffd59ba 100644 --- a/fsck.c +++ b/fsck.c @@ -1295,7 +1295,7 @@ static int fsck_blobs(struct oidset *blobs_found, struct oidset *blobs_done, buf = repo_read_object_file(the_repository, oid, &type, &size); if (!buf) { - if (is_promisor_object(oid)) + if (is_promisor_object(the_repository, oid)) continue; ret |= report(options, oid, OBJ_BLOB, msg_missing, @@ -1353,7 +1353,7 @@ int git_fsck_config(const char *var, const char *value, struct strbuf sb = STRBUF_INIT; if (git_config_pathname(&path, var, value)) - return 1; + return -1; strbuf_addf(&sb, "skiplist=%s", path); free(path); fsck_set_msg_types(options, sb.buf); diff --git a/fsck.h b/fsck.h index 500b4c04d2cbf2..a95ae7eb847c49 100644 --- a/fsck.h +++ b/fsck.h @@ -15,7 +15,7 @@ enum fsck_msg_type { }; /* - * Documentation/fsck-msgids.txt documents these; when + * Documentation/fsck-msgids.adoc documents these; when * modifying this list in any way, make sure to keep the * two in sync. */ @@ -31,8 +31,10 @@ enum fsck_msg_type { FUNC(BAD_NAME, ERROR) \ FUNC(BAD_OBJECT_SHA1, ERROR) \ FUNC(BAD_PARENT_SHA1, ERROR) \ + FUNC(BAD_REF_CONTENT, ERROR) \ FUNC(BAD_REF_FILETYPE, ERROR) \ FUNC(BAD_REF_NAME, ERROR) \ + FUNC(BAD_REFERENT_NAME, ERROR) \ FUNC(BAD_TIMEZONE, ERROR) \ FUNC(BAD_TREE, ERROR) \ FUNC(BAD_TREE_SHA1, ERROR) \ @@ -84,6 +86,10 @@ enum fsck_msg_type { FUNC(MAILMAP_SYMLINK, INFO) \ FUNC(BAD_TAG_NAME, INFO) \ FUNC(MISSING_TAGGER_ENTRY, INFO) \ + FUNC(SYMLINK_REF, INFO) \ + FUNC(REF_MISSING_NEWLINE, INFO) \ + FUNC(SYMREF_TARGET_IS_NOT_A_REF, INFO) \ + FUNC(TRAILING_REF_CONTENT, INFO) \ /* ignored (elevated when requested) */ \ FUNC(EXTRA_HEADER_ENTRY, IGNORE) diff --git a/fsmonitor.c b/fsmonitor.c index 237ca59d004582..98b2b476f08684 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -247,7 +248,7 @@ static size_t handle_using_name_hash_icase( * technically this is a tracked file or a sparse-directory. * It should not have any entries in the untracked-cache, so * we should not need to use the case-corrected spelling to - * invalidate the the untracked-cache. So we may not need to + * invalidate the untracked-cache. So we may not need to * do this. For now, I'm going to be conservative and always * do it; we can revisit this later. */ diff --git a/generate-cmdlist.sh b/generate-cmdlist.sh index 205541e0f7f81b..0ed39c4c5dabcd 100755 --- a/generate-cmdlist.sh +++ b/generate-cmdlist.sh @@ -64,7 +64,7 @@ define_category_names () { print_command_list () { echo "static struct cmdname_help command_list[] = {" - echo "$1" | + echo "$2" | while read cmd rest do synopsis= @@ -76,7 +76,7 @@ print_command_list () { break ;; esac - done <"Documentation/$cmd.txt" + done <"$1/Documentation/$cmd.adoc" printf '\t{ "%s", N_("%s"), 0' "$cmd" "$synopsis" printf " | CAT_%s" $rest @@ -93,18 +93,28 @@ do shift done -commands="$(command_list "$1")" -categories="$(category_list "$commands")" +if test "$#" -ne 2 +then + die "USAGE: $0 <SOURCE_DIR> <OUTPUT>" +fi + +SOURCE_DIR="$1" +OUTPUT="$2" + +{ + commands="$(command_list "$SOURCE_DIR"/command-list.txt)" + categories="$(category_list "$commands")" -echo "/* Automatically generated by generate-cmdlist.sh */ -struct cmdname_help { - const char *name; - const char *help; - uint32_t category; -}; -" -define_categories "$categories" -echo -define_category_names "$categories" -echo -print_command_list "$commands" + echo "/* Automatically generated by generate-cmdlist.sh */ + struct cmdname_help { + const char *name; + const char *help; + uint32_t category; + }; + " + define_categories "$categories" + echo + define_category_names "$categories" + echo + print_command_list "$SOURCE_DIR" "$commands" +} >"$OUTPUT" diff --git a/generate-configlist.sh b/generate-configlist.sh index 8692fe5cf4d5e4..dffdaada8b5b39 100755 --- a/generate-configlist.sh +++ b/generate-configlist.sh @@ -1,13 +1,19 @@ #!/bin/sh -echo "/* Automatically generated by generate-configlist.sh */" -echo +SOURCE_DIR="$1" +OUTPUT="$2" + +if test -z "$SOURCE_DIR" || ! test -d "$SOURCE_DIR" || test -z "$OUTPUT" +then + echo >&2 "USAGE: $0 <SOURCE_DIR> <OUTPUT>" + exit 1 +fi print_config_list () { cat <<EOF static const char *config_name_list[] = { EOF - grep -h '^[a-zA-Z].*\..*::$' Documentation/*config.txt Documentation/config/*.txt | + grep -h '^[a-zA-Z].*\..*::$' "$SOURCE_DIR"/Documentation/*config.adoc "$SOURCE_DIR"/Documentation/config/*.adoc | sed '/deprecated/d; s/::$//; s/, */\n/g' | sort | sed 's/^.*$/ "&",/' @@ -17,5 +23,9 @@ EOF EOF } -echo -print_config_list +{ + echo "/* Automatically generated by generate-configlist.sh */" + echo + echo + print_config_list +} >"$OUTPUT" diff --git a/generate-hooklist.sh b/generate-hooklist.sh index 2f9f54eb545be2..e0cdf2694476ce 100755 --- a/generate-hooklist.sh +++ b/generate-hooklist.sh @@ -2,6 +2,17 @@ # # Usage: ./generate-hooklist.sh >hook-list.h +SOURCE_DIR="$1" +OUTPUT="$2" + +if test -z "$SOURCE_DIR" || ! test -d "$SOURCE_DIR" || test -z "$OUTPUT" +then + echo >&2 "USAGE: $0 <SOURCE_DIR> <OUTPUT>" + exit 1 +fi + +{ + cat <<EOF /* Automatically generated by generate-hooklist.sh */ @@ -11,10 +22,12 @@ EOF sed -n \ -e '/^~~~~*$/ {x; s/^.*$/ "&",/; p;}' \ -e 'x' \ - <Documentation/githooks.txt | + <"$SOURCE_DIR"/Documentation/githooks.adoc | LC_ALL=C sort cat <<EOF NULL, }; EOF + +} >"$OUTPUT" diff --git a/generate-perl.sh b/generate-perl.sh new file mode 100755 index 00000000000000..65f122ebfc76dc --- /dev/null +++ b/generate-perl.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +set -e + +if test $# -ne 5 +then + echo >&2 "USAGE: $0 <GIT_BUILD_OPTIONS> <GIT_VERSION_FILE> <PERL_HEADER> <INPUT> <OUTPUT>" + exit 1 +fi + +GIT_BUILD_OPTIONS="$1" +GIT_VERSION_FILE="$2" +PERL_HEADER="$3" +INPUT="$4" +OUTPUT="$5" + +. "$GIT_BUILD_OPTIONS" +. "$GIT_VERSION_FILE" + +sed -e '1{' \ + -e " /^#!.*perl/!b" \ + -e " s|#!.*perl|#!$PERL_PATH|" \ + -e " r $PERL_HEADER" \ + -e ' G' \ + -e '}' \ + -e "s|@GIT_VERSION@|$GIT_VERSION|g" \ + -e "s|@LOCALEDIR@|$PERL_LOCALEDIR|g" \ + -e "s|@NO_GETTEXT@|$NO_GETTEXT|g" \ + -e "s|@NO_PERL_CPAN_FALLBACKS@|$NO_PERL_CPAN_FALLBACKS|g" \ + "$INPUT" >"$OUTPUT" + +case "$INPUT" in +*.perl) + chmod a+x "$OUTPUT";; +*) + ;; +esac diff --git a/generate-python.sh b/generate-python.sh new file mode 100755 index 00000000000000..31ac115689d9cb --- /dev/null +++ b/generate-python.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +set -e + +if test $# -ne 3 +then + echo >&2 "USAGE: $0 <GIT_BUILD_OPTIONS> <INPUT> <OUTPUT>" + exit 1 +fi + +GIT_BUILD_OPTIONS="$1" +INPUT="$2" +OUTPUT="$3" + +. "$GIT_BUILD_OPTIONS" + +sed -e "1s|#!.*python|#!$PYTHON_PATH|" \ + "$INPUT" >"$OUTPUT+" +chmod a+x "$OUTPUT+" +mv "$OUTPUT+" "$OUTPUT" diff --git a/generate-script.sh b/generate-script.sh new file mode 100755 index 00000000000000..a149e4f0ba348e --- /dev/null +++ b/generate-script.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +set -e + +if test $# -ne 3 +then + echo >&2 "USAGE: $0 <INPUT> <OUTPUT> <GIT-BUILD-OPTIONS>" + exit 1 +fi + +INPUT="$1" +OUTPUT="$2" +BUILD_OPTIONS="$3" + +. "$BUILD_OPTIONS" + +sed -e "1s|#!.*/sh|#!$SHELL_PATH|" \ + -e "s|@SHELL_PATH@|$SHELL_PATH|" \ + -e "s|@DIFF@|$DIFF|" \ + -e "s|@LOCALEDIR@|$LOCALEDIR|g" \ + -e "s/@USE_GETTEXT_SCHEME@/$USE_GETTEXT_SCHEME/g" \ + -e "$BROKEN_PATH_FIX" \ + -e "s|@GITWEBDIR@|$GITWEBDIR|g" \ + -e "s|@PERL_PATH@|$PERL_PATH|g" \ + -e "s|@PAGER_ENV@|$PAGER_ENV|g" \ + "$INPUT" >"$OUTPUT" + +case "$(basename "$INPUT")" in +git-mergetool--lib.sh|git-sh-i18n.sh|git-sh-setup.sh) + ;; +*) + chmod a+x "$OUTPUT" + ;; +esac diff --git a/gettext.c b/gettext.c index 57facbc21ec254..8d08a61f8487dc 100644 --- a/gettext.c +++ b/gettext.c @@ -2,6 +2,8 @@ * Copyright (c) 2010 Ævar Arnfjörð Bjarmason */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "abspath.h" #include "environment.h" diff --git a/git-archimport.perl b/git-archimport.perl index f5a317b89961ce..6d0169cb6af0de 100755 --- a/git-archimport.perl +++ b/git-archimport.perl @@ -54,7 +54,7 @@ =head1 Devel Notes =cut -use 5.008001; +require v5.26; use strict; use warnings; use Getopt::Std; diff --git a/git-compat-util.h b/git-compat-util.h index e4a306dd5639b5..e123288e8f1393 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -44,6 +44,16 @@ struct strbuf; #define GIT_GNUC_PREREQ(maj, min) 0 #endif +#if defined(__GNUC__) || defined(__clang__) +# define PRAGMA(pragma) _Pragma(#pragma) +# define DISABLE_WARNING(warning) PRAGMA(GCC diagnostic ignored #warning) +#else +# define DISABLE_WARNING(warning) +#endif + +#ifdef DISABLE_SIGN_COMPARE_WARNINGS +DISABLE_WARNING(-Wsign-compare) +#endif #ifndef FLEX_ARRAY /* @@ -691,6 +701,8 @@ int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); +void show_usage_if_asked(int ac, const char **av, const char *err); + #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO #include "compat/apple-common-crypto.h" @@ -1527,38 +1539,6 @@ int cmd_main(int, const char **); int common_exit(const char *file, int line, int code); #define exit(code) exit(common_exit(__FILE__, __LINE__, (code))) -/* - * You can mark a stack variable with UNLEAK(var) to avoid it being - * reported as a leak by tools like LSAN or valgrind. The argument - * should generally be the variable itself (not its address and not what - * it points to). It's safe to use this on pointers which may already - * have been freed, or on pointers which may still be in use. - * - * Use this _only_ for a variable that leaks by going out of scope at - * program exit (so only from cmd_* functions or their direct helpers). - * Normal functions, especially those which may be called multiple - * times, should actually free their memory. This is only meant as - * an annotation, and does nothing in non-leak-checking builds. - */ -#ifdef SUPPRESS_ANNOTATED_LEAKS -void unleak_memory(const void *ptr, size_t len); -#define UNLEAK(var) unleak_memory(&(var), sizeof(var)) -#else -#define UNLEAK(var) do {} while (0) -#endif - -#define z_const -#include <zlib.h> - -#if ZLIB_VERNUM < 0x1290 -/* - * This is uncompress2, which is only available in zlib >= 1.2.9 - * (released as of early 2017). See compat/zlib-uncompress2.c. - */ -int uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong *sourceLen); -#endif - /* * This include must come after system headers, since it introduces macros that * replace system names. diff --git a/git-curl-compat.h b/git-curl-compat.h index e1d0bdd273501f..703756ba851d5b 100644 --- a/git-curl-compat.h +++ b/git-curl-compat.h @@ -28,104 +28,6 @@ * introduced, oldest first, in the official version of cURL library. */ -/** - * CURL_SOCKOPT_OK was added in 7.21.5, released in April 2011. - */ -#if LIBCURL_VERSION_NUM < 0x071505 -#define CURL_SOCKOPT_OK 0 -#endif - -/** - * CURLOPT_TCP_KEEPALIVE was added in 7.25.0, released in March 2012. - */ -#if LIBCURL_VERSION_NUM >= 0x071900 -#define GITCURL_HAVE_CURLOPT_TCP_KEEPALIVE 1 -#endif - - -/** - * CURLOPT_LOGIN_OPTIONS was added in 7.34.0, released in December - * 2013. - * - * If we start requiring 7.34.0 we might also be able to remove the - * code conditional on USE_CURL_FOR_IMAP_SEND in imap-send.c, see - * 1e16b255b95 (git-imap-send: use libcurl for implementation, - * 2014-11-09) and the check it added for "072200" in the Makefile. - - */ -#if LIBCURL_VERSION_NUM >= 0x072200 -#define GIT_CURL_HAVE_CURLOPT_LOGIN_OPTIONS 1 -#endif - -/** - * CURL_SSLVERSION_TLSv1_[012] was added in 7.34.0, released in - * December 2013. - */ -#if LIBCURL_VERSION_NUM >= 0x072200 -#define GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_0 -#endif - -/** - * CURLOPT_PINNEDPUBLICKEY was added in 7.39.0, released in November - * 2014. CURLE_SSL_PINNEDPUBKEYNOTMATCH was added in that same version. - */ -#if LIBCURL_VERSION_NUM >= 0x072c00 -#define GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY 1 -#define GIT_CURL_HAVE_CURLE_SSL_PINNEDPUBKEYNOTMATCH 1 -#endif - -/** - * CURL_HTTP_VERSION_2 was added in 7.43.0, released in June 2015. - * - * The CURL_HTTP_VERSION_2 alias (but not CURL_HTTP_VERSION_2_0) has - * always been a macro, not an enum field (checked on curl version - * 7.78.0) - */ -#if LIBCURL_VERSION_NUM >= 0x072b00 -#define GIT_CURL_HAVE_CURL_HTTP_VERSION_2 1 -#endif - -/** - * CURLSSLOPT_NO_REVOKE was added in 7.44.0, released in August 2015. - * - * The CURLSSLOPT_NO_REVOKE is, has always been a macro, not an enum - * field (checked on curl version 7.78.0) - */ -#if LIBCURL_VERSION_NUM >= 0x072c00 -#define GIT_CURL_HAVE_CURLSSLOPT_NO_REVOKE 1 -#endif - -/** - * CURLOPT_PROXY_CAINFO was added in 7.52.0, released in August 2017. - */ -#if LIBCURL_VERSION_NUM >= 0x073400 -#define GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO 1 -#endif - -/** - * CURLOPT_PROXY_{KEYPASSWD,SSLCERT,SSLKEY} was added in 7.52.0, - * released in August 2017. - */ -#if LIBCURL_VERSION_NUM >= 0x073400 -#define GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD 1 -#endif - -/** - * CURL_SSLVERSION_TLSv1_3 was added in 7.53.0, released in February - * 2017. - */ -#if LIBCURL_VERSION_NUM >= 0x073400 -#define GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_3 1 -#endif - -/** - * CURLSSLSET_{NO_BACKENDS,OK,TOO_LATE,UNKNOWN_BACKEND} were added in - * 7.56.0, released in September 2017. - */ -#if LIBCURL_VERSION_NUM >= 0x073800 -#define GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS -#endif - /** * Versions before curl 7.66.0 (September 2019) required manually setting the * transfer-encoding for a streaming POST; after that this is handled diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 1e03ba94d1b271..edf02f99642910 100755 --- a/git-cvsexportcommit.perl +++ b/git-cvsexportcommit.perl @@ -1,6 +1,6 @@ #!/usr/bin/perl -use 5.008001; +require v5.26; use strict; use warnings; use Getopt::Std; diff --git a/git-cvsimport.perl b/git-cvsimport.perl index 211ec8459a0b84..e10ad5334e513b 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.008001; +require v5.26; use strict; use warnings; use Getopt::Long; diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 124f598bdc0705..a4e1bad33ca2a3 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -15,7 +15,7 @@ #### #### -use 5.008001; +require v5.26; use strict; use warnings; use bytes; @@ -26,7 +26,7 @@ use File::Basename; use Getopt::Long qw(:config require_order no_ignore_case); -my $VERSION = '@@GIT_VERSION@@'; +my $VERSION = '@GIT_VERSION@'; my $log = GITCVS::log->new(); my $cfg; diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index dd0c9a5b7f2b07..d32e47cc09eab0 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -61,9 +61,7 @@ launch_merge_tool () { export BASE eval $GIT_DIFFTOOL_EXTCMD '"$LOCAL"' '"$REMOTE"' else - initialize_merge_tool "$merge_tool" - # ignore the error from the above --- run_merge_tool - # will diagnose unusable tool by itself + initialize_merge_tool "$merge_tool" || exit 1 run_merge_tool "$merge_tool" fi } @@ -87,9 +85,7 @@ if test -n "$GIT_DIFFTOOL_DIRDIFF" then LOCAL="$1" REMOTE="$2" - initialize_merge_tool "$merge_tool" - # ignore the error from the above --- run_merge_tool - # will diagnose unusable tool by itself + initialize_merge_tool "$merge_tool" || exit 1 run_merge_tool "$merge_tool" false status=$? diff --git a/git-gui/Makefile b/git-gui/Makefile index 667c39ed564a55..6c5a12bc320d7d 100644 --- a/git-gui/Makefile +++ b/git-gui/Makefile @@ -1,3 +1,4 @@ +# The default target of this Makefile is... all:: # Define V=1 to have a more verbose compile. diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 8fe7538e72084d..887d6d596c16fc 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -1357,7 +1357,6 @@ set current_diff_path {} set is_3way_diff 0 set is_submodule_diff 0 set is_conflict_diff 0 -set diff_empty_count 0 set last_revert {} set last_revert_enc {} @@ -3594,6 +3593,8 @@ $ui_diff tag configure clr1 -font font_diffbold $ui_diff tag configure clr4 -underline 1 $ui_diff tag conf d_info -foreground blue -font font_diffbold +$ui_diff tag conf d_rescan -foreground blue -underline 1 -font font_diffbold +$ui_diff tag bind d_rescan <Button-1> { clear_diff; rescan ui_ready 0 } $ui_diff tag conf d_cr -elide true $ui_diff tag conf d_@ -font font_diffbold diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 11379f8ad355e2..208dc2817ca68c 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -207,8 +207,17 @@ You must stage at least 1 file before you can commit. # -- A message is required. # - set msg [string trim [$ui_comm get 1.0 end]] + set msg [$ui_comm get 1.0 end] + # Strip trailing whitespace regsub -all -line {[ \t\r]+$} $msg {} msg + # Strip comment lines + regsub -all {(^|\n)#[^\n]*} $msg {\1} msg + # Strip leading empty lines + regsub {^\n*} $msg {} msg + # Compress consecutive empty lines + regsub -all {\n{3,}} $msg "\n\n" msg + # Strip trailing empty line + regsub {\n\n$} $msg "\n" msg if {$msg eq {}} { error_popup [mc "Please supply a commit message. diff --git a/git-gui/lib/console.tcl b/git-gui/lib/console.tcl index bb6b9c889e20a3..fafafb81f1269c 100644 --- a/git-gui/lib/console.tcl +++ b/git-gui/lib/console.tcl @@ -97,7 +97,7 @@ method exec {cmd {after {}}} { lappend cmd 2>@1 set fd_f [_open_stdout_stderr $cmd] } - fconfigure $fd_f -blocking 0 -translation binary + fconfigure $fd_f -blocking 0 -translation binary -encoding [encoding system] fileevent $fd_f readable [cb _read $fd_f $after] } diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index 871ad488c2a1c0..d657bfec05b498 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -63,28 +63,17 @@ proc force_diff_encoding {enc} { } proc handle_empty_diff {} { - global current_diff_path file_states file_lists - global diff_empty_count + global current_diff_path file_states + global ui_diff set path $current_diff_path set s $file_states($path) if {[lindex $s 0] ne {_M} || [has_textconv $path]} return - # Prevent infinite rescan loops - incr diff_empty_count - if {$diff_empty_count > 1} return - - info_popup [mc "No differences detected. - -%s has no changes. - -The modification date of this file was updated by another application, but the content within the file was not changed. - -A rescan will be automatically started to find other files which may have the same state." [short_path $path]] - - clear_diff - display_file $path __ - rescan ui_ready 0 + $ui_diff conf -state normal + $ui_diff insert end [mc "* No differences detected; stage the file to de-list it from Unstaged Changes.\n"] d_info + $ui_diff insert end [mc "* Click to find other files that may have the same state.\n"] d_rescan + $ui_diff conf -state disabled } proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} { @@ -387,7 +376,6 @@ proc read_diff {fd conflict_size cont_info} { global ui_diff diff_active is_submodule_diff global is_3way_diff is_conflict_diff current_diff_header global current_diff_queue - global diff_empty_count $ui_diff conf -state normal while {[gets $fd line] >= 0} { @@ -559,8 +547,6 @@ proc read_diff {fd conflict_size cont_info} { if {[$ui_diff index end] eq {2.0}} { handle_empty_diff - } else { - set diff_empty_count 0 } set callback [lindex $cont_info 1] diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl index e688b016ef6c9d..8b8c16b1d616b6 100644 --- a/git-gui/lib/mergetool.tcl +++ b/git-gui/lib/mergetool.tcl @@ -272,8 +272,25 @@ proc merge_resolve_tool2 {} { } } default { - error_popup [mc "Unsupported merge tool '%s'" $tool] - return + set tool_cmd [get_config mergetool.$tool.cmd] + if {$tool_cmd ne {}} { + if {([string first {[} $tool_cmd] != -1) || ([string first {]} $tool_cmd] != -1)} { + error_popup [mc "Unable to process square brackets in \"mergetool.%s.cmd\" configuration option. + +Please remove the square brackets." $tool] + return + } else { + set cmdline {} + foreach command_part $tool_cmd { + lappend cmdline [subst -nobackslashes -nocommands $command_part] + } + } + } else { + error_popup [mc "Unsupported merge tool '%s'. + +To use this tool, configure \"mergetool.%s.cmd\" as shown in the git-config manual page." $tool $tool] + return + } } } diff --git a/git-gui/po/bg.po b/git-gui/po/bg.po index 5af78f15a86db9..27b05038e4418e 100644 --- a/git-gui/po/bg.po +++ b/git-gui/po/bg.po @@ -1,15 +1,15 @@ # Bulgarian translation of git-gui po-file. -# Copyright (C) 2012, 2013, 2014, 2015, 2016 Alexander Shopov <ash@kambanaria.org>. +# Copyright (C) 2012, 2013, 2014, 2015, 2016, 2024 Alexander Shopov <ash@kambanaria.org>. # This file is distributed under the same license as the git package. -# Alexander Shopov <ash@kambanaria.org>, 2012, 2013, 2014, 2015, 2016. +# Alexander Shopov <ash@kambanaria.org>, 2012, 2013, 2014, 2015, 2016, 2024. # # msgid "" msgstr "" "Project-Id-Version: git-gui master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2016-10-13 15:16+0300\n" -"PO-Revision-Date: 2016-10-13 15:16+0300\n" +"POT-Creation-Date: 2020-02-08 22:54+0100\n" +"PO-Revision-Date: 2024-12-22 15:44+0100\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -18,33 +18,33 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: git-gui.sh:865 +#: git-gui.sh:847 #, tcl-format msgid "Invalid font specified in %s:" msgstr "Указан е неправилен шрифт в „%s“:" -#: git-gui.sh:919 +#: git-gui.sh:901 msgid "Main Font" msgstr "Основен шрифт" -#: git-gui.sh:920 +#: git-gui.sh:902 msgid "Diff/Console Font" msgstr "Шрифт за разликите/конзолата" -#: git-gui.sh:935 git-gui.sh:949 git-gui.sh:962 git-gui.sh:1052 git-gui.sh:1071 -#: git-gui.sh:3147 +#: git-gui.sh:917 git-gui.sh:931 git-gui.sh:944 git-gui.sh:1034 git-gui.sh:1053 +#: git-gui.sh:3212 msgid "git-gui: fatal error" msgstr "git-gui: фатална грешка" -#: git-gui.sh:936 +#: git-gui.sh:918 msgid "Cannot find git in PATH." msgstr "Командата git липсва в пътя (PATH)." -#: git-gui.sh:963 +#: git-gui.sh:945 msgid "Cannot parse Git version string:" -msgstr "Низът с версията на Git не може да бъде интерпретиран:" +msgstr "Низът с версията на Git не може да се анализира:" -#: git-gui.sh:988 +#: git-gui.sh:970 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -55,7 +55,7 @@ msgid "" "\n" "Assume '%s' is version 1.5.0?\n" msgstr "" -"Версията на Git не може да бъде определена.\n" +"Версията на Git не може да се определи.\n" "\n" "Версията на „%s“ изглежда, че е „%s“.\n" "\n" @@ -63,506 +63,522 @@ msgstr "" "\n" "Да се приеме ли, че „%s“ е версия „1.5.0“?\n" -#: git-gui.sh:1285 +#: git-gui.sh:1267 msgid "Git directory not found:" msgstr "Директорията на Git не е открита:" -#: git-gui.sh:1319 +#: git-gui.sh:1301 msgid "Cannot move to top of working directory:" -msgstr "Не може да се премине към родителската директория." +msgstr "Не може да се премине към родителската директория." -#: git-gui.sh:1327 +#: git-gui.sh:1309 msgid "Cannot use bare repository:" msgstr "Голо хранилище не може да се използва:" -#: git-gui.sh:1335 +#: git-gui.sh:1317 msgid "No working directory" msgstr "Работната директория липсва" -#: git-gui.sh:1507 lib/checkout_op.tcl:306 +#: git-gui.sh:1491 lib/checkout_op.tcl:306 msgid "Refreshing file status..." msgstr "Обновяване на състоянието на файла…" -#: git-gui.sh:1567 +#: git-gui.sh:1551 msgid "Scanning for modified files ..." msgstr "Проверка за променени файлове…" -#: git-gui.sh:1645 +#: git-gui.sh:1629 msgid "Calling prepare-commit-msg hook..." msgstr "Куката „prepare-commit-msg“ се изпълнява в момента…" -#: git-gui.sh:1662 +#: git-gui.sh:1646 msgid "Commit declined by prepare-commit-msg hook." msgstr "Подаването е отхвърлено от куката „prepare-commit-msg“." -#: git-gui.sh:1820 lib/browser.tcl:252 +#: git-gui.sh:1804 lib/browser.tcl:252 msgid "Ready." msgstr "Готово." -#: git-gui.sh:1984 +#: git-gui.sh:1968 #, tcl-format msgid "" "Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s files." msgstr "" -"Достигнат е максималният размер на списъка за извеждане(gui." -"maxfilesdisplayed = %s), съответно не са показани всички %s файла." +"Достигнат е максималният размер на списъка за " +"извеждане(gui.maxfilesdisplayed = %s), съответно не са показани всички %s " +"файла." -#: git-gui.sh:2107 +#: git-gui.sh:2091 msgid "Unmodified" msgstr "Непроменен" -#: git-gui.sh:2109 +#: git-gui.sh:2093 msgid "Modified, not staged" msgstr "Променен, но не е в индекса" -#: git-gui.sh:2110 git-gui.sh:2122 +#: git-gui.sh:2094 git-gui.sh:2106 msgid "Staged for commit" msgstr "В индекса за подаване" -#: git-gui.sh:2111 git-gui.sh:2123 +#: git-gui.sh:2095 git-gui.sh:2107 msgid "Portions staged for commit" msgstr "Части са в индекса за подаване" -#: git-gui.sh:2112 git-gui.sh:2124 +#: git-gui.sh:2096 git-gui.sh:2108 msgid "Staged for commit, missing" msgstr "В индекса за подаване, но липсва" -#: git-gui.sh:2114 +#: git-gui.sh:2098 msgid "File type changed, not staged" msgstr "Видът на файла е сменен, но не е в индекса" -#: git-gui.sh:2115 git-gui.sh:2116 +#: git-gui.sh:2099 git-gui.sh:2100 msgid "File type changed, old type staged for commit" msgstr "Видът на файла е сменен, но новият вид не е в индекса" -#: git-gui.sh:2117 +#: git-gui.sh:2101 msgid "File type changed, staged" msgstr "Видът на файла е сменен и е в индекса" -#: git-gui.sh:2118 +#: git-gui.sh:2102 msgid "File type change staged, modification not staged" msgstr "Видът на файла е сменен в индекса, но не и съдържанието" -#: git-gui.sh:2119 +#: git-gui.sh:2103 msgid "File type change staged, file missing" msgstr "Видът на файла е сменен в индекса, но файлът липсва" -#: git-gui.sh:2121 +#: git-gui.sh:2105 msgid "Untracked, not staged" msgstr "Неследен" -#: git-gui.sh:2126 +#: git-gui.sh:2110 msgid "Missing" msgstr "Липсващ" -#: git-gui.sh:2127 +#: git-gui.sh:2111 msgid "Staged for removal" msgstr "В индекса за изтриване" -#: git-gui.sh:2128 +#: git-gui.sh:2112 msgid "Staged for removal, still present" msgstr "В индекса за изтриване, но още го има" -#: git-gui.sh:2130 git-gui.sh:2131 git-gui.sh:2132 git-gui.sh:2133 -#: git-gui.sh:2134 git-gui.sh:2135 +#: git-gui.sh:2114 git-gui.sh:2115 git-gui.sh:2116 git-gui.sh:2117 +#: git-gui.sh:2118 git-gui.sh:2119 msgid "Requires merge resolution" msgstr "Изисква коригиране при сливане" -#: git-gui.sh:2170 -msgid "Starting gitk... please wait..." -msgstr "Стартиране на „gitk“…, изчакайте…" - -#: git-gui.sh:2182 +#: git-gui.sh:2164 msgid "Couldn't find gitk in PATH" msgstr "Командата „gitk“ липсва в пътищата, определени от променливата PATH." -#: git-gui.sh:2241 +#: git-gui.sh:2210 git-gui.sh:2245 +#, tcl-format +msgid "Starting %s... please wait..." +msgstr "Стартиране на „%s“…, изчакайте…" + +#: git-gui.sh:2224 msgid "Couldn't find git gui in PATH" msgstr "" "Командата „git gui“ липсва в пътищата, определени от променливата PATH." -#: git-gui.sh:2676 lib/choose_repository.tcl:41 +#: git-gui.sh:2726 lib/choose_repository.tcl:53 msgid "Repository" msgstr "Хранилище" -#: git-gui.sh:2677 +#: git-gui.sh:2727 msgid "Edit" msgstr "Редактиране" -#: git-gui.sh:2679 lib/choose_rev.tcl:567 +#: git-gui.sh:2729 lib/choose_rev.tcl:567 msgid "Branch" msgstr "Клон" -#: git-gui.sh:2682 lib/choose_rev.tcl:554 +#: git-gui.sh:2732 lib/choose_rev.tcl:554 msgid "Commit@@noun" msgstr "Подаване" -#: git-gui.sh:2685 lib/merge.tcl:127 lib/merge.tcl:174 +#: git-gui.sh:2735 lib/merge.tcl:127 lib/merge.tcl:174 msgid "Merge" msgstr "Сливане" -#: git-gui.sh:2686 lib/choose_rev.tcl:563 +#: git-gui.sh:2736 lib/choose_rev.tcl:563 msgid "Remote" msgstr "Отдалечено хранилище" -#: git-gui.sh:2689 +#: git-gui.sh:2739 msgid "Tools" msgstr "Команди" -#: git-gui.sh:2698 +#: git-gui.sh:2748 msgid "Explore Working Copy" msgstr "Разглеждане на работното копие" -#: git-gui.sh:2704 +#: git-gui.sh:2763 msgid "Git Bash" msgstr "Bash за Git" -#: git-gui.sh:2714 +#: git-gui.sh:2772 msgid "Browse Current Branch's Files" msgstr "Разглеждане на файловете в текущия клон" -#: git-gui.sh:2718 +#: git-gui.sh:2776 msgid "Browse Branch Files..." msgstr "Разглеждане на текущия клон…" -#: git-gui.sh:2723 +#: git-gui.sh:2781 msgid "Visualize Current Branch's History" msgstr "Визуализация на историята на текущия клон" -#: git-gui.sh:2727 +#: git-gui.sh:2785 msgid "Visualize All Branch History" msgstr "Визуализация на историята на всички клонове" -#: git-gui.sh:2734 +#: git-gui.sh:2792 #, tcl-format msgid "Browse %s's Files" msgstr "Разглеждане на файловете в „%s“" -#: git-gui.sh:2736 +#: git-gui.sh:2794 #, tcl-format msgid "Visualize %s's History" msgstr "Визуализация на историята на „%s“" -#: git-gui.sh:2741 lib/database.tcl:40 +#: git-gui.sh:2799 lib/database.tcl:40 msgid "Database Statistics" msgstr "Статистика на базата от данни" -#: git-gui.sh:2744 lib/database.tcl:33 +#: git-gui.sh:2802 lib/database.tcl:33 msgid "Compress Database" msgstr "Компресиране на базата от данни" -#: git-gui.sh:2747 +#: git-gui.sh:2805 msgid "Verify Database" msgstr "Проверка на базата от данни" -#: git-gui.sh:2754 git-gui.sh:2758 git-gui.sh:2762 +#: git-gui.sh:2812 git-gui.sh:2816 git-gui.sh:2820 msgid "Create Desktop Icon" msgstr "Добавяне на икона на работния плот" -#: git-gui.sh:2770 lib/choose_repository.tcl:193 lib/choose_repository.tcl:201 +#: git-gui.sh:2828 lib/choose_repository.tcl:209 lib/choose_repository.tcl:217 msgid "Quit" msgstr "Спиране на програмата" -#: git-gui.sh:2778 +#: git-gui.sh:2836 msgid "Undo" msgstr "Отмяна" -#: git-gui.sh:2781 +#: git-gui.sh:2839 msgid "Redo" msgstr "Повторение" -#: git-gui.sh:2785 git-gui.sh:3399 +#: git-gui.sh:2843 git-gui.sh:3461 msgid "Cut" msgstr "Отрязване" -#: git-gui.sh:2788 git-gui.sh:3402 git-gui.sh:3476 git-gui.sh:3562 +#: git-gui.sh:2846 git-gui.sh:3464 git-gui.sh:3540 git-gui.sh:3633 #: lib/console.tcl:69 msgid "Copy" msgstr "Копиране" -#: git-gui.sh:2791 git-gui.sh:3405 +#: git-gui.sh:2849 git-gui.sh:3467 msgid "Paste" msgstr "Поставяне" -#: git-gui.sh:2794 git-gui.sh:3408 lib/branch_delete.tcl:28 -#: lib/remote_branch_delete.tcl:39 +#: git-gui.sh:2852 git-gui.sh:3470 lib/remote_branch_delete.tcl:39 +#: lib/branch_delete.tcl:28 msgid "Delete" msgstr "Изтриване" -#: git-gui.sh:2798 git-gui.sh:3412 git-gui.sh:3566 lib/console.tcl:71 +#: git-gui.sh:2856 git-gui.sh:3474 git-gui.sh:3637 lib/console.tcl:71 msgid "Select All" msgstr "Избиране на всичко" -#: git-gui.sh:2807 +#: git-gui.sh:2865 msgid "Create..." msgstr "Създаване…" -#: git-gui.sh:2813 +#: git-gui.sh:2871 msgid "Checkout..." msgstr "Изтегляне…" -#: git-gui.sh:2819 +#: git-gui.sh:2877 msgid "Rename..." msgstr "Преименуване…" -#: git-gui.sh:2824 +#: git-gui.sh:2882 msgid "Delete..." msgstr "Изтриване…" -#: git-gui.sh:2829 +#: git-gui.sh:2887 msgid "Reset..." msgstr "Отмяна на промените…" -#: git-gui.sh:2839 +#: git-gui.sh:2897 msgid "Done" msgstr "Готово" -#: git-gui.sh:2841 +#: git-gui.sh:2899 msgid "Commit@@verb" msgstr "Подаване" -#: git-gui.sh:2850 git-gui.sh:3335 -msgid "New Commit" -msgstr "Ново подаване" - -#: git-gui.sh:2858 git-gui.sh:3342 +#: git-gui.sh:2908 git-gui.sh:3400 msgid "Amend Last Commit" msgstr "Поправяне на последното подаване" -#: git-gui.sh:2868 git-gui.sh:3296 lib/remote_branch_delete.tcl:101 +#: git-gui.sh:2918 git-gui.sh:3361 lib/remote_branch_delete.tcl:101 msgid "Rescan" msgstr "Обновяване" -#: git-gui.sh:2874 +#: git-gui.sh:2924 msgid "Stage To Commit" msgstr "Към индекса за подаване" -#: git-gui.sh:2880 +#: git-gui.sh:2930 msgid "Stage Changed Files To Commit" msgstr "Всички променени файлове към индекса за подаване" -#: git-gui.sh:2886 +#: git-gui.sh:2936 msgid "Unstage From Commit" msgstr "Изваждане от индекса за подаване" -#: git-gui.sh:2892 lib/index.tcl:442 +#: git-gui.sh:2942 lib/index.tcl:521 msgid "Revert Changes" msgstr "Връщане на оригинала" -#: git-gui.sh:2900 git-gui.sh:3613 git-gui.sh:3644 +#: git-gui.sh:2950 git-gui.sh:3700 git-gui.sh:3731 msgid "Show Less Context" msgstr "По-малко контекст" -#: git-gui.sh:2904 git-gui.sh:3617 git-gui.sh:3648 +#: git-gui.sh:2954 git-gui.sh:3704 git-gui.sh:3735 msgid "Show More Context" msgstr "Повече контекст" -#: git-gui.sh:2911 git-gui.sh:3309 git-gui.sh:3423 +#: git-gui.sh:2961 git-gui.sh:3374 git-gui.sh:3485 msgid "Sign Off" msgstr "Подписване" -#: git-gui.sh:2927 +#: git-gui.sh:2977 msgid "Local Merge..." msgstr "Локално сливане…" -#: git-gui.sh:2932 +#: git-gui.sh:2982 msgid "Abort Merge..." msgstr "Преустановяване на сливане…" -#: git-gui.sh:2944 git-gui.sh:2972 +#: git-gui.sh:2994 git-gui.sh:3022 msgid "Add..." msgstr "Добавяне…" -#: git-gui.sh:2948 +#: git-gui.sh:2998 msgid "Push..." msgstr "Изтласкване…" -#: git-gui.sh:2952 +#: git-gui.sh:3002 msgid "Delete Branch..." msgstr "Изтриване на клон…" -#: git-gui.sh:2962 git-gui.sh:3595 +#: git-gui.sh:3012 git-gui.sh:3666 msgid "Options..." msgstr "Опции…" -#: git-gui.sh:2973 +#: git-gui.sh:3023 msgid "Remove..." msgstr "Премахване…" -#: git-gui.sh:2982 lib/choose_repository.tcl:55 +#: git-gui.sh:3032 lib/choose_repository.tcl:67 msgid "Help" msgstr "Помощ" -#: git-gui.sh:2986 git-gui.sh:2990 lib/about.tcl:14 -#: lib/choose_repository.tcl:49 lib/choose_repository.tcl:58 +#: git-gui.sh:3036 git-gui.sh:3040 lib/choose_repository.tcl:61 +#: lib/choose_repository.tcl:70 lib/about.tcl:14 #, tcl-format msgid "About %s" -msgstr "Относно %s" +msgstr "Относно „%s“" -#: git-gui.sh:3014 +#: git-gui.sh:3064 msgid "Online Documentation" msgstr "Документация в Интернет" -#: git-gui.sh:3017 lib/choose_repository.tcl:52 lib/choose_repository.tcl:61 +#: git-gui.sh:3067 lib/choose_repository.tcl:64 lib/choose_repository.tcl:73 msgid "Show SSH Key" msgstr "Показване на ключа за SSH" -#: git-gui.sh:3032 git-gui.sh:3164 +#: git-gui.sh:3097 git-gui.sh:3229 msgid "usage:" msgstr "употреба:" -#: git-gui.sh:3036 git-gui.sh:3168 +#: git-gui.sh:3101 git-gui.sh:3233 msgid "Usage" msgstr "Употреба" -#: git-gui.sh:3117 lib/blame.tcl:573 +#: git-gui.sh:3182 lib/blame.tcl:575 msgid "Error" msgstr "Грешка" -#: git-gui.sh:3148 +#: git-gui.sh:3213 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" -msgstr "" -"ФАТАЛНА ГРЕШКА: пътят %s не може да бъде открит: такъв файл или директория " -"няма" +msgstr "ФАТАЛНА ГРЕШКА: пътят „%s“ липсва: такъв файл или директория няма" -#: git-gui.sh:3181 +#: git-gui.sh:3246 msgid "Current Branch:" msgstr "Текущ клон:" -#: git-gui.sh:3206 +#: git-gui.sh:3271 msgid "Unstaged Changes" msgstr "Промени извън индекса" -#: git-gui.sh:3228 +#: git-gui.sh:3293 msgid "Staged Changes (Will Commit)" msgstr "Промени в индекса (за подаване)" -#: git-gui.sh:3302 +#: git-gui.sh:3367 msgid "Stage Changed" msgstr "Индексът е променен" -#: git-gui.sh:3321 lib/transport.tcl:137 +#: git-gui.sh:3386 lib/transport.tcl:137 msgid "Push" msgstr "Изтласкване" -#: git-gui.sh:3356 +#: git-gui.sh:3413 msgid "Initial Commit Message:" msgstr "Първоначално съобщение при подаване:" -#: git-gui.sh:3357 +#: git-gui.sh:3414 msgid "Amended Commit Message:" msgstr "Поправено съобщение при подаване:" -#: git-gui.sh:3358 +#: git-gui.sh:3415 msgid "Amended Initial Commit Message:" msgstr "Поправено първоначално съобщение при подаване:" -#: git-gui.sh:3359 +#: git-gui.sh:3416 msgid "Amended Merge Commit Message:" msgstr "Поправено съобщение при подаване със сливане:" -#: git-gui.sh:3360 +#: git-gui.sh:3417 msgid "Merge Commit Message:" msgstr "Съобщение при подаване със сливане:" -#: git-gui.sh:3361 +#: git-gui.sh:3418 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: git-gui.sh:3415 git-gui.sh:3570 lib/console.tcl:73 +#: git-gui.sh:3477 git-gui.sh:3641 lib/console.tcl:73 msgid "Copy All" msgstr "Копиране на всичко" -#: git-gui.sh:3439 lib/blame.tcl:105 +#: git-gui.sh:3501 lib/blame.tcl:106 msgid "File:" msgstr "Файл:" -#: git-gui.sh:3558 +#: git-gui.sh:3549 lib/choose_repository.tcl:1100 +msgid "Open" +msgstr "Отваряне" + +#: git-gui.sh:3629 msgid "Refresh" msgstr "Обновяване" -#: git-gui.sh:3579 +#: git-gui.sh:3650 msgid "Decrease Font Size" -msgstr "По-едър шрифт" +msgstr "По-дребен шрифт" -#: git-gui.sh:3583 +#: git-gui.sh:3654 msgid "Increase Font Size" -msgstr "По-дребен шрифт" +msgstr "По-едър шрифт" -#: git-gui.sh:3591 lib/blame.tcl:294 +#: git-gui.sh:3662 lib/blame.tcl:296 msgid "Encoding" msgstr "Кодиране" -#: git-gui.sh:3602 +#: git-gui.sh:3673 msgid "Apply/Reverse Hunk" msgstr "Прилагане/връщане на парче" -#: git-gui.sh:3607 +#: git-gui.sh:3678 msgid "Apply/Reverse Line" msgstr "Прилагане/връщане на ред" -#: git-gui.sh:3626 +#: git-gui.sh:3684 git-gui.sh:3794 git-gui.sh:3805 +msgid "Revert Hunk" +msgstr "Връщане на парче" + +#: git-gui.sh:3689 git-gui.sh:3801 git-gui.sh:3812 +msgid "Revert Line" +msgstr "Връщане на ред" + +#: git-gui.sh:3694 git-gui.sh:3791 +msgid "Undo Last Revert" +msgstr "Отмяна на последното връщане" + +#: git-gui.sh:3713 msgid "Run Merge Tool" msgstr "Изпълнение на програмата за сливане" -#: git-gui.sh:3631 +#: git-gui.sh:3718 msgid "Use Remote Version" msgstr "Версия от отдалеченото хранилище" -#: git-gui.sh:3635 +#: git-gui.sh:3722 msgid "Use Local Version" msgstr "Локална версия" -#: git-gui.sh:3639 +#: git-gui.sh:3726 msgid "Revert To Base" msgstr "Връщане към родителската версия" -#: git-gui.sh:3657 +#: git-gui.sh:3744 msgid "Visualize These Changes In The Submodule" msgstr "Визуализиране на промените в подмодула" -#: git-gui.sh:3661 +#: git-gui.sh:3748 msgid "Visualize Current Branch History In The Submodule" msgstr "Визуализация на историята на текущия клон в историята за подмодула" -#: git-gui.sh:3665 +#: git-gui.sh:3752 msgid "Visualize All Branch History In The Submodule" msgstr "Визуализация на историята на всички клони в историята за подмодула" -#: git-gui.sh:3670 +#: git-gui.sh:3757 msgid "Start git gui In The Submodule" msgstr "Стартиране на „git gui“ за подмодула" -#: git-gui.sh:3705 +#: git-gui.sh:3793 msgid "Unstage Hunk From Commit" msgstr "Изваждане на парчето от подаването" -#: git-gui.sh:3707 +#: git-gui.sh:3797 msgid "Unstage Lines From Commit" msgstr "Изваждане на редовете от подаването" -#: git-gui.sh:3709 +#: git-gui.sh:3798 git-gui.sh:3809 +msgid "Revert Lines" +msgstr "Връщане на редовете" + +#: git-gui.sh:3800 msgid "Unstage Line From Commit" msgstr "Изваждане на реда от подаването" -#: git-gui.sh:3712 +#: git-gui.sh:3804 msgid "Stage Hunk For Commit" msgstr "Добавяне на парчето за подаване" -#: git-gui.sh:3714 +#: git-gui.sh:3808 msgid "Stage Lines For Commit" msgstr "Добавяне на редовете за подаване" -#: git-gui.sh:3716 +#: git-gui.sh:3811 msgid "Stage Line For Commit" msgstr "Добавяне на реда за подаване" -#: git-gui.sh:3741 +#: git-gui.sh:3861 msgid "Initializing..." msgstr "Инициализиране…" -#: git-gui.sh:3886 +#: git-gui.sh:4017 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -574,12 +590,12 @@ msgid "" msgstr "" "Възможно е да има проблем със средата.\n" "\n" -"Най-вероятно следните променливи няма да бъдат\n" -"взети под внимание от подпроцесите на Git\n" +"Най-вероятно следните променливи няма да се\n" +"вземат под внимание от подпроцесите на Git\n" "от %s:\n" "\n" -#: git-gui.sh:3915 +#: git-gui.sh:4046 msgid "" "\n" "This is due to a known issue with the\n" @@ -589,7 +605,7 @@ msgstr "" "Това е познат проблем и се дължи на\n" "версията на Tcl включена в Cygwin." -#: git-gui.sh:3920 +#: git-gui.sh:4051 #, tcl-format msgid "" "\n" @@ -605,389 +621,204 @@ msgstr "" "е да поставите настройките „user.name“ и\n" "„user.email“ в личния си файл „~/.gitconfig“.\n" -#: lib/about.tcl:26 -msgid "git-gui - a graphical user interface for Git." -msgstr "git-gui — графичен интерфейс за Git." +#: lib/spellcheck.tcl:57 +msgid "Unsupported spell checker" +msgstr "Тази програма за проверка на правописа не се поддържа" -#: lib/blame.tcl:73 -#, tcl-format -msgid "%s (%s): File Viewer" -msgstr "%s (%s): Преглед на файлове" +#: lib/spellcheck.tcl:65 +msgid "Spell checking is unavailable" +msgstr "Липсва програма за проверка на правописа" -#: lib/blame.tcl:79 -msgid "Commit:" -msgstr "Подаване:" +#: lib/spellcheck.tcl:68 +msgid "Invalid spell checking configuration" +msgstr "Неправилни настройки на проверката на правописа" -#: lib/blame.tcl:280 -msgid "Copy Commit" -msgstr "Копиране на подаване" +#: lib/spellcheck.tcl:70 +#, tcl-format +msgid "Reverting dictionary to %s." +msgstr "Ползване на речник за език „%s“." -#: lib/blame.tcl:284 -msgid "Find Text..." -msgstr "Търсене на текст…" +#: lib/spellcheck.tcl:73 +msgid "Spell checker silently failed on startup" +msgstr "Програмата за правопис даже не стартира успешно." -#: lib/blame.tcl:288 -msgid "Goto Line..." -msgstr "Към ред…" +#: lib/spellcheck.tcl:80 +msgid "Unrecognized spell checker" +msgstr "Непозната програма за проверка на правописа" -#: lib/blame.tcl:297 -msgid "Do Full Copy Detection" -msgstr "Пълно търсене на копиране" +#: lib/spellcheck.tcl:186 +msgid "No Suggestions" +msgstr "Няма предложения" -#: lib/blame.tcl:301 -msgid "Show History Context" -msgstr "Показване на контекста от историята" +#: lib/spellcheck.tcl:388 +msgid "Unexpected EOF from spell checker" +msgstr "Неочакван край на файл от програмата за проверка на правописа" -#: lib/blame.tcl:304 -msgid "Blame Parent Commit" -msgstr "Анотиране на родителското подаване" +#: lib/spellcheck.tcl:392 +msgid "Spell Checker Failed" +msgstr "Грешка в програмата за проверка на правописа" -#: lib/blame.tcl:466 +#: lib/transport.tcl:6 lib/remote_add.tcl:132 #, tcl-format -msgid "Reading %s..." -msgstr "Чете се „%s“…" +msgid "fetch %s" +msgstr "доставяне на „%s“" -#: lib/blame.tcl:594 -msgid "Loading copy/move tracking annotations..." -msgstr "Зареждане на анотациите за проследяване на копирането/преместването…" +#: lib/transport.tcl:7 +#, tcl-format +msgid "Fetching new changes from %s" +msgstr "Доставяне на промените от „%s“" -#: lib/blame.tcl:614 -msgid "lines annotated" -msgstr "реда анотирани" +#: lib/transport.tcl:18 +#, tcl-format +msgid "remote prune %s" +msgstr "окастряне на следящите клони към „%s“" -#: lib/blame.tcl:806 -msgid "Loading original location annotations..." -msgstr "Зареждане на анотациите за първоначалното местоположение…" +#: lib/transport.tcl:19 +#, tcl-format +msgid "Pruning tracking branches deleted from %s" +msgstr "Окастряне на следящите клони на изтритите клони от „%s“" -#: lib/blame.tcl:809 -msgid "Annotation complete." -msgstr "Анотирането завърши." +#: lib/transport.tcl:25 +msgid "fetch all remotes" +msgstr "доставяне от всички отдалечени" -#: lib/blame.tcl:839 -msgid "Busy" -msgstr "Операцията не е завършила" +#: lib/transport.tcl:26 +msgid "Fetching new changes from all remotes" +msgstr "Доставяне на промените от всички отдалечени хранилища" -#: lib/blame.tcl:840 -msgid "Annotation process is already running." -msgstr "В момента тече процес на анотиране." +#: lib/transport.tcl:40 +msgid "remote prune all remotes" +msgstr "окастряне на следящите изтрити" -#: lib/blame.tcl:879 -msgid "Running thorough copy detection..." -msgstr "Изпълнява се цялостен процес на откриване на копиране…" +#: lib/transport.tcl:41 +msgid "Pruning tracking branches deleted from all remotes" +msgstr "" +"Окастряне на следящите клони на изтритите клони от всички отдалечени " +"хранилища" -#: lib/blame.tcl:947 -msgid "Loading annotation..." -msgstr "Зареждане на анотации…" +#: lib/transport.tcl:54 lib/transport.tcl:92 lib/transport.tcl:110 +#: lib/remote_add.tcl:162 +#, tcl-format +msgid "push %s" +msgstr "изтласкване на „%s“" -#: lib/blame.tcl:1000 -msgid "Author:" -msgstr "Автор:" +#: lib/transport.tcl:55 +#, tcl-format +msgid "Pushing changes to %s" +msgstr "Изтласкване на промените към „%s“" -#: lib/blame.tcl:1004 -msgid "Committer:" -msgstr "Подал:" +#: lib/transport.tcl:93 +#, tcl-format +msgid "Mirroring to %s" +msgstr "Изтласкване на всичко към „%s“" -#: lib/blame.tcl:1009 -msgid "Original File:" -msgstr "Първоначален файл:" +#: lib/transport.tcl:111 +#, tcl-format +msgid "Pushing %s %s to %s" +msgstr "Изтласкване на %s „%s“ към „%s“" -#: lib/blame.tcl:1057 -msgid "Cannot find HEAD commit:" -msgstr "Подаването за връх „HEAD“ не може да се открие:" +#: lib/transport.tcl:132 +msgid "Push Branches" +msgstr "Клони за изтласкване" -#: lib/blame.tcl:1112 -msgid "Cannot find parent commit:" -msgstr "Родителското подаване не може да бъде открито" +#: lib/transport.tcl:141 lib/checkout_op.tcl:580 lib/remote_add.tcl:34 +#: lib/browser.tcl:292 lib/branch_checkout.tcl:30 lib/branch_rename.tcl:32 +#: lib/choose_font.tcl:45 lib/option.tcl:127 lib/tools_dlg.tcl:41 +#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/remote_branch_delete.tcl:43 +#: lib/branch_create.tcl:37 lib/branch_delete.tcl:34 lib/merge.tcl:178 +msgid "Cancel" +msgstr "Отказване" -#: lib/blame.tcl:1127 -msgid "Unable to display parent" -msgstr "Родителят не може да бъде показан" +#: lib/transport.tcl:147 +msgid "Source Branches" +msgstr "Клони-източници" -#: lib/blame.tcl:1128 lib/diff.tcl:358 -msgid "Error loading diff:" -msgstr "Грешка при зареждане на разлика:" +#: lib/transport.tcl:162 +msgid "Destination Repository" +msgstr "Целево хранилище" -#: lib/blame.tcl:1269 -msgid "Originally By:" -msgstr "Първоначално от:" +#: lib/transport.tcl:165 lib/remote_branch_delete.tcl:51 +msgid "Remote:" +msgstr "Отдалечено хранилище:" -#: lib/blame.tcl:1275 -msgid "In File:" -msgstr "Във файл:" +#: lib/transport.tcl:187 lib/remote_branch_delete.tcl:72 +msgid "Arbitrary Location:" +msgstr "Произволно местоположение:" -#: lib/blame.tcl:1280 -msgid "Copied Or Moved Here By:" -msgstr "Копирано или преместено тук от:" +#: lib/transport.tcl:205 +msgid "Transfer Options" +msgstr "Настройки при пренасянето" -#: lib/branch_checkout.tcl:16 -#, tcl-format -msgid "%s (%s): Checkout Branch" -msgstr "%s (%s): Клон за изтегляне" +#: lib/transport.tcl:207 +msgid "Force overwrite existing branch (may discard changes)" +msgstr "" +"Изрично презаписване на съществуващ клон (някои промени може да се загубят)" -#: lib/branch_checkout.tcl:21 -msgid "Checkout Branch" -msgstr "Клон за изтегляне" +#: lib/transport.tcl:211 +msgid "Use thin pack (for slow network connections)" +msgstr "Максимална компресия (за бавни мрежови връзки)" -#: lib/branch_checkout.tcl:26 -msgid "Checkout" -msgstr "Изтегляне" +#: lib/transport.tcl:215 +msgid "Include tags" +msgstr "Включване на етикетите" -#: lib/branch_checkout.tcl:30 lib/branch_create.tcl:37 lib/branch_delete.tcl:34 -#: lib/branch_rename.tcl:32 lib/browser.tcl:292 lib/checkout_op.tcl:579 -#: lib/choose_font.tcl:45 lib/merge.tcl:178 lib/option.tcl:127 -#: lib/remote_add.tcl:34 lib/remote_branch_delete.tcl:43 lib/tools_dlg.tcl:41 -#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/transport.tcl:141 -msgid "Cancel" -msgstr "Отказване" +#: lib/transport.tcl:229 +#, tcl-format +msgid "%s (%s): Push" +msgstr "%s (%s): Изтласкване" -#: lib/branch_checkout.tcl:35 lib/browser.tcl:297 lib/tools_dlg.tcl:321 -msgid "Revision" -msgstr "Версия" +#: lib/checkout_op.tcl:85 +#, tcl-format +msgid "Fetching %s from %s" +msgstr "Доставяне на „%s“ от „%s“" -#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:69 lib/option.tcl:310 -msgid "Options" -msgstr "Опции" +#: lib/checkout_op.tcl:133 +#, tcl-format +msgid "fatal: Cannot resolve %s" +msgstr "фатална грешка: „%s“ не може да се открие" -#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92 -msgid "Fetch Tracking Branch" -msgstr "Изтегляне на промените от следения клон" +#: lib/checkout_op.tcl:146 lib/sshkey.tcl:58 lib/console.tcl:81 +#: lib/database.tcl:30 +msgid "Close" +msgstr "Затваряне" -#: lib/branch_checkout.tcl:47 -msgid "Detach From Local Branch" -msgstr "Изтриване от локалния клон" +#: lib/checkout_op.tcl:175 +#, tcl-format +msgid "Branch '%s' does not exist." +msgstr "Клонът „%s“ не съществува." -#: lib/branch_create.tcl:23 +#: lib/checkout_op.tcl:194 #, tcl-format -msgid "%s (%s): Create Branch" -msgstr "%s (%s): Създаване на клон" +msgid "Failed to configure simplified git-pull for '%s'." +msgstr "Неуспешно настройване на опростен git-pull за „%s“." -#: lib/branch_create.tcl:28 -msgid "Create New Branch" -msgstr "Създаване на нов клон" +#: lib/checkout_op.tcl:202 lib/branch_rename.tcl:102 +#, tcl-format +msgid "Branch '%s' already exists." +msgstr "Клонът „%s“ вече съществува." -#: lib/branch_create.tcl:33 lib/choose_repository.tcl:407 -msgid "Create" -msgstr "Създаване" +#: lib/checkout_op.tcl:229 +#, tcl-format +msgid "" +"Branch '%s' already exists.\n" +"\n" +"It cannot fast-forward to %s.\n" +"A merge is required." +msgstr "" +"Клонът „%s“ съществува.\n" +"\n" +"Той не може да се слее тривиално до „%s“.\n" +"Необходимо е сливане." -#: lib/branch_create.tcl:42 -msgid "Branch Name" -msgstr "Име на клона" +#: lib/checkout_op.tcl:243 +#, tcl-format +msgid "Merge strategy '%s' not supported." +msgstr "Стратегия за сливане „%s“ не се поддържа." -#: lib/branch_create.tcl:44 lib/remote_add.tcl:41 lib/tools_dlg.tcl:51 -msgid "Name:" -msgstr "Име:" - -#: lib/branch_create.tcl:57 -msgid "Match Tracking Branch Name" -msgstr "Съвпадане по името на следения клон" - -#: lib/branch_create.tcl:66 -msgid "Starting Revision" -msgstr "Начална версия" - -#: lib/branch_create.tcl:72 -msgid "Update Existing Branch:" -msgstr "Обновяване на съществуващ клон:" - -#: lib/branch_create.tcl:75 -msgid "No" -msgstr "Не" - -#: lib/branch_create.tcl:80 -msgid "Fast Forward Only" -msgstr "Само тривиално превъртащо сливане" - -#: lib/branch_create.tcl:85 lib/checkout_op.tcl:571 -msgid "Reset" -msgstr "Отначало" - -#: lib/branch_create.tcl:97 -msgid "Checkout After Creation" -msgstr "Преминаване към клона след създаването му" - -#: lib/branch_create.tcl:132 -msgid "Please select a tracking branch." -msgstr "Изберете клон за следени." - -#: lib/branch_create.tcl:141 -#, tcl-format -msgid "Tracking branch %s is not a branch in the remote repository." -msgstr "Следящият клон — „%s“, не съществува в отдалеченото хранилище." - -#: lib/branch_create.tcl:154 lib/branch_rename.tcl:92 -msgid "Please supply a branch name." -msgstr "Дайте име на клона." - -#: lib/branch_create.tcl:165 lib/branch_rename.tcl:112 -#, tcl-format -msgid "'%s' is not an acceptable branch name." -msgstr "„%s“ не може да се използва за име на клон." - -#: lib/branch_delete.tcl:16 -#, tcl-format -msgid "%s (%s): Delete Branch" -msgstr "%s (%s): Изтриване на клон" - -#: lib/branch_delete.tcl:21 -msgid "Delete Local Branch" -msgstr "Изтриване на локален клон" - -#: lib/branch_delete.tcl:39 -msgid "Local Branches" -msgstr "Локални клони" - -#: lib/branch_delete.tcl:51 -msgid "Delete Only If Merged Into" -msgstr "Изтриване, само ако промените са слети и другаде" - -#: lib/branch_delete.tcl:53 lib/remote_branch_delete.tcl:120 -msgid "Always (Do not perform merge checks)" -msgstr "Винаги (без проверка за сливане)" - -#: lib/branch_delete.tcl:103 -#, tcl-format -msgid "The following branches are not completely merged into %s:" -msgstr "Не всички промени в клоните са слети в „%s“:" - -#: lib/branch_delete.tcl:115 lib/remote_branch_delete.tcl:218 -msgid "" -"Recovering deleted branches is difficult.\n" -"\n" -"Delete the selected branches?" -msgstr "" -"Възстановяването на изтрити клони може да е трудно.\n" -"\n" -"Сигурни ли сте, че искате да триете?" - -#: lib/branch_delete.tcl:131 -#, tcl-format -msgid " - %s:" -msgstr " — „%s:“" - -#: lib/branch_delete.tcl:141 -#, tcl-format -msgid "" -"Failed to delete branches:\n" -"%s" -msgstr "" -"Неуспешно триене на клони:\n" -"%s" - -#: lib/branch_rename.tcl:15 -#, tcl-format -msgid "%s (%s): Rename Branch" -msgstr "%s (%s): Преименуване на клон" - -#: lib/branch_rename.tcl:23 -msgid "Rename Branch" -msgstr "Преименуване на клон" - -#: lib/branch_rename.tcl:28 -msgid "Rename" -msgstr "Преименуване" - -#: lib/branch_rename.tcl:38 -msgid "Branch:" -msgstr "Клон:" - -#: lib/branch_rename.tcl:46 -msgid "New Name:" -msgstr "Ново име:" - -#: lib/branch_rename.tcl:81 -msgid "Please select a branch to rename." -msgstr "Изберете клон за преименуване." - -#: lib/branch_rename.tcl:102 lib/checkout_op.tcl:202 -#, tcl-format -msgid "Branch '%s' already exists." -msgstr "Клонът „%s“ вече съществува." - -#: lib/branch_rename.tcl:123 -#, tcl-format -msgid "Failed to rename '%s'." -msgstr "Неуспешно преименуване на „%s“." - -#: lib/browser.tcl:17 -msgid "Starting..." -msgstr "Стартиране…" - -#: lib/browser.tcl:27 -#, tcl-format -msgid "%s (%s): File Browser" -msgstr "%s (%s): Файлов браузър" - -#: lib/browser.tcl:132 lib/browser.tcl:149 -#, tcl-format -msgid "Loading %s..." -msgstr "Зареждане на „%s“…" - -#: lib/browser.tcl:193 -msgid "[Up To Parent]" -msgstr "[Към родителя]" - -#: lib/browser.tcl:275 -#, tcl-format -msgid "%s (%s): Browse Branch Files" -msgstr "%s (%s): Разглеждане на файловете в клона" - -#: lib/browser.tcl:282 -msgid "Browse Branch Files" -msgstr "Разглеждане на файловете в клона" - -#: lib/browser.tcl:288 lib/choose_repository.tcl:422 -#: lib/choose_repository.tcl:509 lib/choose_repository.tcl:518 -#: lib/choose_repository.tcl:1074 -msgid "Browse" -msgstr "Разглеждане" - -#: lib/checkout_op.tcl:85 -#, tcl-format -msgid "Fetching %s from %s" -msgstr "Доставяне на „%s“ от „%s“" - -#: lib/checkout_op.tcl:133 -#, tcl-format -msgid "fatal: Cannot resolve %s" -msgstr "фатална грешка: „%s“ не може да се открие" - -#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:30 -#: lib/sshkey.tcl:55 -msgid "Close" -msgstr "Затваряне" - -#: lib/checkout_op.tcl:175 -#, tcl-format -msgid "Branch '%s' does not exist." -msgstr "Клонът „%s“ не съществува." - -#: lib/checkout_op.tcl:194 -#, tcl-format -msgid "Failed to configure simplified git-pull for '%s'." -msgstr "Неуспешно настройване на опростен git-pull за „%s“." - -#: lib/checkout_op.tcl:229 -#, tcl-format -msgid "" -"Branch '%s' already exists.\n" -"\n" -"It cannot fast-forward to %s.\n" -"A merge is required." -msgstr "" -"Клонът „%s“ съществува.\n" -"\n" -"Той не може да бъде тривиално слят до „%s“.\n" -"Необходимо е сливане." - -#: lib/checkout_op.tcl:243 -#, tcl-format -msgid "Merge strategy '%s' not supported." -msgstr "Стратегия за сливане „%s“ не се поддържа." - -#: lib/checkout_op.tcl:262 -#, tcl-format -msgid "Failed to update '%s'." -msgstr "Неуспешно обновяване на „%s“." +#: lib/checkout_op.tcl:262 +#, tcl-format +msgid "Failed to update '%s'." +msgstr "Неуспешно обновяване на „%s“." #: lib/checkout_op.tcl:274 msgid "Staging area (index) is already locked." @@ -1006,7 +837,7 @@ msgstr "" "хранилището.\n" "\n" "Някой друг процес за Git е променил хранилището междувременно. Състоянието " -"трябва да бъде проверено, преди да се премине към нов клон.\n" +"трябва да се провери, преди да се премине към нов клон.\n" "\n" "Автоматично ще започне нова проверка.\n" @@ -1019,22 +850,22 @@ msgstr "Работната директория се привежда към „ msgid "files checked out" msgstr "файла са изтеглени" -#: lib/checkout_op.tcl:376 +#: lib/checkout_op.tcl:377 #, tcl-format msgid "Aborted checkout of '%s' (file level merging is required)." msgstr "" "Преустановяване на изтеглянето на „%s“ (необходимо е пофайлово сливане)." -#: lib/checkout_op.tcl:377 +#: lib/checkout_op.tcl:378 msgid "File level merge required." msgstr "Необходимо е пофайлово сливане." -#: lib/checkout_op.tcl:381 +#: lib/checkout_op.tcl:382 #, tcl-format msgid "Staying on branch '%s'." msgstr "Оставане върху клона „%s“." -#: lib/checkout_op.tcl:452 +#: lib/checkout_op.tcl:453 msgid "" "You are no longer on a local branch.\n" "\n" @@ -1045,31 +876,35 @@ msgstr "" "\n" "Ако искате да сте на клон, създайте базиран на „Това несвързано изтегляне“." -#: lib/checkout_op.tcl:503 lib/checkout_op.tcl:507 +#: lib/checkout_op.tcl:504 lib/checkout_op.tcl:508 #, tcl-format msgid "Checked out '%s'." msgstr "„%s“ е изтеглен." -#: lib/checkout_op.tcl:535 +#: lib/checkout_op.tcl:536 #, tcl-format msgid "Resetting '%s' to '%s' will lose the following commits:" msgstr "" "Зануляването на „%s“ към „%s“ ще доведе до загубването на следните подавания:" -#: lib/checkout_op.tcl:557 +#: lib/checkout_op.tcl:558 msgid "Recovering lost commits may not be easy." msgstr "Възстановяването на загубените подавания може да е трудно." -#: lib/checkout_op.tcl:562 +#: lib/checkout_op.tcl:563 #, tcl-format msgid "Reset '%s'?" msgstr "Зануляване на „%s“?" -#: lib/checkout_op.tcl:567 lib/merge.tcl:170 lib/tools_dlg.tcl:336 +#: lib/checkout_op.tcl:568 lib/tools_dlg.tcl:336 lib/merge.tcl:170 msgid "Visualize" msgstr "Визуализация" -#: lib/checkout_op.tcl:635 +#: lib/checkout_op.tcl:572 lib/branch_create.tcl:85 +msgid "Reset" +msgstr "Отначало" + +#: lib/checkout_op.tcl:636 #, tcl-format msgid "" "Failed to set current branch.\n" @@ -1087,1721 +922,1945 @@ msgstr "" "Това състояние е аварийно и не трябва да се случва. Програмата „%s“ ще " "преустанови работа." -#: lib/choose_font.tcl:41 -msgid "Select" -msgstr "Избор" +#: lib/remote_add.tcl:20 +#, tcl-format +msgid "%s (%s): Add Remote" +msgstr "%s (%s): Добавяне на отдалечено хранилище" -#: lib/choose_font.tcl:55 -msgid "Font Family" -msgstr "Шрифт" +#: lib/remote_add.tcl:25 +msgid "Add New Remote" +msgstr "Добавяне на отдалечено хранилище" -#: lib/choose_font.tcl:76 -msgid "Font Size" -msgstr "Размер" +#: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37 +msgid "Add" +msgstr "Добавяне" -#: lib/choose_font.tcl:93 -msgid "Font Example" -msgstr "Мостра" +#: lib/remote_add.tcl:39 +msgid "Remote Details" +msgstr "Данни за отдалеченото хранилище" -#: lib/choose_font.tcl:105 -msgid "" -"This is example text.\n" -"If you like this text, it can be your font." -msgstr "" -"Това е примерен текст.\n" -"Ако ви харесва как изглежда, изберете шрифта." +#: lib/remote_add.tcl:41 lib/tools_dlg.tcl:51 lib/branch_create.tcl:44 +msgid "Name:" +msgstr "Име:" -#: lib/choose_repository.tcl:33 -msgid "Git Gui" -msgstr "ГПИ на Git" +#: lib/remote_add.tcl:50 +msgid "Location:" +msgstr "Местоположение:" -#: lib/choose_repository.tcl:92 lib/choose_repository.tcl:412 -msgid "Create New Repository" -msgstr "Създаване на ново хранилище" +#: lib/remote_add.tcl:60 +msgid "Further Action" +msgstr "Следващо действие" -#: lib/choose_repository.tcl:98 -msgid "New..." -msgstr "Ново…" +#: lib/remote_add.tcl:63 +msgid "Fetch Immediately" +msgstr "Незабавно доставяне" -#: lib/choose_repository.tcl:105 lib/choose_repository.tcl:496 -msgid "Clone Existing Repository" -msgstr "Клониране на съществуващо хранилище" +#: lib/remote_add.tcl:69 +msgid "Initialize Remote Repository and Push" +msgstr "Инициализиране на отдалеченото хранилище и изтласкване на промените" -#: lib/choose_repository.tcl:116 -msgid "Clone..." -msgstr "Клониране…" +#: lib/remote_add.tcl:75 +msgid "Do Nothing Else Now" +msgstr "Да не се прави нищо" -#: lib/choose_repository.tcl:123 lib/choose_repository.tcl:1064 -msgid "Open Existing Repository" -msgstr "Отваряне на съществуващо хранилище" +#: lib/remote_add.tcl:100 +msgid "Please supply a remote name." +msgstr "Задайте име за отдалеченото хранилище." -#: lib/choose_repository.tcl:129 -msgid "Open..." -msgstr "Отваряне…" +#: lib/remote_add.tcl:113 +#, tcl-format +msgid "'%s' is not an acceptable remote name." +msgstr "Отдалечено хранилище не може да се казва „%s“." -#: lib/choose_repository.tcl:142 -msgid "Recent Repositories" -msgstr "Скоро ползвани" +#: lib/remote_add.tcl:124 +#, tcl-format +msgid "Failed to add remote '%s' of location '%s'." +msgstr "Неуспешно добавяне на отдалеченото хранилище „%s“ от адрес „%s“." -#: lib/choose_repository.tcl:148 -msgid "Open Recent Repository:" -msgstr "Отваряне на хранилище ползвано наскоро:" +#: lib/remote_add.tcl:133 +#, tcl-format +msgid "Fetching the %s" +msgstr "Доставяне на „%s“" -#: lib/choose_repository.tcl:316 lib/choose_repository.tcl:323 -#: lib/choose_repository.tcl:330 +#: lib/remote_add.tcl:156 #, tcl-format -msgid "Failed to create repository %s:" -msgstr "Неуспешно създаване на хранилището „%s“:" +msgid "Do not know how to initialize repository at location '%s'." +msgstr "Хранилището с местоположение „%s“ не може да се инициализира." -#: lib/choose_repository.tcl:417 -msgid "Directory:" -msgstr "Директория:" +#: lib/remote_add.tcl:163 +#, tcl-format +msgid "Setting up the %s (at %s)" +msgstr "Добавяне на хранилище „%s“ (с адрес „%s“)" -#: lib/choose_repository.tcl:447 lib/choose_repository.tcl:573 -#: lib/choose_repository.tcl:1098 -msgid "Git Repository" -msgstr "Хранилище на Git" +#: lib/browser.tcl:17 +msgid "Starting..." +msgstr "Стартиране…" -#: lib/choose_repository.tcl:472 +#: lib/browser.tcl:27 #, tcl-format -msgid "Directory %s already exists." -msgstr "Вече съществува директория „%s“." +msgid "%s (%s): File Browser" +msgstr "%s (%s): Файлов браузър" -#: lib/choose_repository.tcl:476 +#: lib/browser.tcl:132 lib/browser.tcl:149 #, tcl-format -msgid "File %s already exists." -msgstr "Вече съществува файл „%s“." +msgid "Loading %s..." +msgstr "Зареждане на „%s“…" -#: lib/choose_repository.tcl:491 -msgid "Clone" -msgstr "Клониране" +#: lib/browser.tcl:193 +msgid "[Up To Parent]" +msgstr "[Към родителя]" -#: lib/choose_repository.tcl:504 -msgid "Source Location:" -msgstr "Адрес на източника:" +#: lib/browser.tcl:275 +#, tcl-format +msgid "%s (%s): Browse Branch Files" +msgstr "%s (%s): Разглеждане на файловете в клона" -#: lib/choose_repository.tcl:513 -msgid "Target Directory:" -msgstr "Целева директория:" +#: lib/browser.tcl:282 +msgid "Browse Branch Files" +msgstr "Разглеждане на файловете в клона" -#: lib/choose_repository.tcl:523 -msgid "Clone Type:" -msgstr "Вид клониране:" +#: lib/browser.tcl:288 lib/choose_repository.tcl:437 +#: lib/choose_repository.tcl:524 lib/choose_repository.tcl:533 +#: lib/choose_repository.tcl:1115 +msgid "Browse" +msgstr "Разглеждане" -#: lib/choose_repository.tcl:528 -msgid "Standard (Fast, Semi-Redundant, Hardlinks)" -msgstr "Стандартно (бързо, частично споделяне на файлове, твърди връзки)" +#: lib/browser.tcl:297 lib/branch_checkout.tcl:35 lib/tools_dlg.tcl:321 +msgid "Revision" +msgstr "Версия" -#: lib/choose_repository.tcl:533 -msgid "Full Copy (Slower, Redundant Backup)" -msgstr "Пълно (бавно, пълноценно резервно копие)" +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "Индексът не може да се отключи." -#: lib/choose_repository.tcl:538 -msgid "Shared (Fastest, Not Recommended, No Backup)" -msgstr "Споделено (най-бързо, не се препоръчва, не прави резервно копие)" +#: lib/index.tcl:30 +msgid "Index Error" +msgstr "Грешка в индекса" -#: lib/choose_repository.tcl:545 -msgid "Recursively clone submodules too" -msgstr "Рекурсивно клониране и на подмодулите" +#: lib/index.tcl:32 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "" +"Неуспешно обновяване на индекса на Git. Автоматично ще започне нова проверка " +"за синхронизирането на git-gui." -#: lib/choose_repository.tcl:579 lib/choose_repository.tcl:626 -#: lib/choose_repository.tcl:772 lib/choose_repository.tcl:842 -#: lib/choose_repository.tcl:1104 lib/choose_repository.tcl:1112 -#, tcl-format -msgid "Not a Git repository: %s" -msgstr "Това не е хранилище на Git: %s" +#: lib/index.tcl:43 +msgid "Continue" +msgstr "Продължаване" -#: lib/choose_repository.tcl:615 -msgid "Standard only available for local repository." -msgstr "Само локални хранилища могат да се клонират стандартно" +#: lib/index.tcl:46 +msgid "Unlock Index" +msgstr "Отключване на индекса" -#: lib/choose_repository.tcl:619 -msgid "Shared only available for local repository." -msgstr "Само локални хранилища могат да се клонират споделено" +#: lib/index.tcl:77 lib/index.tcl:146 lib/index.tcl:220 lib/index.tcl:587 +#: lib/choose_repository.tcl:999 +msgid "files" +msgstr "файлове" -#: lib/choose_repository.tcl:640 -#, tcl-format -msgid "Location %s already exists." -msgstr "Местоположението „%s“ вече съществува." +#: lib/index.tcl:326 +msgid "Unstaging selected files from commit" +msgstr "Изваждане на избраните файлове от подаването" -#: lib/choose_repository.tcl:651 -msgid "Failed to configure origin" -msgstr "Неуспешно настройване на хранилището-източник" +#: lib/index.tcl:330 +#, tcl-format +msgid "Unstaging %s from commit" +msgstr "Изваждане на „%s“ от подаването" -#: lib/choose_repository.tcl:663 -msgid "Counting objects" -msgstr "Преброяване на обекти" +#: lib/index.tcl:369 +msgid "Ready to commit." +msgstr "Готовност за подаване." -#: lib/choose_repository.tcl:664 -msgid "buckets" -msgstr "клетки" +#: lib/index.tcl:378 +msgid "Adding selected files" +msgstr "Добавяне на избраните файлове" -#: lib/choose_repository.tcl:688 +#: lib/index.tcl:382 #, tcl-format -msgid "Unable to copy objects/info/alternates: %s" -msgstr "Обектите/информацията/синонимите не могат да бъдат копирани: %s" +msgid "Adding %s" +msgstr "Добавяне на „%s“" -#: lib/choose_repository.tcl:724 +#: lib/index.tcl:412 #, tcl-format -msgid "Nothing to clone from %s." -msgstr "Няма какво да се клонира от „%s“." +msgid "Stage %d untracked files?" +msgstr "Да се добавят ли %d неследени файла към индекса?" -#: lib/choose_repository.tcl:726 lib/choose_repository.tcl:940 -#: lib/choose_repository.tcl:952 -msgid "The 'master' branch has not been initialized." -msgstr "Основният клон — „master“ не е инициализиран." +#: lib/index.tcl:420 +msgid "Adding all changed files" +msgstr "Добавяне на всички променени файлове" -#: lib/choose_repository.tcl:739 -msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "Не се поддържат твърди връзки. Преминава се към копиране." +#: lib/index.tcl:503 +#, tcl-format +msgid "Revert changes in file %s?" +msgstr "Да се махнат ли промените във файла „%s“?" -#: lib/choose_repository.tcl:751 +#: lib/index.tcl:508 #, tcl-format -msgid "Cloning from %s" -msgstr "Клониране на „%s“" +msgid "Revert changes in these %i files?" +msgstr "Да се махнат ли промените в тези %i файла?" -#: lib/choose_repository.tcl:782 -msgid "Copying objects" -msgstr "Копиране на обекти" +#: lib/index.tcl:517 +msgid "Any unstaged changes will be permanently lost by the revert." +msgstr "" +"Всички промени, които не са били добавени в индекса, ще се загубят " +"безвъзвратно." -#: lib/choose_repository.tcl:783 -msgid "KiB" -msgstr "KiB" +#: lib/index.tcl:520 lib/index.tcl:563 +msgid "Do Nothing" +msgstr "Нищо да не се прави" -#: lib/choose_repository.tcl:807 +#: lib/index.tcl:545 #, tcl-format -msgid "Unable to copy object: %s" -msgstr "Неуспешно копиране на обект: %s" - -#: lib/choose_repository.tcl:817 -msgid "Linking objects" -msgstr "Създаване на връзки към обектите" - -#: lib/choose_repository.tcl:818 -msgid "objects" -msgstr "обекти" +msgid "Delete untracked file %s?" +msgstr "Да се изтрие ли неследеният файл „%s“?" -#: lib/choose_repository.tcl:826 +#: lib/index.tcl:550 #, tcl-format -msgid "Unable to hardlink object: %s" -msgstr "Неуспешно създаване на твърда връзка към обект: %s" +msgid "Delete these %i untracked files?" +msgstr "Да се изтрият ли тези %d неследени файла?" -#: lib/choose_repository.tcl:881 -msgid "Cannot fetch branches and objects. See console output for details." -msgstr "" -"Клоните и обектите не могат да бъдат изтеглени. За повече информация " -"погледнете изхода на конзолата." +#: lib/index.tcl:560 +msgid "Files will be permanently deleted." +msgstr "Файловете ще се изтрият окончателно." -#: lib/choose_repository.tcl:892 -msgid "Cannot fetch tags. See console output for details." -msgstr "" -"Етикетите не могат да бъдат изтеглени. За повече информация погледнете " -"изхода на конзолата." +#: lib/index.tcl:564 +msgid "Delete Files" +msgstr "Изтриване на файлове" -#: lib/choose_repository.tcl:916 -msgid "Cannot determine HEAD. See console output for details." -msgstr "" -"Върхът „HEAD“ не може да бъде определен. За повече информация погледнете " -"изхода на конзолата." +#: lib/index.tcl:586 +msgid "Deleting" +msgstr "Изтриване" -#: lib/choose_repository.tcl:925 +#: lib/index.tcl:665 +msgid "Encountered errors deleting files:\n" +msgstr "Грешки при изтриване на файловете:\n" + +#: lib/index.tcl:674 #, tcl-format -msgid "Unable to cleanup %s" -msgstr "„%s“ не може да се зачисти" +msgid "None of the %d selected files could be deleted." +msgstr "Никой от избраните %d файла не бе изтрит." -#: lib/choose_repository.tcl:931 -msgid "Clone failed." -msgstr "Неуспешно клониране." +#: lib/index.tcl:679 +#, tcl-format +msgid "%d of the %d selected files could not be deleted." +msgstr "%d от избраните %d файла не бяха изтрити." -#: lib/choose_repository.tcl:938 -msgid "No default branch obtained." -msgstr "Не е получен клон по подразбиране." +#: lib/index.tcl:726 +msgid "Reverting selected files" +msgstr "Махане на промените в избраните файлове" -#: lib/choose_repository.tcl:949 +#: lib/index.tcl:730 #, tcl-format -msgid "Cannot resolve %s as a commit." -msgstr "Няма подаване отговарящо на „%s“." - -#: lib/choose_repository.tcl:961 -msgid "Creating working directory" -msgstr "Създаване на работната директория" +msgid "Reverting %s" +msgstr "Махане на промените в „%s“" -#: lib/choose_repository.tcl:962 lib/index.tcl:70 lib/index.tcl:136 -#: lib/index.tcl:207 -msgid "files" -msgstr "файлове" +#: lib/branch_checkout.tcl:16 +#, tcl-format +msgid "%s (%s): Checkout Branch" +msgstr "%s (%s): Клон за изтегляне" -#: lib/choose_repository.tcl:981 -msgid "Cannot clone submodules." -msgstr "Подмодулите не могат да се клонират." +#: lib/branch_checkout.tcl:21 +msgid "Checkout Branch" +msgstr "Клон за изтегляне" -#: lib/choose_repository.tcl:990 -msgid "Cloning submodules" -msgstr "Клониране на подмодули" +#: lib/branch_checkout.tcl:26 +msgid "Checkout" +msgstr "Изтегляне" -#: lib/choose_repository.tcl:1015 -msgid "Initial file checkout failed." -msgstr "Неуспешно първоначално изтегляне." +#: lib/branch_checkout.tcl:39 lib/option.tcl:310 lib/branch_create.tcl:69 +msgid "Options" +msgstr "Опции" -#: lib/choose_repository.tcl:1059 -msgid "Open" -msgstr "Отваряне" +#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92 +msgid "Fetch Tracking Branch" +msgstr "Изтегляне на промените от следения клон" -#: lib/choose_repository.tcl:1069 -msgid "Repository:" -msgstr "Хранилище:" +#: lib/branch_checkout.tcl:47 +msgid "Detach From Local Branch" +msgstr "Изтриване от локалния клон" -#: lib/choose_repository.tcl:1118 +#: lib/status_bar.tcl:263 #, tcl-format -msgid "Failed to open repository %s:" -msgstr "Неуспешно отваряне на хранилището „%s“:" +msgid "%s ... %*i of %*i %s (%3i%%)" +msgstr "%s… %*i от общо %*i %s (%3i%%)" -#: lib/choose_rev.tcl:52 -msgid "This Detached Checkout" -msgstr "Това несвързано изтегляне" +#: lib/remote.tcl:200 +msgid "Push to" +msgstr "Изтласкване към" -#: lib/choose_rev.tcl:60 -msgid "Revision Expression:" -msgstr "Израз за версия:" +#: lib/remote.tcl:218 +msgid "Remove Remote" +msgstr "Премахване на отдалечено хранилище" -#: lib/choose_rev.tcl:72 -msgid "Local Branch" -msgstr "Локален клон" +#: lib/remote.tcl:223 +msgid "Prune from" +msgstr "Окастряне от" -#: lib/choose_rev.tcl:77 -msgid "Tracking Branch" -msgstr "Следящ клон" +#: lib/remote.tcl:228 +msgid "Fetch from" +msgstr "Доставяне от" -#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544 -msgid "Tag" -msgstr "Етикет" +#: lib/remote.tcl:249 lib/remote.tcl:253 lib/remote.tcl:258 lib/remote.tcl:264 +msgid "All" +msgstr "Всички" -#: lib/choose_rev.tcl:321 +#: lib/branch_rename.tcl:15 #, tcl-format -msgid "Invalid revision: %s" -msgstr "Неправилна версия: %s" - -#: lib/choose_rev.tcl:342 -msgid "No revision selected." -msgstr "Не е избрана версия." +msgid "%s (%s): Rename Branch" +msgstr "%s (%s): Преименуване на клон" -#: lib/choose_rev.tcl:350 -msgid "Revision expression is empty." -msgstr "Изразът за версия е празен." +#: lib/branch_rename.tcl:23 +msgid "Rename Branch" +msgstr "Преименуване на клон" -#: lib/choose_rev.tcl:537 -msgid "Updated" -msgstr "Обновен" +#: lib/branch_rename.tcl:28 +msgid "Rename" +msgstr "Преименуване" -#: lib/choose_rev.tcl:565 -msgid "URL" -msgstr "Адрес" +#: lib/branch_rename.tcl:38 +msgid "Branch:" +msgstr "Клон:" -#: lib/commit.tcl:9 -msgid "" -"There is nothing to amend.\n" -"\n" -"You are about to create the initial commit. There is no commit before this " -"to amend.\n" -msgstr "" -"Няма какво да се поправи.\n" -"\n" -"Ще създадете първоначалното подаване. Преди него няма други подавания, които " -"да поправите.\n" +#: lib/branch_rename.tcl:46 +msgid "New Name:" +msgstr "Ново име:" -#: lib/commit.tcl:18 +#: lib/branch_rename.tcl:81 +msgid "Please select a branch to rename." +msgstr "Изберете клон за преименуване." + +#: lib/branch_rename.tcl:92 lib/branch_create.tcl:154 +msgid "Please supply a branch name." +msgstr "Дайте име на клона." + +#: lib/branch_rename.tcl:112 lib/branch_create.tcl:165 +#, tcl-format +msgid "'%s' is not an acceptable branch name." +msgstr "„%s“ не може да се използва за име на клон." + +#: lib/branch_rename.tcl:123 +#, tcl-format +msgid "Failed to rename '%s'." +msgstr "Неуспешно преименуване на „%s“." + +#: lib/choose_font.tcl:41 +msgid "Select" +msgstr "Избор" + +#: lib/choose_font.tcl:55 +msgid "Font Family" +msgstr "Шрифт" + +#: lib/choose_font.tcl:76 +msgid "Font Size" +msgstr "Размер" + +#: lib/choose_font.tcl:93 +msgid "Font Example" +msgstr "Мостра" + +#: lib/choose_font.tcl:105 msgid "" -"Cannot amend while merging.\n" -"\n" -"You are currently in the middle of a merge that has not been fully " -"completed. You cannot amend the prior commit unless you first abort the " -"current merge activity.\n" +"This is example text.\n" +"If you like this text, it can be your font." msgstr "" -"По време на сливане не може да поправяте.\n" -"\n" -"В момента все още не сте завършили операция по сливане. Не може да поправите " -"предишното подаване, освен ако първо не преустановите текущото сливане.\n" +"Това е примерен текст.\n" +"Ако ви харесва как изглежда, изберете шрифта." -#: lib/commit.tcl:48 -msgid "Error loading commit data for amend:" -msgstr "Грешка при зареждане на данните от подаване, които да се поправят:" +#: lib/option.tcl:11 +#, tcl-format +msgid "Invalid global encoding '%s'" +msgstr "Неправилно глобално кодиране „%s“" -#: lib/commit.tcl:75 -msgid "Unable to obtain your identity:" -msgstr "Идентификацията ви не може да бъде определена:" +#: lib/option.tcl:19 +#, tcl-format +msgid "Invalid repo encoding '%s'" +msgstr "Неправилно кодиране „%s“ на хранилището" -#: lib/commit.tcl:80 -msgid "Invalid GIT_COMMITTER_IDENT:" -msgstr "Неправилно поле „GIT_COMMITTER_IDENT“:" +#: lib/option.tcl:119 +msgid "Restore Defaults" +msgstr "Стандартни настройки" -#: lib/commit.tcl:129 +#: lib/option.tcl:123 +msgid "Save" +msgstr "Запазване" + +#: lib/option.tcl:133 #, tcl-format -msgid "warning: Tcl does not support encoding '%s'." -msgstr "предупреждение: Tcl не поддържа кодирането „%s“." +msgid "%s Repository" +msgstr "Хранилище „%s“" -#: lib/commit.tcl:149 -msgid "" -"Last scanned state does not match repository state.\n" -"\n" -"Another Git program has modified this repository since the last scan. A " -"rescan must be performed before another commit can be created.\n" -"\n" -"The rescan will be automatically started now.\n" -msgstr "" -"Състоянието при последната проверка не отговаря на състоянието на " -"хранилището.\n" -"\n" -"Някой друг процес за Git е променил хранилището междувременно. Състоянието " -"трябва да бъде проверено преди ново подаване.\n" -"\n" -"Автоматично ще започне нова проверка.\n" +#: lib/option.tcl:134 +msgid "Global (All Repositories)" +msgstr "Глобално (за всички хранилища)" + +#: lib/option.tcl:140 +msgid "User Name" +msgstr "Потребителско име" + +#: lib/option.tcl:141 +msgid "Email Address" +msgstr "Адрес на е-поща" + +#: lib/option.tcl:143 +msgid "Summarize Merge Commits" +msgstr "Обобщаване на подаванията при сливане" + +#: lib/option.tcl:144 +msgid "Merge Verbosity" +msgstr "Подробности при сливанията" + +#: lib/option.tcl:145 +msgid "Show Diffstat After Merge" +msgstr "Извеждане на статистика след сливанията" + +#: lib/option.tcl:146 +msgid "Use Merge Tool" +msgstr "Използване на програма за сливане" + +#: lib/option.tcl:148 +msgid "Trust File Modification Timestamps" +msgstr "Доверие във времето на промяна на файловете" + +#: lib/option.tcl:149 +msgid "Prune Tracking Branches During Fetch" +msgstr "Окастряне на следящите клонове при доставяне" + +#: lib/option.tcl:150 +msgid "Match Tracking Branches" +msgstr "Напасване на следящите клонове" + +#: lib/option.tcl:151 +msgid "Use Textconv For Diffs and Blames" +msgstr "Използване на „textconv“ за разликите и анотирането" + +#: lib/option.tcl:152 +msgid "Blame Copy Only On Changed Files" +msgstr "Анотиране на копието само по променените файлове" + +#: lib/option.tcl:153 +msgid "Maximum Length of Recent Repositories List" +msgstr "Максимален брой на списъка „Скоро ползвани“ хранилища" + +#: lib/option.tcl:154 +msgid "Minimum Letters To Blame Copy On" +msgstr "Минимален брой знаци за анотиране на копието" + +#: lib/option.tcl:155 +msgid "Blame History Context Radius (days)" +msgstr "Исторически обхват за анотиране в дни" + +#: lib/option.tcl:156 +msgid "Number of Diff Context Lines" +msgstr "Брой редове за контекста на разликите" + +#: lib/option.tcl:157 +msgid "Additional Diff Parameters" +msgstr "Аргументи към командата за разликите" + +#: lib/option.tcl:158 +msgid "Commit Message Text Width" +msgstr "Широчина на текста на съобщението при подаване" + +#: lib/option.tcl:159 +msgid "New Branch Name Template" +msgstr "Шаблон за името на новите клони" + +#: lib/option.tcl:160 +msgid "Default File Contents Encoding" +msgstr "Кодиране на файловете" + +#: lib/option.tcl:161 +msgid "Warn before committing to a detached head" +msgstr "Предупреждаване при подаване към несвързан указател" -#: lib/commit.tcl:173 +#: lib/option.tcl:162 +msgid "Staging of untracked files" +msgstr "Добавяне на неследените файлове към индекса" + +#: lib/option.tcl:163 +msgid "Show untracked files" +msgstr "Показване на неследените файлове" + +#: lib/option.tcl:164 +msgid "Tab spacing" +msgstr "Ширина на табулацията" + +#: lib/option.tcl:182 lib/option.tcl:197 lib/option.tcl:220 lib/option.tcl:282 +#: lib/database.tcl:57 #, tcl-format -msgid "" -"Unmerged files cannot be committed.\n" -"\n" -"File %s has merge conflicts. You must resolve them and stage the file " -"before committing.\n" -msgstr "" -"Неслетите файлове не могат да бъдат подавани.\n" -"\n" -"Във файла „%s“ има конфликти при сливане. За да го подадете, трябва първо да " -"коригирате конфликтите и да добавите файла към индекса за подаване.\n" +msgid "%s:" +msgstr "%s:" + +#: lib/option.tcl:210 +msgid "Change" +msgstr "Смяна" + +#: lib/option.tcl:254 +msgid "Spelling Dictionary:" +msgstr "Правописен речник:" + +#: lib/option.tcl:284 +msgid "Change Font" +msgstr "Смяна на шрифта" -#: lib/commit.tcl:181 +#: lib/option.tcl:288 #, tcl-format -msgid "" -"Unknown file state %s detected.\n" -"\n" -"File %s cannot be committed by this program.\n" -msgstr "" -"Непознато състояние на файл „%s“.\n" -"\n" -"Файлът „%s“ не може да бъде подаден чрез текущата програма.\n" +msgid "Choose %s" +msgstr "Избор на „%s“" -#: lib/commit.tcl:189 -msgid "" -"No changes to commit.\n" -"\n" -"You must stage at least 1 file before you can commit.\n" -msgstr "" -"Няма промени за подаване.\n" -"\n" -"Трябва да добавите поне един файл към индекса, за да подадете.\n" +#: lib/option.tcl:294 +msgid "pt." +msgstr "тчк." + +#: lib/option.tcl:308 +msgid "Preferences" +msgstr "Настройки" + +#: lib/option.tcl:345 +msgid "Failed to completely save options:" +msgstr "Неуспешно запазване на настройките:" + +#: lib/encoding.tcl:443 +msgid "Default" +msgstr "Стандартното" + +#: lib/encoding.tcl:448 +#, tcl-format +msgid "System (%s)" +msgstr "Системното (%s)" + +#: lib/encoding.tcl:459 lib/encoding.tcl:465 +msgid "Other" +msgstr "Друго" + +#: lib/tools.tcl:76 +#, tcl-format +msgid "Running %s requires a selected file." +msgstr "За изпълнението на „%s“ трябва да изберете файл." + +#: lib/tools.tcl:92 +#, tcl-format +msgid "Are you sure you want to run %1$s on file \"%2$s\"?" +msgstr "Сигурни ли сте, че искате да изпълните „%1$s“ върху файла „%2$s“?" + +#: lib/tools.tcl:96 +#, tcl-format +msgid "Are you sure you want to run %s?" +msgstr "Сигурни ли сте, че искате да изпълните „%s“?" + +#: lib/tools.tcl:118 +#, tcl-format +msgid "Tool: %s" +msgstr "Команда: %s" + +#: lib/tools.tcl:119 +#, tcl-format +msgid "Running: %s" +msgstr "Изпълнение: %s" + +#: lib/tools.tcl:158 +#, tcl-format +msgid "Tool completed successfully: %s" +msgstr "Командата завърши успешно: %s" + +#: lib/tools.tcl:160 +#, tcl-format +msgid "Tool failed: %s" +msgstr "Командата върна грешка: %s" + +#: lib/mergetool.tcl:8 +msgid "Force resolution to the base version?" +msgstr "Да се използва базовата версия" + +#: lib/mergetool.tcl:9 +msgid "Force resolution to this branch?" +msgstr "Да се използва версията от този клон" + +#: lib/mergetool.tcl:10 +msgid "Force resolution to the other branch?" +msgstr "Да се използва версията от другия клон" -#: lib/commit.tcl:204 +#: lib/mergetool.tcl:14 +#, tcl-format msgid "" -"Please supply a commit message.\n" +"Note that the diff shows only conflicting changes.\n" "\n" -"A good commit message has the following format:\n" +"%s will be overwritten.\n" "\n" -"- First line: Describe in one sentence what you did.\n" -"- Second line: Blank\n" -"- Remaining lines: Describe why this change is good.\n" +"This operation can be undone only by restarting the merge." msgstr "" -"Задайте добро съобщение при подаване.\n" +"Разликата показва само разликите с конфликт.\n" "\n" -"Използвайте следния формат:\n" +"Файлът „%s“ ще се презапише.\n" "\n" -"● Първи ред: описание в едно изречение на промяната.\n" -"● Втори ред: празен.\n" -"● Останалите редове: опишете защо се налага тази промяна.\n" - -#: lib/commit.tcl:235 -msgid "Calling pre-commit hook..." -msgstr "Изпълняване на куката преди подаване…" - -#: lib/commit.tcl:250 -msgid "Commit declined by pre-commit hook." -msgstr "Подаването е отхвърлено от куката преди подаване." +"Тази операция може да се отмени само чрез започване на сливането наново." -#: lib/commit.tcl:269 -msgid "" -"You are about to commit on a detached head. This is a potentially dangerous " -"thing to do because if you switch to another branch you will lose your " -"changes and it can be difficult to retrieve them later from the reflog. You " -"should probably cancel this commit and create a new branch to continue.\n" -" \n" -" Do you really want to proceed with your Commit?" +#: lib/mergetool.tcl:45 +#, tcl-format +msgid "File %s seems to have unresolved conflicts, still stage?" msgstr "" -"Ще подадете към несвързан, отделѐн указател „HEAD“. Това е опасно, защото " -"при преминаването към клон ще загубите промените си, като единственият начин " -"да ги върнете ще е чрез журнала на указателите (reflog). Най-вероятно трябва " -"да не правите това подаване, а да създадете нов клон, преди да продължите.\n" -" \n" -"Сигурни ли сте, че искате да извършите текущото подаване?" +"Изглежда, че все още има некоригирани конфликти във файла „%s“. Да се добави " +"ли файлът към индекса?" -#: lib/commit.tcl:290 -msgid "Calling commit-msg hook..." -msgstr "Изпълняване на куката за съобщението при подаване…" +#: lib/mergetool.tcl:60 +#, tcl-format +msgid "Adding resolution for %s" +msgstr "Добавяне на корекция на конфликтите в „%s“" -#: lib/commit.tcl:305 -msgid "Commit declined by commit-msg hook." -msgstr "Подаването е отхвърлено от куката за съобщението при подаване." +#: lib/mergetool.tcl:141 +msgid "Cannot resolve deletion or link conflicts using a tool" +msgstr "" +"Конфликтите при символни връзки или изтриване не може да се коригират с " +"външна програма." -#: lib/commit.tcl:318 -msgid "Committing changes..." -msgstr "Подаване на промените…" +#: lib/mergetool.tcl:146 +msgid "Conflict file does not exist" +msgstr "Файлът, в който е конфликтът, не съществува" -#: lib/commit.tcl:334 -msgid "write-tree failed:" -msgstr "неуспешно запазване на дървото (write-tree):" +#: lib/mergetool.tcl:246 +#, tcl-format +msgid "Not a GUI merge tool: '%s'" +msgstr "Това не е графична програма за сливане: „%s“" -#: lib/commit.tcl:335 lib/commit.tcl:382 lib/commit.tcl:403 -msgid "Commit failed." -msgstr "Неуспешно подаване." +#: lib/mergetool.tcl:275 +#, tcl-format +msgid "Unsupported merge tool '%s'" +msgstr "Неподдържана програма за сливане: „%s“" + +#: lib/mergetool.tcl:310 +msgid "Merge tool is already running, terminate it?" +msgstr "Програмата за сливане вече е стартирана. Да се изключи ли?" -#: lib/commit.tcl:352 +#: lib/mergetool.tcl:330 #, tcl-format -msgid "Commit %s appears to be corrupt" -msgstr "Подаването „%s“ изглежда повредено" +msgid "" +"Error retrieving versions:\n" +"%s" +msgstr "" +"Грешка при изтеглянето на версии:\n" +"%s" -#: lib/commit.tcl:357 +#: lib/mergetool.tcl:350 +#, tcl-format msgid "" -"No changes to commit.\n" -"\n" -"No files were modified by this commit and it was not a merge commit.\n" +"Could not start the merge tool:\n" "\n" -"A rescan will be automatically started now.\n" +"%s" msgstr "" -"Няма промени за подаване.\n" +"Програмата за сливане не може да се стартира:\n" "\n" -"В това подаване не са променяни никакви файлове, а и не е подаване със " -"сливане.\n" -"\n" -"Автоматично ще започне нова проверка.\n" - -#: lib/commit.tcl:364 -msgid "No changes to commit." -msgstr "Няма промени за подаване." +"%s" -#: lib/commit.tcl:381 -msgid "commit-tree failed:" -msgstr "неуспешно подаване на дървото (commit-tree):" +#: lib/mergetool.tcl:354 +msgid "Running merge tool..." +msgstr "Стартиране на програмата за сливане…" -#: lib/commit.tcl:402 -msgid "update-ref failed:" -msgstr "неуспешно обновяване на указателите (update-ref):" +#: lib/mergetool.tcl:382 lib/mergetool.tcl:390 +msgid "Merge tool failed." +msgstr "Грешка в програмата за сливане." -#: lib/commit.tcl:495 +#: lib/tools_dlg.tcl:22 #, tcl-format -msgid "Created commit %s: %s" -msgstr "Успешно подаване %s: %s" +msgid "%s (%s): Add Tool" +msgstr "%s (%s): Добавяне на команда" -#: lib/console.tcl:59 -msgid "Working... please wait..." -msgstr "В момента се извършва действие, изчакайте…" +#: lib/tools_dlg.tcl:28 +msgid "Add New Tool Command" +msgstr "Добавяне на команда" -#: lib/console.tcl:186 -msgid "Success" -msgstr "Успех" +#: lib/tools_dlg.tcl:34 +msgid "Add globally" +msgstr "Глобално добавяне" -#: lib/console.tcl:200 -msgid "Error: Command Failed" -msgstr "Грешка: неуспешно изпълнение на команда" +#: lib/tools_dlg.tcl:46 +msgid "Tool Details" +msgstr "Подробности за командата" -#: lib/database.tcl:42 -msgid "Number of loose objects" -msgstr "Брой непакетирани обекти" +#: lib/tools_dlg.tcl:49 +msgid "Use '/' separators to create a submenu tree:" +msgstr "За създаване на подменюта използвайте знака „/“ за разделител:" -#: lib/database.tcl:43 -msgid "Disk space used by loose objects" -msgstr "Дисково пространство заето от непакетирани обекти" +#: lib/tools_dlg.tcl:60 +msgid "Command:" +msgstr "Команда:" -#: lib/database.tcl:44 -msgid "Number of packed objects" -msgstr "Брой пакетирани обекти" +#: lib/tools_dlg.tcl:71 +msgid "Show a dialog before running" +msgstr "Преди изпълнение да се извежда диалогов прозорец" -#: lib/database.tcl:45 -msgid "Number of packs" -msgstr "Брой пакети" +#: lib/tools_dlg.tcl:77 +msgid "Ask the user to select a revision (sets $REVISION)" +msgstr "Потребителят да укаже версия (задаване на променливата $REVISION)" -#: lib/database.tcl:46 -msgid "Disk space used by packed objects" -msgstr "Дисково пространство заето от пакетирани обекти" +#: lib/tools_dlg.tcl:82 +msgid "Ask the user for additional arguments (sets $ARGS)" +msgstr "" +"Потребителят да укаже допълнителни аргументи (задаване на променливата $ARGS)" -#: lib/database.tcl:47 -msgid "Packed objects waiting for pruning" -msgstr "Пакетирани обекти за окастряне" +#: lib/tools_dlg.tcl:89 +msgid "Don't show the command output window" +msgstr "Без показване на прозорец с изхода от командата" -#: lib/database.tcl:48 -msgid "Garbage files" -msgstr "Файлове за боклука" +#: lib/tools_dlg.tcl:94 +msgid "Run only if a diff is selected ($FILENAME not empty)" +msgstr "" +"Стартиране само след избор на разлика (променливата $FILENAME не е празна)" -#: lib/database.tcl:57 lib/option.tcl:182 lib/option.tcl:197 lib/option.tcl:220 -#: lib/option.tcl:282 -#, tcl-format -msgid "%s:" -msgstr "%s:" +#: lib/tools_dlg.tcl:118 +msgid "Please supply a name for the tool." +msgstr "Задайте име за командата." -#: lib/database.tcl:66 +#: lib/tools_dlg.tcl:126 #, tcl-format -msgid "%s (%s): Database Statistics" -msgstr "%s (%s): Статистика на базата от данни" - -#: lib/database.tcl:72 -msgid "Compressing the object database" -msgstr "Компресиране на базата с данни за обектите" - -#: lib/database.tcl:83 -msgid "Verifying the object database with fsck-objects" -msgstr "Проверка на базата с данни за обектите с програмата „fsck-objects“" +msgid "Tool '%s' already exists." +msgstr "Командата „%s“ вече съществува." -#: lib/database.tcl:107 +#: lib/tools_dlg.tcl:148 #, tcl-format msgid "" -"This repository currently has approximately %i loose objects.\n" -"\n" -"To maintain optimal performance it is strongly recommended that you compress " -"the database.\n" -"\n" -"Compress the database now?" +"Could not add tool:\n" +"%s" msgstr "" -"В това хранилище в момента има към %i непакетирани обекти.\n" -"\n" -"За добра производителност се препоръчва да компресирате базата с данни за " -"обектите.\n" -"\n" -"Да се започне ли компресирането?" +"Командата не може да се добави:\n" +"%s" -#: lib/date.tcl:25 +#: lib/tools_dlg.tcl:187 #, tcl-format -msgid "Invalid date from Git: %s" -msgstr "Неправилни данни от Git: %s" +msgid "%s (%s): Remove Tool" +msgstr "%s (%s): Премахване на команда" -#: lib/diff.tcl:77 +#: lib/tools_dlg.tcl:193 +msgid "Remove Tool Commands" +msgstr "Премахване на команди" + +#: lib/tools_dlg.tcl:198 +msgid "Remove" +msgstr "Премахване" + +#: lib/tools_dlg.tcl:231 +msgid "(Blue denotes repository-local tools)" +msgstr "(командите към локалното хранилище са обозначени в синьо)" + +#: lib/tools_dlg.tcl:283 #, tcl-format -msgid "" -"No differences detected.\n" -"\n" -"%s has no changes.\n" -"\n" -"The modification date of this file was updated by another application, but " -"the content within the file was not changed.\n" -"\n" -"A rescan will be automatically started to find other files which may have " -"the same state." -msgstr "" -"Не са открити разлики.\n" -"\n" -"Няма промени в „%s“.\n" -"\n" -"Времето на промяна на файла е бил зададен от друга програма, но съдържанието " -"му не е променено.\n" -"\n" -"Автоматично ще започне нова проверка дали няма други файлове в това " -"състояние." +msgid "%s (%s):" +msgstr "%s (%s):" -#: lib/diff.tcl:117 +#: lib/tools_dlg.tcl:292 #, tcl-format -msgid "Loading diff of %s..." -msgstr "Зареждане на разликите в „%s“…" +msgid "Run Command: %s" +msgstr "Изпълнение на командата „%s“" -#: lib/diff.tcl:143 -msgid "" -"LOCAL: deleted\n" -"REMOTE:\n" -msgstr "" -"ЛОКАЛНО: изтрит\n" -"ОТДАЛЕЧЕНО:\n" +#: lib/tools_dlg.tcl:306 +msgid "Arguments" +msgstr "Аргументи" -#: lib/diff.tcl:148 -msgid "" -"REMOTE: deleted\n" -"LOCAL:\n" -msgstr "" -"ОТДАЛЕЧЕНО: изтрит\n" -"ЛОКАЛНО:\n" +#: lib/tools_dlg.tcl:341 +msgid "OK" +msgstr "Добре" + +#: lib/search.tcl:48 +msgid "Find:" +msgstr "Търсене:" + +#: lib/search.tcl:50 +msgid "Next" +msgstr "Следваща поява" + +#: lib/search.tcl:51 +msgid "Prev" +msgstr "Предишна поява" + +#: lib/search.tcl:52 +msgid "RegExp" +msgstr "РегИзр" + +#: lib/search.tcl:54 +msgid "Case" +msgstr "Главни/Малки" + +#: lib/shortcut.tcl:8 lib/shortcut.tcl:43 lib/shortcut.tcl:75 +#, tcl-format +msgid "%s (%s): Create Desktop Icon" +msgstr "%s (%s): Добавяне на икона на работния плот" -#: lib/diff.tcl:155 -msgid "LOCAL:\n" -msgstr "ЛОКАЛНО:\n" +#: lib/shortcut.tcl:24 lib/shortcut.tcl:65 +msgid "Cannot write shortcut:" +msgstr "Клавишната комбинация не може да се запази:" -#: lib/diff.tcl:158 -msgid "REMOTE:\n" -msgstr "ОТДАЛЕЧЕНО:\n" +#: lib/shortcut.tcl:140 +msgid "Cannot write icon:" +msgstr "Иконата не може да се запази:" -#: lib/diff.tcl:220 lib/diff.tcl:357 +#: lib/remote_branch_delete.tcl:29 #, tcl-format -msgid "Unable to display %s" -msgstr "Файлът „%s“ не може да бъде показан" +msgid "%s (%s): Delete Branch Remotely" +msgstr "%s (%s): Изтриване на отдалечения клон" -#: lib/diff.tcl:221 -msgid "Error loading file:" -msgstr "Грешка при зареждане на файл:" +#: lib/remote_branch_delete.tcl:34 +msgid "Delete Branch Remotely" +msgstr "Изтриване на отдалечения клон" -#: lib/diff.tcl:227 -msgid "Git Repository (subproject)" -msgstr "Хранилище на Git (подмодул)" +#: lib/remote_branch_delete.tcl:48 +msgid "From Repository" +msgstr "От хранилище" -#: lib/diff.tcl:239 -msgid "* Binary file (not showing content)." -msgstr "● Двоичен файл (съдържанието не се показва)." +#: lib/remote_branch_delete.tcl:88 +msgid "Branches" +msgstr "Клони" -#: lib/diff.tcl:244 -#, tcl-format -msgid "" -"* Untracked file is %d bytes.\n" -"* Showing only first %d bytes.\n" -msgstr "" -"● Неследеният файл е %d байта.\n" -"● Показват се само първите %d байта.\n" +#: lib/remote_branch_delete.tcl:110 +msgid "Delete Only If" +msgstr "Изтриване, само ако" -#: lib/diff.tcl:250 +#: lib/remote_branch_delete.tcl:112 +msgid "Merged Into:" +msgstr "Слят в:" + +#: lib/remote_branch_delete.tcl:120 lib/branch_delete.tcl:53 +msgid "Always (Do not perform merge checks)" +msgstr "Винаги (без проверка за сливане)" + +#: lib/remote_branch_delete.tcl:153 +msgid "A branch is required for 'Merged Into'." +msgstr "За данните „Слят в“ е необходимо да зададете клон." + +#: lib/remote_branch_delete.tcl:185 #, tcl-format msgid "" +"The following branches are not completely merged into %s:\n" "\n" -"* Untracked file clipped here by %s.\n" -"* To see the entire file, use an external editor.\n" +" - %s" msgstr "" +"Следните клони не са слети напълно в „%s“:\n" "\n" -"● Неследеният файл е отрязан дотук от програмата „%s“.\n" -"● Използвайте външен редактор, за да видите целия файл.\n" - -#: lib/diff.tcl:580 -msgid "Failed to unstage selected hunk." -msgstr "Избраното парче не може да бъде извадено от индекса." - -#: lib/diff.tcl:587 -msgid "Failed to stage selected hunk." -msgstr "Избраното парче не може да бъде добавено към индекса." +" ● %s" -#: lib/diff.tcl:666 -msgid "Failed to unstage selected line." -msgstr "Избраният ред не може да бъде изваден от индекса." +#: lib/remote_branch_delete.tcl:190 +#, tcl-format +msgid "" +"One or more of the merge tests failed because you have not fetched the " +"necessary commits. Try fetching from %s first." +msgstr "" +"Поне една от пробите за сливане е неуспешна, защото не сте доставили всички " +"необходими подавания. Пробвайте първо да доставите подаванията от „%s“." -#: lib/diff.tcl:674 -msgid "Failed to stage selected line." -msgstr "Избраният ред не може да бъде добавен към индекса." +#: lib/remote_branch_delete.tcl:208 +msgid "Please select one or more branches to delete." +msgstr "Изберете поне един клон за изтриване." -#: lib/encoding.tcl:443 -msgid "Default" -msgstr "Стандартното" +#: lib/remote_branch_delete.tcl:218 lib/branch_delete.tcl:115 +msgid "" +"Recovering deleted branches is difficult.\n" +"\n" +"Delete the selected branches?" +msgstr "" +"Възстановяването на изтрити клони може да е трудно.\n" +"\n" +"Сигурни ли сте, че искате да триете?" -#: lib/encoding.tcl:448 +#: lib/remote_branch_delete.tcl:227 #, tcl-format -msgid "System (%s)" -msgstr "Системното (%s)" - -#: lib/encoding.tcl:459 lib/encoding.tcl:465 -msgid "Other" -msgstr "Друго" +msgid "Deleting branches from %s" +msgstr "Изтриване на клони от „%s“" -#: lib/error.tcl:20 -#, tcl-format -msgid "%s: error" -msgstr "%s: грешка" +#: lib/remote_branch_delete.tcl:300 +msgid "No repository selected." +msgstr "Не е избрано хранилище." -#: lib/error.tcl:36 +#: lib/remote_branch_delete.tcl:305 #, tcl-format -msgid "%s: warning" -msgstr "%s: предупреждение" +msgid "Scanning %s..." +msgstr "Претърсване на „%s“…" -#: lib/error.tcl:80 -#, tcl-format -msgid "%s hook failed:" -msgstr "%s: грешка от куката" +#: lib/choose_repository.tcl:45 +msgid "Git Gui" +msgstr "ГПИ на Git" -#: lib/error.tcl:96 -msgid "You must correct the above errors before committing." -msgstr "Преди да можете да подадете, коригирайте горните грешки." +#: lib/choose_repository.tcl:104 lib/choose_repository.tcl:427 +msgid "Create New Repository" +msgstr "Създаване на ново хранилище" -#: lib/error.tcl:116 -#, tcl-format -msgid "%s (%s): error" -msgstr "%s (%s): грешка" +#: lib/choose_repository.tcl:110 +msgid "New..." +msgstr "Ново…" -#: lib/index.tcl:6 -msgid "Unable to unlock the index." -msgstr "Индексът не може да бъде отключен." +#: lib/choose_repository.tcl:117 lib/choose_repository.tcl:511 +msgid "Clone Existing Repository" +msgstr "Клониране на съществуващо хранилище" -#: lib/index.tcl:17 -msgid "Index Error" -msgstr "Грешка в индекса" +#: lib/choose_repository.tcl:128 +msgid "Clone..." +msgstr "Клониране…" -#: lib/index.tcl:19 -msgid "" -"Updating the Git index failed. A rescan will be automatically started to " -"resynchronize git-gui." -msgstr "" -"Неуспешно обновяване на индекса на Git. Автоматично ще започне нова проверка " -"за синхронизирането на git-gui." +#: lib/choose_repository.tcl:135 lib/choose_repository.tcl:1105 +msgid "Open Existing Repository" +msgstr "Отваряне на съществуващо хранилище" -#: lib/index.tcl:30 -msgid "Continue" -msgstr "Продължаване" +#: lib/choose_repository.tcl:141 +msgid "Open..." +msgstr "Отваряне…" -#: lib/index.tcl:33 -msgid "Unlock Index" -msgstr "Отключване на индекса" +#: lib/choose_repository.tcl:154 +msgid "Recent Repositories" +msgstr "Скоро ползвани" -#: lib/index.tcl:294 -msgid "Unstaging selected files from commit" -msgstr "Изваждане на избраните файлове от подаването" +#: lib/choose_repository.tcl:164 +msgid "Open Recent Repository:" +msgstr "Отваряне на хранилище ползвано наскоро:" -#: lib/index.tcl:298 +#: lib/choose_repository.tcl:331 lib/choose_repository.tcl:338 +#: lib/choose_repository.tcl:345 #, tcl-format -msgid "Unstaging %s from commit" -msgstr "Изваждане на „%s“ от подаването" +msgid "Failed to create repository %s:" +msgstr "Неуспешно създаване на хранилището „%s“:" -#: lib/index.tcl:337 -msgid "Ready to commit." -msgstr "Готовност за подаване." +#: lib/choose_repository.tcl:422 lib/branch_create.tcl:33 +msgid "Create" +msgstr "Създаване" -#: lib/index.tcl:346 -msgid "Adding selected files" -msgstr "Добавяне на избраните файлове" +#: lib/choose_repository.tcl:432 +msgid "Directory:" +msgstr "Директория:" + +#: lib/choose_repository.tcl:462 lib/choose_repository.tcl:588 +#: lib/choose_repository.tcl:1139 +msgid "Git Repository" +msgstr "Хранилище на Git" -#: lib/index.tcl:350 +#: lib/choose_repository.tcl:487 #, tcl-format -msgid "Adding %s" -msgstr "Добавяне на „%s“" +msgid "Directory %s already exists." +msgstr "Вече съществува директория „%s“." -#: lib/index.tcl:380 +#: lib/choose_repository.tcl:491 #, tcl-format -msgid "Stage %d untracked files?" -msgstr "Да се добавят ли %d неследени файла към индекса?" +msgid "File %s already exists." +msgstr "Вече съществува файл „%s“." -#: lib/index.tcl:388 -msgid "Adding all changed files" -msgstr "Добавяне на всички променени файлове" +#: lib/choose_repository.tcl:506 +msgid "Clone" +msgstr "Клониране" -#: lib/index.tcl:428 -#, tcl-format -msgid "Revert changes in file %s?" -msgstr "Да се махнат ли промените във файла „%s“?" +#: lib/choose_repository.tcl:519 +msgid "Source Location:" +msgstr "Адрес на източника:" -#: lib/index.tcl:430 -#, tcl-format -msgid "Revert changes in these %i files?" -msgstr "Да се махнат ли промените в тези %i файла?" +#: lib/choose_repository.tcl:528 +msgid "Target Directory:" +msgstr "Целева директория:" -#: lib/index.tcl:438 -msgid "Any unstaged changes will be permanently lost by the revert." -msgstr "" -"Всички промени, които не са били вкарани в индекса, ще бъдат безвъзвратно " -"загубени." +#: lib/choose_repository.tcl:538 +msgid "Clone Type:" +msgstr "Вид клониране:" -#: lib/index.tcl:441 -msgid "Do Nothing" -msgstr "Нищо да не се прави" +#: lib/choose_repository.tcl:543 +msgid "Standard (Fast, Semi-Redundant, Hardlinks)" +msgstr "Стандартно (бързо, частично споделяне на файлове, твърди връзки)" -#: lib/index.tcl:459 -msgid "Reverting selected files" -msgstr "Махане на промените в избраните файлове" +#: lib/choose_repository.tcl:548 +msgid "Full Copy (Slower, Redundant Backup)" +msgstr "Пълно (бавно, пълноценно резервно копие)" -#: lib/index.tcl:463 -#, tcl-format -msgid "Reverting %s" -msgstr "Махане на промените в „%s“" +#: lib/choose_repository.tcl:553 +msgid "Shared (Fastest, Not Recommended, No Backup)" +msgstr "Споделено (най-бързо, не се препоръчва, не прави резервно копие)" -#: lib/line.tcl:17 -msgid "Goto Line:" -msgstr "Към ред:" +#: lib/choose_repository.tcl:560 +msgid "Recursively clone submodules too" +msgstr "Рекурсивно клониране и на подмодулите" -#: lib/line.tcl:23 -msgid "Go" -msgstr "Придвижване" +#: lib/choose_repository.tcl:594 lib/choose_repository.tcl:641 +#: lib/choose_repository.tcl:790 lib/choose_repository.tcl:864 +#: lib/choose_repository.tcl:1145 lib/choose_repository.tcl:1153 +#, tcl-format +msgid "Not a Git repository: %s" +msgstr "Това не е хранилище на Git: %s" -#: lib/merge.tcl:13 -msgid "" -"Cannot merge while amending.\n" -"\n" -"You must finish amending this commit before starting any type of merge.\n" -msgstr "" -"По време на поправяне не може да сливане.\n" -"\n" -"Трябва да завършите поправянето на текущото подаване, преди да започнете " -"сливане.\n" +#: lib/choose_repository.tcl:630 +msgid "Standard only available for local repository." +msgstr "Само локални хранилища може да се клонират стандартно" -#: lib/merge.tcl:27 -msgid "" -"Last scanned state does not match repository state.\n" -"\n" -"Another Git program has modified this repository since the last scan. A " -"rescan must be performed before a merge can be performed.\n" -"\n" -"The rescan will be automatically started now.\n" -msgstr "" -"Последно установеното състояние не отговаря на това в хранилището.\n" -"\n" -"Някой друг процес за Git е променил хранилището междувременно. Състоянието " -"трябва да бъде проверено, преди да се извърши сливане.\n" -"\n" -"Автоматично ще започне нова проверка.\n" -"\n" +#: lib/choose_repository.tcl:634 +msgid "Shared only available for local repository." +msgstr "Само локални хранилища може да се клонират споделено" -#: lib/merge.tcl:45 +#: lib/choose_repository.tcl:655 #, tcl-format -msgid "" -"You are in the middle of a conflicted merge.\n" -"\n" -"File %s has merge conflicts.\n" -"\n" -"You must resolve them, stage the file, and commit to complete the current " -"merge. Only then can you begin another merge.\n" -msgstr "" -"В момента тече сливане, но има конфликти.\n" -"\n" -"Погледнете файла „%s“.\n" -"\n" -"Трябва да коригирате конфликтите в него, да го добавите към индекса и да " -"завършите текущото сливане чрез подаване. Чак тогава може да започнете ново " -"сливане.\n" +msgid "Location %s already exists." +msgstr "Местоположението „%s“ вече съществува." -#: lib/merge.tcl:55 -#, tcl-format -msgid "" -"You are in the middle of a change.\n" -"\n" -"File %s is modified.\n" -"\n" -"You should complete the current commit before starting a merge. Doing so " -"will help you abort a failed merge, should the need arise.\n" -msgstr "" -"В момента тече подаване.\n" -"\n" -"Файлът „%s“ е променен.\n" -"\n" -"Трябва да завършите текущото подаване, преди да започнете сливане. Така ще " -"можете лесно да преустановите сливането, ако възникне нужда.\n" +#: lib/choose_repository.tcl:666 +msgid "Failed to configure origin" +msgstr "Неуспешно настройване на хранилището-източник" -#: lib/merge.tcl:108 +#: lib/choose_repository.tcl:678 +msgid "Counting objects" +msgstr "Преброяване на обекти" + +#: lib/choose_repository.tcl:679 +msgid "buckets" +msgstr "клетки" + +#: lib/choose_repository.tcl:703 #, tcl-format -msgid "%s of %s" -msgstr "%s от общо %s" +msgid "Unable to copy objects/info/alternates: %s" +msgstr "Обектите/Информацията/Синонимите не може да се копират: %s" -#: lib/merge.tcl:126 +#: lib/choose_repository.tcl:740 #, tcl-format -msgid "Merging %s and %s..." -msgstr "Сливане на „%s“ и „%s“…" +msgid "Nothing to clone from %s." +msgstr "Няма какво да се клонира от „%s“." -#: lib/merge.tcl:137 -msgid "Merge completed successfully." -msgstr "Сливането завърши успешно." +#: lib/choose_repository.tcl:742 lib/choose_repository.tcl:962 +#: lib/choose_repository.tcl:974 +msgid "The 'master' branch has not been initialized." +msgstr "Основният клон — „master“ не е инициализиран." -#: lib/merge.tcl:139 -msgid "Merge failed. Conflict resolution is required." -msgstr "Неуспешно сливане — има конфликти за коригиране." +#: lib/choose_repository.tcl:755 +msgid "Hardlinks are unavailable. Falling back to copying." +msgstr "Не се поддържат твърди връзки. Преминава се към копиране." -#: lib/merge.tcl:156 +#: lib/choose_repository.tcl:769 #, tcl-format -msgid "%s (%s): Merge" -msgstr "%s (%s): Сливане" +msgid "Cloning from %s" +msgstr "Клониране на „%s“" -#: lib/merge.tcl:164 +#: lib/choose_repository.tcl:800 +msgid "Copying objects" +msgstr "Копиране на обекти" + +#: lib/choose_repository.tcl:801 +msgid "KiB" +msgstr "KiB" + +#: lib/choose_repository.tcl:825 #, tcl-format -msgid "Merge Into %s" -msgstr "Сливане в „%s“" +msgid "Unable to copy object: %s" +msgstr "Неуспешно копиране на обект: %s" -#: lib/merge.tcl:183 -msgid "Revision To Merge" -msgstr "Версия за сливане" +#: lib/choose_repository.tcl:837 +msgid "Linking objects" +msgstr "Създаване на връзки към обектите" -#: lib/merge.tcl:218 -msgid "" -"Cannot abort while amending.\n" -"\n" -"You must finish amending this commit.\n" +#: lib/choose_repository.tcl:838 +msgid "objects" +msgstr "обекти" + +#: lib/choose_repository.tcl:846 +#, tcl-format +msgid "Unable to hardlink object: %s" +msgstr "Неуспешно създаване на твърда връзка към обект: %s" + +#: lib/choose_repository.tcl:903 +msgid "Cannot fetch branches and objects. See console output for details." msgstr "" -"Поправянето не може да бъде преустановено.\n" -"\n" -"Трябва да завършите поправката на това подаване.\n" +"Клоните и обектите не може да се изтеглят. За повече информация погледнете " +"изхода на конзолата." -#: lib/merge.tcl:228 -msgid "" -"Abort merge?\n" -"\n" -"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n" -"\n" -"Continue with aborting the current merge?" +#: lib/choose_repository.tcl:914 +msgid "Cannot fetch tags. See console output for details." msgstr "" -"Да се преустанови ли сливането?\n" -"\n" -"В такъв случай ●ВСИЧКИ● неподадени промени ще бъдат безвъзвратно загубени.\n" -"\n" -"Наистина ли да се преустанови сливането?" +"Етикетите не може да се изтеглят. За повече информация погледнете изхода на " +"конзолата." -#: lib/merge.tcl:234 -msgid "" -"Reset changes?\n" -"\n" -"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n" -"\n" -"Continue with resetting the current changes?" +#: lib/choose_repository.tcl:938 +msgid "Cannot determine HEAD. See console output for details." msgstr "" -"Да се занулят ли промените?\n" -"\n" -"В такъв случай ●ВСИЧКИ● неподадени промени ще бъдат безвъзвратно загубени.\n" -"\n" -"Наистина ли да се занулят промените?" +"Върхът „HEAD“ не може да се определи. За повече информация погледнете изхода " +"на конзолата." -#: lib/merge.tcl:245 -msgid "Aborting" -msgstr "Преустановяване" +#: lib/choose_repository.tcl:947 +#, tcl-format +msgid "Unable to cleanup %s" +msgstr "„%s“ не може да се изчисти" -#: lib/merge.tcl:245 -msgid "files reset" -msgstr "файла със занулени промени" +#: lib/choose_repository.tcl:953 +msgid "Clone failed." +msgstr "Неуспешно клониране." -#: lib/merge.tcl:273 -msgid "Abort failed." -msgstr "Неуспешно преустановяване." +#: lib/choose_repository.tcl:960 +msgid "No default branch obtained." +msgstr "Не е получен клон по подразбиране." -#: lib/merge.tcl:275 -msgid "Abort completed. Ready." -msgstr "Успешно преустановяване. Готовност за следващо действие." +#: lib/choose_repository.tcl:971 +#, tcl-format +msgid "Cannot resolve %s as a commit." +msgstr "Няма подаване отговарящо на „%s“." -#: lib/mergetool.tcl:8 -msgid "Force resolution to the base version?" -msgstr "Да се използва базовата версия" +#: lib/choose_repository.tcl:998 +msgid "Creating working directory" +msgstr "Създаване на работната директория" -#: lib/mergetool.tcl:9 -msgid "Force resolution to this branch?" -msgstr "Да се използва версията от този клон" +#: lib/choose_repository.tcl:1028 +msgid "Initial file checkout failed." +msgstr "Неуспешно първоначално изтегляне." -#: lib/mergetool.tcl:10 -msgid "Force resolution to the other branch?" -msgstr "Да се използва версията от другия клон" +#: lib/choose_repository.tcl:1072 +msgid "Cloning submodules" +msgstr "Клониране на подмодули" -#: lib/mergetool.tcl:14 -#, tcl-format -msgid "" -"Note that the diff shows only conflicting changes.\n" -"\n" -"%s will be overwritten.\n" -"\n" -"This operation can be undone only by restarting the merge." -msgstr "" -"Разликата показва само разликите с конфликт.\n" -"\n" -"Файлът „%s“ ще бъде презаписан.\n" -"\n" -"Тази операция може да бъде отменена само чрез започване на сливането наново." +#: lib/choose_repository.tcl:1087 +msgid "Cannot clone submodules." +msgstr "Подмодулите не може да се клонират." -#: lib/mergetool.tcl:45 +#: lib/choose_repository.tcl:1110 +msgid "Repository:" +msgstr "Хранилище:" + +#: lib/choose_repository.tcl:1159 #, tcl-format -msgid "File %s seems to have unresolved conflicts, still stage?" -msgstr "" -"Изглежда, че все още има некоригирани конфликти във файла „%s“. Да се добави " -"ли файлът към индекса?" +msgid "Failed to open repository %s:" +msgstr "Неуспешно отваряне на хранилището „%s“:" -#: lib/mergetool.tcl:60 +#: lib/about.tcl:26 +msgid "git-gui - a graphical user interface for Git." +msgstr "git-gui — графичен интерфейс за Git." + +#: lib/blame.tcl:74 #, tcl-format -msgid "Adding resolution for %s" -msgstr "Добавяне на корекция на конфликтите в „%s“" +msgid "%s (%s): File Viewer" +msgstr "%s (%s): Преглед на файлове" -#: lib/mergetool.tcl:141 -msgid "Cannot resolve deletion or link conflicts using a tool" -msgstr "" -"Конфликтите при символни връзки или изтриване не могат да бъдат коригирани с " -"външна програма." +#: lib/blame.tcl:80 +msgid "Commit:" +msgstr "Подаване:" -#: lib/mergetool.tcl:146 -msgid "Conflict file does not exist" -msgstr "Файлът, в който е конфликтът, не съществува" +#: lib/blame.tcl:282 +msgid "Copy Commit" +msgstr "Копиране на подаване" -#: lib/mergetool.tcl:246 -#, tcl-format -msgid "Not a GUI merge tool: '%s'" -msgstr "Това не е графична програма за сливане: „%s“" +#: lib/blame.tcl:286 +msgid "Find Text..." +msgstr "Търсене на текст…" -#: lib/mergetool.tcl:275 -#, tcl-format -msgid "Unsupported merge tool '%s'" -msgstr "Неподдържана програма за сливане: „%s“" +#: lib/blame.tcl:290 +msgid "Goto Line..." +msgstr "Към ред…" -#: lib/mergetool.tcl:310 -msgid "Merge tool is already running, terminate it?" -msgstr "Програмата за сливане вече е стартирана. Да бъде ли изключена?" +#: lib/blame.tcl:299 +msgid "Do Full Copy Detection" +msgstr "Пълно търсене на копиране" -#: lib/mergetool.tcl:330 -#, tcl-format -msgid "" -"Error retrieving versions:\n" -"%s" -msgstr "" -"Грешка при изтеглянето на версии:\n" -"%s" +#: lib/blame.tcl:303 +msgid "Show History Context" +msgstr "Показване на контекста от историята" -#: lib/mergetool.tcl:350 +#: lib/blame.tcl:306 +msgid "Blame Parent Commit" +msgstr "Анотиране на родителското подаване" + +#: lib/blame.tcl:468 #, tcl-format -msgid "" -"Could not start the merge tool:\n" -"\n" -"%s" -msgstr "" -"Програмата за сливане не може да бъде стартирана:\n" -"\n" -"%s" +msgid "Reading %s..." +msgstr "Чете се „%s“…" -#: lib/mergetool.tcl:354 -msgid "Running merge tool..." -msgstr "Стартиране на програмата за сливане…" +#: lib/blame.tcl:596 +msgid "Loading copy/move tracking annotations..." +msgstr "Зареждане на анотациите за проследяване на копирането/преместването…" -#: lib/mergetool.tcl:382 lib/mergetool.tcl:390 -msgid "Merge tool failed." -msgstr "Грешка в програмата за сливане." +#: lib/blame.tcl:613 +msgid "lines annotated" +msgstr "реда анотирани" + +#: lib/blame.tcl:815 +msgid "Loading original location annotations..." +msgstr "Зареждане на анотациите за първоначалното местоположение…" + +#: lib/blame.tcl:818 +msgid "Annotation complete." +msgstr "Анотирането завърши." + +#: lib/blame.tcl:849 +msgid "Busy" +msgstr "Операцията не е завършила" -#: lib/option.tcl:11 -#, tcl-format -msgid "Invalid global encoding '%s'" -msgstr "Неправилно глобално кодиране „%s“" +#: lib/blame.tcl:850 +msgid "Annotation process is already running." +msgstr "В момента тече процес на анотиране." -#: lib/option.tcl:19 -#, tcl-format -msgid "Invalid repo encoding '%s'" -msgstr "Неправилно кодиране „%s“ на хранилището" +#: lib/blame.tcl:889 +msgid "Running thorough copy detection..." +msgstr "Изпълнява се цялостен процес на откриване на копиране…" -#: lib/option.tcl:119 -msgid "Restore Defaults" -msgstr "Стандартни настройки" +#: lib/blame.tcl:957 +msgid "Loading annotation..." +msgstr "Зареждане на анотации…" -#: lib/option.tcl:123 -msgid "Save" -msgstr "Запазване" +#: lib/blame.tcl:1010 +msgid "Author:" +msgstr "Автор:" -#: lib/option.tcl:133 -#, tcl-format -msgid "%s Repository" -msgstr "Хранилище „%s“" +#: lib/blame.tcl:1014 +msgid "Committer:" +msgstr "Подал:" -#: lib/option.tcl:134 -msgid "Global (All Repositories)" -msgstr "Глобално (за всички хранилища)" +#: lib/blame.tcl:1019 +msgid "Original File:" +msgstr "Първоначален файл:" -#: lib/option.tcl:140 -msgid "User Name" -msgstr "Потребителско име" +#: lib/blame.tcl:1067 +msgid "Cannot find HEAD commit:" +msgstr "Подаването за връх „HEAD“ не може да се открие:" -#: lib/option.tcl:141 -msgid "Email Address" -msgstr "Адрес на е-поща" +#: lib/blame.tcl:1122 +msgid "Cannot find parent commit:" +msgstr "Родителското подаване не може да се открие" -#: lib/option.tcl:143 -msgid "Summarize Merge Commits" -msgstr "Обобщаване на подаванията при сливане" +#: lib/blame.tcl:1137 +msgid "Unable to display parent" +msgstr "Родителят не може да се покаже" -#: lib/option.tcl:144 -msgid "Merge Verbosity" -msgstr "Подробности при сливанията" +#: lib/blame.tcl:1138 lib/diff.tcl:345 +msgid "Error loading diff:" +msgstr "Грешка при зареждане на разлика:" -#: lib/option.tcl:145 -msgid "Show Diffstat After Merge" -msgstr "Извеждане на статистика след сливанията" +#: lib/blame.tcl:1279 +msgid "Originally By:" +msgstr "Първоначално от:" -#: lib/option.tcl:146 -msgid "Use Merge Tool" -msgstr "Използване на програма за сливане" +#: lib/blame.tcl:1285 +msgid "In File:" +msgstr "Във файл:" -#: lib/option.tcl:148 -msgid "Trust File Modification Timestamps" -msgstr "Доверие във времето на промяна на файловете" +#: lib/blame.tcl:1290 +msgid "Copied Or Moved Here By:" +msgstr "Копирано или преместено тук от:" -#: lib/option.tcl:149 -msgid "Prune Tracking Branches During Fetch" -msgstr "Окастряне на следящите клонове при доставяне" +#: lib/diff.tcl:77 +#, tcl-format +msgid "" +"No differences detected.\n" +"\n" +"%s has no changes.\n" +"\n" +"The modification date of this file was updated by another application, but " +"the content within the file was not changed.\n" +"\n" +"A rescan will be automatically started to find other files which may have " +"the same state." +msgstr "" +"Не са открити разлики.\n" +"\n" +"Няма промени в „%s“.\n" +"\n" +"Времето на промяна на файла е бил зададен от друга програма, но съдържанието " +"му не е променено.\n" +"\n" +"Автоматично ще започне нова проверка дали няма други файлове в това " +"състояние." -#: lib/option.tcl:150 -msgid "Match Tracking Branches" -msgstr "Напасване на следящите клонове" +#: lib/diff.tcl:117 +#, tcl-format +msgid "Loading diff of %s..." +msgstr "Зареждане на разликите в „%s“…" -#: lib/option.tcl:151 -msgid "Use Textconv For Diffs and Blames" -msgstr "Използване на „textconv“ за разликите и анотирането" +#: lib/diff.tcl:143 +msgid "" +"LOCAL: deleted\n" +"REMOTE:\n" +msgstr "" +"ЛОКАЛНО: изтрит\n" +"ОТДАЛЕЧЕНО:\n" -#: lib/option.tcl:152 -msgid "Blame Copy Only On Changed Files" -msgstr "Анотиране на копието само по променените файлове" +#: lib/diff.tcl:148 +msgid "" +"REMOTE: deleted\n" +"LOCAL:\n" +msgstr "" +"ОТДАЛЕЧЕНО: изтрит\n" +"ЛОКАЛНО:\n" -#: lib/option.tcl:153 -msgid "Maximum Length of Recent Repositories List" -msgstr "Максимален брой на списъка „Скоро ползвани“ хранилища" +#: lib/diff.tcl:155 +msgid "LOCAL:\n" +msgstr "ЛОКАЛНО:\n" -#: lib/option.tcl:154 -msgid "Minimum Letters To Blame Copy On" -msgstr "Минимален брой знаци за анотиране на копието" +#: lib/diff.tcl:158 +msgid "REMOTE:\n" +msgstr "ОТДАЛЕЧЕНО:\n" -#: lib/option.tcl:155 -msgid "Blame History Context Radius (days)" -msgstr "Исторически обхват за анотиране в дни" +#: lib/diff.tcl:220 lib/diff.tcl:344 +#, tcl-format +msgid "Unable to display %s" +msgstr "Файлът „%s“ не може да се покаже" -#: lib/option.tcl:156 -msgid "Number of Diff Context Lines" -msgstr "Брой редове за контекста на разликите" +#: lib/diff.tcl:221 +msgid "Error loading file:" +msgstr "Грешка при зареждане на файл:" -#: lib/option.tcl:157 -msgid "Additional Diff Parameters" -msgstr "Аргументи към командата за разликите" +#: lib/diff.tcl:227 +msgid "Git Repository (subproject)" +msgstr "Хранилище на Git (подмодул)" -#: lib/option.tcl:158 -msgid "Commit Message Text Width" -msgstr "Широчина на текста на съобщението при подаване" +#: lib/diff.tcl:239 +msgid "* Binary file (not showing content)." +msgstr "● Двоичен файл (съдържанието не се показва)." -#: lib/option.tcl:159 -msgid "New Branch Name Template" -msgstr "Шаблон за името на новите клони" +#: lib/diff.tcl:244 +#, tcl-format +msgid "" +"* Untracked file is %d bytes.\n" +"* Showing only first %d bytes.\n" +msgstr "" +"● Неследеният файл е %d байта.\n" +"● Показват се само първите %d байта.\n" -#: lib/option.tcl:160 -msgid "Default File Contents Encoding" -msgstr "Кодиране на файловете" +#: lib/diff.tcl:250 +#, tcl-format +msgid "" +"\n" +"* Untracked file clipped here by %s.\n" +"* To see the entire file, use an external editor.\n" +msgstr "" +"\n" +"● Неследеният файл е отрязан дотук от програмата „%s“.\n" +"● Използвайте външен редактор, за да видите целия файл.\n" -#: lib/option.tcl:161 -msgid "Warn before committing to a detached head" -msgstr "Предупреждаване при подаване към несвързан указател" +#: lib/diff.tcl:583 +msgid "Failed to unstage selected hunk." +msgstr "Избраното парче не може да се извади от индекса." -#: lib/option.tcl:162 -msgid "Staging of untracked files" -msgstr "Добавяне на неследените файлове към индекса" +#: lib/diff.tcl:591 +msgid "Failed to revert selected hunk." +msgstr "Избраното парче не може да се върне." -#: lib/option.tcl:163 -msgid "Show untracked files" -msgstr "Показване на неследените файлове" +#: lib/diff.tcl:594 +msgid "Failed to stage selected hunk." +msgstr "Избраното парче не може да се добави към индекса." -#: lib/option.tcl:164 -msgid "Tab spacing" -msgstr "Ширина на табулацията" +#: lib/diff.tcl:687 +msgid "Failed to unstage selected line." +msgstr "Избраният ред не може да се извади от индекса." -#: lib/option.tcl:210 -msgid "Change" -msgstr "Смяна" +#: lib/diff.tcl:696 +msgid "Failed to revert selected line." +msgstr "Избраният ред не може да се върне." -#: lib/option.tcl:254 -msgid "Spelling Dictionary:" -msgstr "Правописен речник:" +#: lib/diff.tcl:700 +msgid "Failed to stage selected line." +msgstr "Избраният ред не може да се добави към индекса." -#: lib/option.tcl:284 -msgid "Change Font" -msgstr "Смяна на шрифта" +#: lib/diff.tcl:889 +msgid "Failed to undo last revert." +msgstr "Неуспешна отмяна на последното връщане." -#: lib/option.tcl:288 +#: lib/sshkey.tcl:34 +msgid "No keys found." +msgstr "Не са открити ключове." + +#: lib/sshkey.tcl:37 #, tcl-format -msgid "Choose %s" -msgstr "Избор на „%s“" +msgid "Found a public key in: %s" +msgstr "Открит е публичен ключ в „%s“" -#: lib/option.tcl:294 -msgid "pt." -msgstr "тчк." +#: lib/sshkey.tcl:43 +msgid "Generate Key" +msgstr "Генериране на ключ" -#: lib/option.tcl:308 -msgid "Preferences" -msgstr "Настройки" +#: lib/sshkey.tcl:61 +msgid "Copy To Clipboard" +msgstr "Копиране към системния буфер" -#: lib/option.tcl:345 -msgid "Failed to completely save options:" -msgstr "Неуспешно запазване на настройките:" +#: lib/sshkey.tcl:75 +msgid "Your OpenSSH Public Key" +msgstr "Публичният ви ключ за OpenSSH" -#: lib/remote.tcl:200 -msgid "Push to" -msgstr "Изтласкване към" +#: lib/sshkey.tcl:83 +msgid "Generating..." +msgstr "Генериране…" -#: lib/remote.tcl:218 -msgid "Remove Remote" -msgstr "Премахване на отдалечено хранилище" +#: lib/sshkey.tcl:89 +#, tcl-format +msgid "" +"Could not start ssh-keygen:\n" +"\n" +"%s" +msgstr "" +"Програмата „ssh-keygen“ не може да се стартира:\n" +"\n" +"%s" -#: lib/remote.tcl:223 -msgid "Prune from" -msgstr "Окастряне от" +#: lib/sshkey.tcl:116 +msgid "Generation failed." +msgstr "Неуспешно генериране." -#: lib/remote.tcl:228 -msgid "Fetch from" -msgstr "Доставяне от" +#: lib/sshkey.tcl:123 +msgid "Generation succeeded, but no keys found." +msgstr "Генерирането завърши успешно, а не са намерени ключове." -#: lib/remote.tcl:253 lib/remote.tcl:258 -msgid "All" -msgstr "Всички" +#: lib/sshkey.tcl:126 +#, tcl-format +msgid "Your key is in: %s" +msgstr "Ключът ви е в „%s“" -#: lib/remote_add.tcl:20 +#: lib/branch_create.tcl:23 #, tcl-format -msgid "%s (%s): Add Remote" -msgstr "%s (%s): Добавяне на отдалечено хранилище" +msgid "%s (%s): Create Branch" +msgstr "%s (%s): Създаване на клон" -#: lib/remote_add.tcl:25 -msgid "Add New Remote" -msgstr "Добавяне на отдалечено хранилище" +#: lib/branch_create.tcl:28 +msgid "Create New Branch" +msgstr "Създаване на нов клон" -#: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37 -msgid "Add" -msgstr "Добавяне" +#: lib/branch_create.tcl:42 +msgid "Branch Name" +msgstr "Име на клона" -#: lib/remote_add.tcl:39 -msgid "Remote Details" -msgstr "Данни за отдалеченото хранилище" +#: lib/branch_create.tcl:57 +msgid "Match Tracking Branch Name" +msgstr "Съвпадане по името на следения клон" -#: lib/remote_add.tcl:50 -msgid "Location:" -msgstr "Местоположение:" +#: lib/branch_create.tcl:66 +msgid "Starting Revision" +msgstr "Начална версия" -#: lib/remote_add.tcl:60 -msgid "Further Action" -msgstr "Следващо действие" +#: lib/branch_create.tcl:72 +msgid "Update Existing Branch:" +msgstr "Обновяване на съществуващ клон:" -#: lib/remote_add.tcl:63 -msgid "Fetch Immediately" -msgstr "Незабавно доставяне" +#: lib/branch_create.tcl:75 +msgid "No" +msgstr "Не" -#: lib/remote_add.tcl:69 -msgid "Initialize Remote Repository and Push" -msgstr "Инициализиране на отдалеченото хранилище и изтласкване на промените" +#: lib/branch_create.tcl:80 +msgid "Fast Forward Only" +msgstr "Само тривиално превъртащо сливане" -#: lib/remote_add.tcl:75 -msgid "Do Nothing Else Now" -msgstr "Да не се прави нищо" +#: lib/branch_create.tcl:97 +msgid "Checkout After Creation" +msgstr "Преминаване към клона след създаването му" -#: lib/remote_add.tcl:100 -msgid "Please supply a remote name." -msgstr "Задайте име за отдалеченото хранилище." +#: lib/branch_create.tcl:132 +msgid "Please select a tracking branch." +msgstr "Изберете клон за следени." -#: lib/remote_add.tcl:113 +#: lib/branch_create.tcl:141 #, tcl-format -msgid "'%s' is not an acceptable remote name." -msgstr "Отдалечено хранилище не може да се казва „%s“." +msgid "Tracking branch %s is not a branch in the remote repository." +msgstr "Следящият клон — „%s“, не съществува в отдалеченото хранилище." -#: lib/remote_add.tcl:124 -#, tcl-format -msgid "Failed to add remote '%s' of location '%s'." -msgstr "Неуспешно добавяне на отдалеченото хранилище „%s“ от адрес „%s“." +#: lib/console.tcl:59 +msgid "Working... please wait..." +msgstr "В момента се извършва действие, изчакайте…" -#: lib/remote_add.tcl:132 lib/transport.tcl:6 -#, tcl-format -msgid "fetch %s" -msgstr "доставяне на „%s“" +#: lib/console.tcl:186 +msgid "Success" +msgstr "Успех" -#: lib/remote_add.tcl:133 -#, tcl-format -msgid "Fetching the %s" -msgstr "Доставяне на „%s“" +#: lib/console.tcl:200 +msgid "Error: Command Failed" +msgstr "Грешка: неуспешно изпълнение на команда" -#: lib/remote_add.tcl:156 -#, tcl-format -msgid "Do not know how to initialize repository at location '%s'." -msgstr "Хранилището с местоположение „%s“ не може да бъде инициализирано." +#: lib/line.tcl:17 +msgid "Goto Line:" +msgstr "Към ред:" -#: lib/remote_add.tcl:162 lib/transport.tcl:54 lib/transport.tcl:92 -#: lib/transport.tcl:110 -#, tcl-format -msgid "push %s" -msgstr "изтласкване на „%s“" +#: lib/line.tcl:23 +msgid "Go" +msgstr "Към" -#: lib/remote_add.tcl:163 -#, tcl-format -msgid "Setting up the %s (at %s)" -msgstr "Добавяне на хранилище „%s“ (с адрес „%s“)" +#: lib/choose_rev.tcl:52 +msgid "This Detached Checkout" +msgstr "Това несвързано изтегляне" -#: lib/remote_branch_delete.tcl:29 -#, tcl-format -msgid "%s (%s): Delete Branch Remotely" -msgstr "%s (%s): Изтриване на отдалечения клон" +#: lib/choose_rev.tcl:60 +msgid "Revision Expression:" +msgstr "Израз за версия:" -#: lib/remote_branch_delete.tcl:34 -msgid "Delete Branch Remotely" -msgstr "Изтриване на отдалечения клон" +#: lib/choose_rev.tcl:72 +msgid "Local Branch" +msgstr "Локален клон" -#: lib/remote_branch_delete.tcl:48 -msgid "From Repository" -msgstr "От хранилище" +#: lib/choose_rev.tcl:77 +msgid "Tracking Branch" +msgstr "Следящ клон" -#: lib/remote_branch_delete.tcl:51 lib/transport.tcl:165 -msgid "Remote:" -msgstr "Отдалечено хранилище:" +#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544 +msgid "Tag" +msgstr "Етикет" -#: lib/remote_branch_delete.tcl:72 lib/transport.tcl:187 -msgid "Arbitrary Location:" -msgstr "Произволно местоположение:" +#: lib/choose_rev.tcl:321 +#, tcl-format +msgid "Invalid revision: %s" +msgstr "Неправилна версия: %s" -#: lib/remote_branch_delete.tcl:88 -msgid "Branches" -msgstr "Клони" +#: lib/choose_rev.tcl:342 +msgid "No revision selected." +msgstr "Не е избрана версия." -#: lib/remote_branch_delete.tcl:110 -msgid "Delete Only If" -msgstr "Изтриване, само ако" +#: lib/choose_rev.tcl:350 +msgid "Revision expression is empty." +msgstr "Изразът за версия е празен." -#: lib/remote_branch_delete.tcl:112 -msgid "Merged Into:" -msgstr "Слят в:" +#: lib/choose_rev.tcl:537 +msgid "Updated" +msgstr "Обновен" -#: lib/remote_branch_delete.tcl:153 -msgid "A branch is required for 'Merged Into'." -msgstr "За данните „Слят в“ е необходимо да зададете клон." +#: lib/choose_rev.tcl:565 +msgid "URL" +msgstr "Адрес" -#: lib/remote_branch_delete.tcl:185 -#, tcl-format +#: lib/commit.tcl:9 msgid "" -"The following branches are not completely merged into %s:\n" +"There is nothing to amend.\n" "\n" -" - %s" +"You are about to create the initial commit. There is no commit before this " +"to amend.\n" msgstr "" -"Следните клони не са слети напълно в „%s“:\n" +"Няма какво да се поправи.\n" "\n" -" ● %s" +"Ще създадете първоначалното подаване. Преди него няма други подавания, които " +"да поправите.\n" -#: lib/remote_branch_delete.tcl:190 -#, tcl-format +#: lib/commit.tcl:18 msgid "" -"One or more of the merge tests failed because you have not fetched the " -"necessary commits. Try fetching from %s first." +"Cannot amend while merging.\n" +"\n" +"You are currently in the middle of a merge that has not been fully " +"completed. You cannot amend the prior commit unless you first abort the " +"current merge activity.\n" msgstr "" -"Поне една от пробите за сливане е неуспешна, защото не сте доставили всички " -"необходими подавания. Пробвайте първо да доставите подаванията от „%s“." - -#: lib/remote_branch_delete.tcl:208 -msgid "Please select one or more branches to delete." -msgstr "Изберете поне един клон за изтриване." - -#: lib/remote_branch_delete.tcl:227 -#, tcl-format -msgid "Deleting branches from %s" -msgstr "Изтриване на клони от „%s“" - -#: lib/remote_branch_delete.tcl:300 -msgid "No repository selected." -msgstr "Не е избрано хранилище." - -#: lib/remote_branch_delete.tcl:305 -#, tcl-format -msgid "Scanning %s..." -msgstr "Претърсване на „%s“…" - -#: lib/search.tcl:48 -msgid "Find:" -msgstr "Търсене:" - -#: lib/search.tcl:50 -msgid "Next" -msgstr "Следваща поява" +"По време на сливане не може да поправяте.\n" +"\n" +"В момента все още не сте завършили операция по сливане. Не може да поправите " +"предишното подаване, освен ако първо не преустановите текущото сливане.\n" -#: lib/search.tcl:51 -msgid "Prev" -msgstr "Предишна поява" +#: lib/commit.tcl:56 +msgid "Error loading commit data for amend:" +msgstr "Грешка при зареждане на данните от подаване, които да се поправят:" -#: lib/search.tcl:52 -msgid "RegExp" -msgstr "РегИзр" +#: lib/commit.tcl:83 +msgid "Unable to obtain your identity:" +msgstr "Идентификацията ви не може да се определи:" -#: lib/search.tcl:54 -msgid "Case" -msgstr "Главни/малки" +#: lib/commit.tcl:88 +msgid "Invalid GIT_COMMITTER_IDENT:" +msgstr "Неправилно поле „GIT_COMMITTER_IDENT“:" -#: lib/shortcut.tcl:8 lib/shortcut.tcl:43 lib/shortcut.tcl:75 +#: lib/commit.tcl:138 #, tcl-format -msgid "%s (%s): Create Desktop Icon" -msgstr "%s (%s): Добавяне на икона на работния плот" - -#: lib/shortcut.tcl:24 lib/shortcut.tcl:65 -msgid "Cannot write shortcut:" -msgstr "Клавишната комбинация не може да бъде запазена:" - -#: lib/shortcut.tcl:140 -msgid "Cannot write icon:" -msgstr "Иконата не може да бъде запазена:" - -#: lib/spellcheck.tcl:57 -msgid "Unsupported spell checker" -msgstr "Тази програма за проверка на правописа не се поддържа" - -#: lib/spellcheck.tcl:65 -msgid "Spell checking is unavailable" -msgstr "Липсва програма за проверка на правописа" +msgid "warning: Tcl does not support encoding '%s'." +msgstr "предупреждение: Tcl не поддържа кодирането „%s“." -#: lib/spellcheck.tcl:68 -msgid "Invalid spell checking configuration" -msgstr "Неправилни настройки на проверката на правописа" +#: lib/commit.tcl:158 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A " +"rescan must be performed before another commit can be created.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "" +"Състоянието при последната проверка не отговаря на състоянието на " +"хранилището.\n" +"\n" +"Някой друг процес за Git е променил хранилището междувременно. Състоянието " +"трябва да се провери преди ново подаване.\n" +"\n" +"Автоматично ще започне нова проверка.\n" -#: lib/spellcheck.tcl:70 +#: lib/commit.tcl:182 #, tcl-format -msgid "Reverting dictionary to %s." -msgstr "Ползване на речник за език „%s“." +msgid "" +"Unmerged files cannot be committed.\n" +"\n" +"File %s has merge conflicts. You must resolve them and stage the file " +"before committing.\n" +msgstr "" +"Неслетите файлове не може да се подадат.\n" +"\n" +"Във файла „%s“ има конфликти при сливане. За да го подадете, трябва първо да " +"коригирате конфликтите и да добавите файла към индекса за подаване.\n" -#: lib/spellcheck.tcl:73 -msgid "Spell checker silently failed on startup" -msgstr "Програмата за правопис даже не стартира успешно." +#: lib/commit.tcl:190 +#, tcl-format +msgid "" +"Unknown file state %s detected.\n" +"\n" +"File %s cannot be committed by this program.\n" +msgstr "" +"Непознато състояние на файл „%s“.\n" +"\n" +"Файлът „%s“ не може да се подаде чрез текущата програма.\n" -#: lib/spellcheck.tcl:80 -msgid "Unrecognized spell checker" -msgstr "Непозната програма за проверка на правописа" +#: lib/commit.tcl:198 +msgid "" +"No changes to commit.\n" +"\n" +"You must stage at least 1 file before you can commit.\n" +msgstr "" +"Няма промени за подаване.\n" +"\n" +"Трябва да добавите поне един файл към индекса, за да подадете.\n" -#: lib/spellcheck.tcl:186 -msgid "No Suggestions" -msgstr "Няма предложения" +#: lib/commit.tcl:213 +msgid "" +"Please supply a commit message.\n" +"\n" +"A good commit message has the following format:\n" +"\n" +"- First line: Describe in one sentence what you did.\n" +"- Second line: Blank\n" +"- Remaining lines: Describe why this change is good.\n" +msgstr "" +"Задайте добро съобщение при подаване.\n" +"\n" +"Използвайте следния формат:\n" +"\n" +"● Първи ред: описание в едно изречение на промяната.\n" +"● Втори ред: празен.\n" +"● Останалите редове: опишете защо се налага тази промяна.\n" -#: lib/spellcheck.tcl:388 -msgid "Unexpected EOF from spell checker" -msgstr "Неочакван край на файл от програмата за проверка на правописа" +#: lib/commit.tcl:244 +msgid "Calling pre-commit hook..." +msgstr "Изпълняване на куката преди подаване…" -#: lib/spellcheck.tcl:392 -msgid "Spell Checker Failed" -msgstr "Грешка в програмата за проверка на правописа" +#: lib/commit.tcl:259 +msgid "Commit declined by pre-commit hook." +msgstr "Подаването е отхвърлено от куката преди подаване." -#: lib/sshkey.tcl:31 -msgid "No keys found." -msgstr "Не са открити ключове." +#: lib/commit.tcl:278 +msgid "" +"You are about to commit on a detached head. This is a potentially dangerous " +"thing to do because if you switch to another branch you will lose your " +"changes and it can be difficult to retrieve them later from the reflog. You " +"should probably cancel this commit and create a new branch to continue.\n" +" \n" +" Do you really want to proceed with your Commit?" +msgstr "" +"Ще подадете към несвързан, отделѐн указател „HEAD“. Това е опасно, защото " +"при преминаването към клон ще загубите промените си, като единственият начин " +"да ги върнете ще е чрез журнала на указателите (reflog). Най-вероятно трябва " +"да не правите това подаване, а да създадете нов клон, преди да продължите.\n" +" \n" +"Сигурни ли сте, че искате да извършите текущото подаване?" -#: lib/sshkey.tcl:34 -#, tcl-format -msgid "Found a public key in: %s" -msgstr "Открит е публичен ключ в „%s“" +#: lib/commit.tcl:299 +msgid "Calling commit-msg hook..." +msgstr "Изпълняване на куката за съобщението при подаване…" -#: lib/sshkey.tcl:40 -msgid "Generate Key" -msgstr "Генериране на ключ" +#: lib/commit.tcl:314 +msgid "Commit declined by commit-msg hook." +msgstr "Подаването е отхвърлено от куката за съобщението при подаване." -#: lib/sshkey.tcl:58 -msgid "Copy To Clipboard" -msgstr "Копиране към системния буфер" +#: lib/commit.tcl:327 +msgid "Committing changes..." +msgstr "Подаване на промените…" -#: lib/sshkey.tcl:72 -msgid "Your OpenSSH Public Key" -msgstr "Публичният ви ключ за OpenSSH" +#: lib/commit.tcl:344 +msgid "write-tree failed:" +msgstr "неуспешно запазване на дървото (write-tree):" -#: lib/sshkey.tcl:80 -msgid "Generating..." -msgstr "Генериране…" +#: lib/commit.tcl:345 lib/commit.tcl:395 lib/commit.tcl:422 +msgid "Commit failed." +msgstr "Неуспешно подаване." -#: lib/sshkey.tcl:86 +#: lib/commit.tcl:362 #, tcl-format +msgid "Commit %s appears to be corrupt" +msgstr "Подаването „%s“ изглежда повредено" + +#: lib/commit.tcl:367 msgid "" -"Could not start ssh-keygen:\n" +"No changes to commit.\n" "\n" -"%s" +"No files were modified by this commit and it was not a merge commit.\n" +"\n" +"A rescan will be automatically started now.\n" msgstr "" -"Програмата „ssh-keygen“ не може да бъде стартирана:\n" +"Няма промени за подаване.\n" "\n" -"%s" +"В това подаване не са променяни никакви файлове, а и не е подаване със " +"сливане.\n" +"\n" +"Автоматично ще започне нова проверка.\n" -#: lib/sshkey.tcl:113 -msgid "Generation failed." -msgstr "Неуспешно генериране." +#: lib/commit.tcl:374 +msgid "No changes to commit." +msgstr "Няма промени за подаване." -#: lib/sshkey.tcl:120 -msgid "Generation succeeded, but no keys found." -msgstr "Генерирането завърши успешно, а не са намерени ключове." +#: lib/commit.tcl:394 +msgid "commit-tree failed:" +msgstr "неуспешно подаване на дървото (commit-tree):" -#: lib/sshkey.tcl:123 -#, tcl-format -msgid "Your key is in: %s" -msgstr "Ключът ви е в „%s“" +#: lib/commit.tcl:421 +msgid "update-ref failed:" +msgstr "неуспешно обновяване на указателите (update-ref):" -#: lib/status_bar.tcl:87 +#: lib/commit.tcl:514 #, tcl-format -msgid "%s ... %*i of %*i %s (%3i%%)" -msgstr "%s… %*i от общо %*i %s (%3i%%)" +msgid "Created commit %s: %s" +msgstr "Успешно подаване %s: %s" -#: lib/tools.tcl:76 +#: lib/branch_delete.tcl:16 #, tcl-format -msgid "Running %s requires a selected file." -msgstr "За изпълнението на „%s“ трябва да изберете файл." +msgid "%s (%s): Delete Branch" +msgstr "%s (%s): Изтриване на клон" -#: lib/tools.tcl:92 -#, tcl-format -msgid "Are you sure you want to run %1$s on file \"%2$s\"?" -msgstr "Сигурни ли сте, че искате да изпълните „%1$s“ върху файла „%2$s“?" +#: lib/branch_delete.tcl:21 +msgid "Delete Local Branch" +msgstr "Изтриване на локален клон" -#: lib/tools.tcl:96 -#, tcl-format -msgid "Are you sure you want to run %s?" -msgstr "Сигурни ли сте, че искате да изпълните „%s“?" +#: lib/branch_delete.tcl:39 +msgid "Local Branches" +msgstr "Локални клони" -#: lib/tools.tcl:118 -#, tcl-format -msgid "Tool: %s" -msgstr "Команда: %s" +#: lib/branch_delete.tcl:51 +msgid "Delete Only If Merged Into" +msgstr "Изтриване, само ако промените са слети и другаде" -#: lib/tools.tcl:119 +#: lib/branch_delete.tcl:103 #, tcl-format -msgid "Running: %s" -msgstr "Изпълнение: %s" +msgid "The following branches are not completely merged into %s:" +msgstr "Не всички промени в клоните са слети в „%s“:" -#: lib/tools.tcl:158 +#: lib/branch_delete.tcl:131 #, tcl-format -msgid "Tool completed successfully: %s" -msgstr "Командата завърши успешно: %s" +msgid " - %s:" +msgstr " — „%s:“" -#: lib/tools.tcl:160 +#: lib/branch_delete.tcl:141 #, tcl-format -msgid "Tool failed: %s" -msgstr "Командата върна грешка: %s" +msgid "" +"Failed to delete branches:\n" +"%s" +msgstr "" +"Неуспешно триене на клони:\n" +"%s" -#: lib/tools_dlg.tcl:22 +#: lib/date.tcl:25 #, tcl-format -msgid "%s (%s): Add Tool" -msgstr "%s (%s): Добавяне на команда" - -#: lib/tools_dlg.tcl:28 -msgid "Add New Tool Command" -msgstr "Добавяне на команда" - -#: lib/tools_dlg.tcl:34 -msgid "Add globally" -msgstr "Глобално добавяне" - -#: lib/tools_dlg.tcl:46 -msgid "Tool Details" -msgstr "Подробности за командата" - -#: lib/tools_dlg.tcl:49 -msgid "Use '/' separators to create a submenu tree:" -msgstr "За създаване на подменюта използвайте знака „/“ за разделител:" - -#: lib/tools_dlg.tcl:60 -msgid "Command:" -msgstr "Команда:" +msgid "Invalid date from Git: %s" +msgstr "Неправилни данни от Git: %s" -#: lib/tools_dlg.tcl:71 -msgid "Show a dialog before running" -msgstr "Преди изпълнение да се извежда диалогов прозорец" +#: lib/database.tcl:42 +msgid "Number of loose objects" +msgstr "Брой непакетирани обекти" -#: lib/tools_dlg.tcl:77 -msgid "Ask the user to select a revision (sets $REVISION)" -msgstr "Потребителят да укаже версия (задаване на променливата $REVISION)" +#: lib/database.tcl:43 +msgid "Disk space used by loose objects" +msgstr "Дисково пространство заето от непакетирани обекти" -#: lib/tools_dlg.tcl:82 -msgid "Ask the user for additional arguments (sets $ARGS)" -msgstr "" -"Потребителят да укаже допълнителни аргументи (задаване на променливата $ARGS)" +#: lib/database.tcl:44 +msgid "Number of packed objects" +msgstr "Брой пакетирани обекти" -#: lib/tools_dlg.tcl:89 -msgid "Don't show the command output window" -msgstr "Без показване на прозорец с изхода от командата" +#: lib/database.tcl:45 +msgid "Number of packs" +msgstr "Брой пакети" -#: lib/tools_dlg.tcl:94 -msgid "Run only if a diff is selected ($FILENAME not empty)" -msgstr "" -"Стартиране само след избор на разлика (променливата $FILENAME не е празна)" +#: lib/database.tcl:46 +msgid "Disk space used by packed objects" +msgstr "Дисково пространство заето от пакетирани обекти" -#: lib/tools_dlg.tcl:118 -msgid "Please supply a name for the tool." -msgstr "Задайте име за командата." +#: lib/database.tcl:47 +msgid "Packed objects waiting for pruning" +msgstr "Пакетирани обекти за окастряне" -#: lib/tools_dlg.tcl:126 +#: lib/database.tcl:48 +msgid "Garbage files" +msgstr "Файлове за боклука" + +#: lib/database.tcl:66 #, tcl-format -msgid "Tool '%s' already exists." -msgstr "Командата „%s“ вече съществува." +msgid "%s (%s): Database Statistics" +msgstr "%s (%s): Статистика на базата от данни" -#: lib/tools_dlg.tcl:148 +#: lib/database.tcl:72 +msgid "Compressing the object database" +msgstr "Компресиране на базата с данни за обектите" + +#: lib/database.tcl:83 +msgid "Verifying the object database with fsck-objects" +msgstr "Проверка на базата с данни за обектите с програмата „fsck-objects“" + +#: lib/database.tcl:107 #, tcl-format msgid "" -"Could not add tool:\n" -"%s" +"This repository currently has approximately %i loose objects.\n" +"\n" +"To maintain optimal performance it is strongly recommended that you compress " +"the database.\n" +"\n" +"Compress the database now?" msgstr "" -"Командата не може да бъде добавена:\n" -"%s" +"В това хранилище в момента има към %i непакетирани обекти.\n" +"\n" +"За добра производителност се препоръчва да компресирате базата с данни за " +"обектите.\n" +"\n" +"Да се започне ли компресирането?" -#: lib/tools_dlg.tcl:187 +#: lib/error.tcl:20 #, tcl-format -msgid "%s (%s): Remove Tool" -msgstr "%s (%s): Премахване на команда" - -#: lib/tools_dlg.tcl:193 -msgid "Remove Tool Commands" -msgstr "Премахване на команди" - -#: lib/tools_dlg.tcl:198 -msgid "Remove" -msgstr "Премахване" +msgid "%s: error" +msgstr "%s: грешка" -#: lib/tools_dlg.tcl:231 -msgid "(Blue denotes repository-local tools)" -msgstr "(командите към локалното хранилище са обозначени в синьо)" +#: lib/error.tcl:36 +#, tcl-format +msgid "%s: warning" +msgstr "%s: предупреждение" -#: lib/tools_dlg.tcl:283 +#: lib/error.tcl:80 #, tcl-format -msgid "%s (%s):" -msgstr "%s (%s):" +msgid "%s hook failed:" +msgstr "%s: грешка от куката" -#: lib/tools_dlg.tcl:292 +#: lib/error.tcl:96 +msgid "You must correct the above errors before committing." +msgstr "Преди да можете да подадете, коригирайте горните грешки." + +#: lib/error.tcl:116 #, tcl-format -msgid "Run Command: %s" -msgstr "Изпълнение на командата „%s“" +msgid "%s (%s): error" +msgstr "%s (%s): грешка" -#: lib/tools_dlg.tcl:306 -msgid "Arguments" -msgstr "Аргументи" +#: lib/merge.tcl:13 +msgid "" +"Cannot merge while amending.\n" +"\n" +"You must finish amending this commit before starting any type of merge.\n" +msgstr "" +"По време на поправяне не може да сливане.\n" +"\n" +"Трябва да завършите поправянето на текущото подаване, преди да започнете " +"сливане.\n" -#: lib/tools_dlg.tcl:341 -msgid "OK" -msgstr "Добре" +#: lib/merge.tcl:27 +msgid "" +"Last scanned state does not match repository state.\n" +"\n" +"Another Git program has modified this repository since the last scan. A " +"rescan must be performed before a merge can be performed.\n" +"\n" +"The rescan will be automatically started now.\n" +msgstr "" +"Последно установеното състояние не отговаря на това в хранилището.\n" +"\n" +"Някой друг процес за Git е променил хранилището междувременно. Състоянието " +"трябва да се провери, преди да се извърши сливане.\n" +"\n" +"Автоматично ще започне нова проверка.\n" +"\n" -#: lib/transport.tcl:7 +#: lib/merge.tcl:45 #, tcl-format -msgid "Fetching new changes from %s" -msgstr "Доставяне на промените от „%s“" +msgid "" +"You are in the middle of a conflicted merge.\n" +"\n" +"File %s has merge conflicts.\n" +"\n" +"You must resolve them, stage the file, and commit to complete the current " +"merge. Only then can you begin another merge.\n" +msgstr "" +"В момента тече сливане, но има конфликти.\n" +"\n" +"Погледнете файла „%s“.\n" +"\n" +"Трябва да коригирате конфликтите в него, да го добавите към индекса и да " +"завършите текущото сливане чрез подаване. Чак тогава може да започнете ново " +"сливане.\n" -#: lib/transport.tcl:18 +#: lib/merge.tcl:55 #, tcl-format -msgid "remote prune %s" -msgstr "окастряне на следящите клони към „%s“" +msgid "" +"You are in the middle of a change.\n" +"\n" +"File %s is modified.\n" +"\n" +"You should complete the current commit before starting a merge. Doing so " +"will help you abort a failed merge, should the need arise.\n" +msgstr "" +"В момента тече подаване.\n" +"\n" +"Файлът „%s“ е променен.\n" +"\n" +"Трябва да завършите текущото подаване, преди да започнете сливане. Така ще " +"можете лесно да преустановите сливането, ако възникне нужда.\n" -#: lib/transport.tcl:19 +#: lib/merge.tcl:108 #, tcl-format -msgid "Pruning tracking branches deleted from %s" -msgstr "Окастряне на следящите клони на изтритите клони от „%s“" - -#: lib/transport.tcl:25 -msgid "fetch all remotes" -msgstr "доставяне от всички отдалечени" - -#: lib/transport.tcl:26 -msgid "Fetching new changes from all remotes" -msgstr "Доставяне на промените от всички отдалечени хранилища" +msgid "%s of %s" +msgstr "%s от общо %s" -#: lib/transport.tcl:40 -msgid "remote prune all remotes" -msgstr "окастряне на следящите изтрити" +#: lib/merge.tcl:126 +#, tcl-format +msgid "Merging %s and %s..." +msgstr "Сливане на „%s“ и „%s“…" -#: lib/transport.tcl:41 -msgid "Pruning tracking branches deleted from all remotes" -msgstr "" -"Окастряне на следящите клони на изтритите клони от всички отдалечени " -"хранилища" +#: lib/merge.tcl:137 +msgid "Merge completed successfully." +msgstr "Сливането завърши успешно." -#: lib/transport.tcl:55 -#, tcl-format -msgid "Pushing changes to %s" -msgstr "Изтласкване на промените към „%s“" +#: lib/merge.tcl:139 +msgid "Merge failed. Conflict resolution is required." +msgstr "Неуспешно сливане — има конфликти за коригиране." -#: lib/transport.tcl:93 +#: lib/merge.tcl:156 #, tcl-format -msgid "Mirroring to %s" -msgstr "Изтласкване на всичко към „%s“" +msgid "%s (%s): Merge" +msgstr "%s (%s): Сливане" -#: lib/transport.tcl:111 +#: lib/merge.tcl:164 #, tcl-format -msgid "Pushing %s %s to %s" -msgstr "Изтласкване на %s „%s“ към „%s“" - -#: lib/transport.tcl:132 -msgid "Push Branches" -msgstr "Клони за изтласкване" +msgid "Merge Into %s" +msgstr "Сливане в „%s“" -#: lib/transport.tcl:147 -msgid "Source Branches" -msgstr "Клони-източници" +#: lib/merge.tcl:183 +msgid "Revision To Merge" +msgstr "Версия за сливане" -#: lib/transport.tcl:162 -msgid "Destination Repository" -msgstr "Целево хранилище" +#: lib/merge.tcl:218 +msgid "" +"Cannot abort while amending.\n" +"\n" +"You must finish amending this commit.\n" +msgstr "" +"Поправянето не може да се преустанови.\n" +"\n" +"Трябва да завършите поправката на това подаване.\n" -#: lib/transport.tcl:205 -msgid "Transfer Options" -msgstr "Настройки при пренасянето" +#: lib/merge.tcl:228 +msgid "" +"Abort merge?\n" +"\n" +"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n" +"\n" +"Continue with aborting the current merge?" +msgstr "" +"Да се преустанови ли сливането?\n" +"\n" +"В такъв случай ●ВСИЧКИ● неподадени промени ще се загубят безвъзвратно.\n" +"\n" +"Наистина ли да се преустанови сливането?" -#: lib/transport.tcl:207 -msgid "Force overwrite existing branch (may discard changes)" +#: lib/merge.tcl:234 +msgid "" +"Reset changes?\n" +"\n" +"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n" +"\n" +"Continue with resetting the current changes?" msgstr "" -"Изрично презаписване на съществуващ клон (някои промени може да бъдат " -"загубени)" +"Да се занулят ли промените?\n" +"\n" +"В такъв случай ●ВСИЧКИ● неподадени промени ще се загубят безвъзвратно.\n" +"\n" +"Наистина ли да се занулят промените?" -#: lib/transport.tcl:211 -msgid "Use thin pack (for slow network connections)" -msgstr "Максимална компресия (за бавни мрежови връзки)" +#: lib/merge.tcl:246 +msgid "Aborting" +msgstr "Преустановяване" -#: lib/transport.tcl:215 -msgid "Include tags" -msgstr "Включване на етикетите" +#: lib/merge.tcl:247 +msgid "files reset" +msgstr "файла със занулени промени" -#: lib/transport.tcl:229 -#, tcl-format -msgid "%s (%s): Push" -msgstr "%s (%s): Изтласкване" +#: lib/merge.tcl:277 +msgid "Abort failed." +msgstr "Неуспешно преустановяване." + +#: lib/merge.tcl:279 +msgid "Abort completed. Ready." +msgstr "Успешно преустановяване. Готовност за следващо действие." diff --git a/git-gui/po/glossary/Makefile b/git-gui/po/glossary/Makefile index 749aa2e7ec1b02..e656b0d2b0fbd0 100644 --- a/git-gui/po/glossary/Makefile +++ b/git-gui/po/glossary/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +update-po:: + PO_TEMPLATE = git-gui-glossary.pot ALL_POFILES = $(wildcard *.po) diff --git a/git-instaweb.sh b/git-instaweb.sh index 8dbe21d5887595..7b44f7078951b5 100755 --- a/git-instaweb.sh +++ b/git-instaweb.sh @@ -3,7 +3,7 @@ # Copyright (c) 2006 Eric Wong # -PERL='@@PERL@@' +PERL='@PERL_PATH@' OPTIONS_KEEPDASHDASH= OPTIONS_STUCKLONG= OPTIONS_SPEC="\ @@ -38,8 +38,8 @@ conf="$GIT_DIR/gitweb/httpd.conf" # if installed, it doesn't need further configuration (module_path) test -z "$httpd" && httpd='lighttpd -f' -# Default is @@GITWEBDIR@@ -test -z "$root" && root='@@GITWEBDIR@@' +# Default is @GITWEBDIR@ +test -z "$root" && root='@GITWEBDIR@' # any untaken local port will do... test -z "$port" && port=1234 @@ -694,9 +694,9 @@ class GitWebRequestHandler(CGIHTTPRequestHandler): return result -bind = "127.0.0.1" +bind = "0.0.0.0" if "$local" == "true": - bind = "0.0.0.0" + bind = "127.0.0.1" # Set our http root directory # This is a work around for a missing directory argument in older Python versions @@ -716,7 +716,7 @@ EOF gitweb_conf() { cat > "$fqgitdir/gitweb/gitweb_config.perl" <<EOF -#!@@PERL@@ +#!@PERL_PATH@ our \$projectroot = "$(dirname "$fqgitdir")"; our \$git_temp = "$fqgitdir/gitweb/tmp"; our \$projects_list = \$projectroot; diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index 1ff26170ffcff8..11ea181259f865 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -159,7 +159,7 @@ check_unchanged () { } valid_tool () { - setup_tool "$1" && return 0 + setup_tool "$1" 2>/dev/null && return 0 cmd=$(get_merge_tool_cmd "$1") test -n "$cmd" } @@ -250,7 +250,12 @@ setup_tool () { . "$MERGE_TOOLS_DIR/${tool%[0-9]}" else setup_user_tool - return $? + rc=$? + if test $rc -ne 0 + then + echo >&2 "error: ${TOOL_MODE}tool.$tool.cmd not set for tool '$tool'" + fi + return $rc fi # Now let the user override the default command for the tool. If @@ -259,6 +264,7 @@ setup_tool () { if ! list_tool_variants | grep -q "^$tool$" then + echo "error: unknown tool variant '$tool'" >&2 return 1 fi @@ -474,7 +480,7 @@ get_merge_tool_path () { merge_tool="$1" if ! valid_tool "$merge_tool" then - echo >&2 "Unknown merge tool $merge_tool" + echo >&2 "Unknown $TOOL_MODE tool $merge_tool" exit 1 fi if diff_mode diff --git a/git-request-pull.sh b/git-request-pull.sh index 01640a044bb10f..775ba8ea11aa0f 100755 --- a/git-request-pull.sh +++ b/git-request-pull.sh @@ -112,7 +112,7 @@ find_matching_ref=' } ' -set fnord $(git ls-remote "$url" | @@PERL@@ -e "$find_matching_ref" "${remote:-HEAD}" "$headrev") +set fnord $(git ls-remote "$url" | @PERL_PATH@ -e "$find_matching_ref" "${remote:-HEAD}" "$headrev") remote_sha1=$2 ref=$3 diff --git a/git-send-email.perl b/git-send-email.perl index c835d4c11af259..798d59b84f1d60 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.008001; +require v5.26; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); use Getopt::Long; @@ -1501,7 +1501,7 @@ sub gen_header { @recipients = unique_email_list(@recipients,@cc,@initial_bcc); @recipients = (map { extract_valid_address_or_die($_) } @recipients); my $date = format_2822_time($time++); - my $gitversion = '@@GIT_VERSION@@'; + my $gitversion = '@GIT_VERSION@'; if ($gitversion =~ m/..GIT_VERSION../) { $gitversion = Git::version(); } diff --git a/git-sh-i18n.sh b/git-sh-i18n.sh index a15c0620db6893..ae4b2d6ba9dc06 100644 --- a/git-sh-i18n.sh +++ b/git-sh-i18n.sh @@ -9,7 +9,7 @@ TEXTDOMAIN=git export TEXTDOMAIN if test -z "$GIT_TEXTDOMAINDIR" then - TEXTDOMAINDIR="@@LOCALEDIR@@" + TEXTDOMAINDIR="@LOCALEDIR@" else TEXTDOMAINDIR="$GIT_TEXTDOMAINDIR" fi @@ -17,9 +17,9 @@ export TEXTDOMAINDIR # First decide what scheme to use... GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough -if test -n "@@USE_GETTEXT_SCHEME@@" +if test -n "@USE_GETTEXT_SCHEME@" then - GIT_INTERNAL_GETTEXT_SH_SCHEME="@@USE_GETTEXT_SCHEME@@" + GIT_INTERNAL_GETTEXT_SH_SCHEME="@USE_GETTEXT_SCHEME@" elif test -n "$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS" then : no probing necessary diff --git a/git-sh-setup.sh b/git-sh-setup.sh index ce273fe0e48d99..19aef72ec25530 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -41,7 +41,7 @@ git_broken_path_fix () { esac } -# @@BROKEN_PATH_FIX@@ +# @BROKEN_PATH_FIX@ # Source git-sh-i18n for gettext support. . "$(git --exec-path)/git-sh-i18n" @@ -154,7 +154,7 @@ git_pager() { else GIT_PAGER=cat fi - for vardef in @@PAGER_ENV@@ + for vardef in @PAGER_ENV@ do var=${vardef%%=*} eval ": \"\${$vardef}\" && export $var" @@ -280,7 +280,7 @@ get_author_ident_from_commit () { # remove lines from $1 that are not in $2, leaving only common lines. create_virtual_base() { sz0=$(wc -c <"$1") - @@DIFF@@ -u -La/"$1" -Lb/"$1" "$1" "$2" | git apply --no-add + @DIFF@ -u -La/"$1" -Lb/"$1" "$1" "$2" | git apply --no-add sz1=$(wc -c <"$1") # If we do not have enough common material, it is not diff --git a/git-submodule.sh b/git-submodule.sh index 03c5a220a26ded..2999b31fad3e97 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -40,11 +40,11 @@ init= require_init= files= remote= -nofetch= +no_fetch= rebase= merge= checkout= -custom_name= +name= depth= progress= dissociate= @@ -52,11 +52,10 @@ single_branch= jobs= recommend_shallow= filter= - -isnumber() -{ - n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1" -} +all= +default= +summary_limit= +for_status= # # Add a new submodule to the working tree, .gitmodules and the index @@ -68,31 +67,33 @@ isnumber() cmd_add() { # parse $args after "submodule ... add". - reference_path= while test $# -ne 0 do case "$1" in -b | --branch) case "$2" in '') usage ;; esac - branch=$2 + branch="--branch=$2" shift ;; + -b* | --branch=*) + branch="$1" + ;; -f | --force) force=$1 ;; -q|--quiet) - quiet=1 + quiet=$1 ;; --progress) - progress=1 + progress=$1 ;; --reference) case "$2" in '') usage ;; esac - reference_path=$2 + reference="--reference=$2" shift ;; --reference=*) - reference_path="${1#--reference=}" + reference="$1" ;; --ref-format) case "$2" in '') usage ;; esac @@ -103,20 +104,23 @@ cmd_add() ref_format="$1" ;; --dissociate) - dissociate=1 + dissociate=$1 ;; --name) case "$2" in '') usage ;; esac - custom_name=$2 + name="--name=$2" shift ;; + --name=*) + name="$1" + ;; --depth) case "$2" in '') usage ;; esac depth="--depth=$2" shift ;; --depth=*) - depth=$1 + depth="$1" ;; --) shift @@ -138,14 +142,14 @@ cmd_add() fi git ${wt_prefix:+-C "$wt_prefix"} submodule--helper add \ - ${quiet:+--quiet} \ - ${force:+--force} \ - ${progress:+"--progress"} \ - ${branch:+--branch "$branch"} \ - ${reference_path:+--reference "$reference_path"} \ + $quiet \ + $force \ + $progress \ + ${branch:+"$branch"} \ + ${reference:+"$reference"} \ ${ref_format:+"$ref_format"} \ - ${dissociate:+--dissociate} \ - ${custom_name:+--name "$custom_name"} \ + $dissociate \ + ${name:+"$name"} \ ${depth:+"$depth"} \ -- \ "$@" @@ -164,10 +168,10 @@ cmd_foreach() do case "$1" in -q|--quiet) - quiet=1 + quiet=$1 ;; --recursive) - recursive=1 + recursive=$1 ;; -*) usage @@ -180,8 +184,8 @@ cmd_foreach() done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper foreach \ - ${quiet:+--quiet} \ - ${recursive:+--recursive} \ + $quiet \ + $recursive \ -- \ "$@" } @@ -198,7 +202,7 @@ cmd_init() do case "$1" in -q|--quiet) - quiet=1 + quiet=$1 ;; --) shift @@ -215,7 +219,7 @@ cmd_init() done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper init \ - ${quiet:+--quiet} \ + $quiet \ -- \ "$@" } @@ -226,7 +230,6 @@ cmd_init() cmd_deinit() { # parse $args after "submodule ... deinit". - deinit_all= while test $# -ne 0 do case "$1" in @@ -234,10 +237,10 @@ cmd_deinit() force=$1 ;; -q|--quiet) - quiet=1 + quiet=$1 ;; --all) - deinit_all=t + all=$1 ;; --) shift @@ -254,9 +257,9 @@ cmd_deinit() done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \ - ${quiet:+--quiet} \ - ${force:+--force} \ - ${deinit_all:+--all} \ + $quiet \ + $force \ + $all \ -- \ "$@" } @@ -273,31 +276,31 @@ cmd_update() do case "$1" in -q|--quiet) - quiet=1 + quiet=$1 ;; -v|--verbose) - quiet=0 + quiet= ;; --progress) - progress=1 + progress=$1 ;; -i|--init) - init=1 + init=$1 ;; --require-init) - require_init=1 + require_init=$1 ;; --remote) - remote=1 + remote=$1 ;; -N|--no-fetch) - nofetch=1 + no_fetch=$1 ;; -f|--force) force=$1 ;; -r|--rebase) - rebase=1 + rebase=$1 ;; --ref-format) case "$2" in '') usage ;; esac @@ -316,22 +319,19 @@ cmd_update() reference="$1" ;; --dissociate) - dissociate=1 + dissociate=$1 ;; -m|--merge) - merge=1 + merge=$1 ;; --recursive) - recursive=1 + recursive=$1 ;; --checkout) - checkout=1 - ;; - --recommend-shallow) - recommend_shallow="--recommend-shallow" + checkout=$1 ;; - --no-recommend-shallow) - recommend_shallow="--no-recommend-shallow" + --recommend-shallow|--no-recommend-shallow) + recommend_shallow=$1 ;; --depth) case "$2" in '') usage ;; esac @@ -339,21 +339,18 @@ cmd_update() shift ;; --depth=*) - depth=$1 + depth="$1" ;; -j|--jobs) case "$2" in '') usage ;; esac jobs="--jobs=$2" shift ;; - --jobs=*) - jobs=$1 + -j*|--jobs=*) + jobs="$1" ;; - --single-branch) - single_branch="--single-branch" - ;; - --no-single-branch) - single_branch="--no-single-branch" + --single-branch|--no-single-branch) + single_branch=$1 ;; --filter) case "$2" in '') usage ;; esac @@ -378,22 +375,21 @@ cmd_update() done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update \ - ${quiet:+--quiet} \ - ${force:+--force} \ - ${progress:+"--progress"} \ - ${remote:+--remote} \ - ${recursive:+--recursive} \ - ${init:+--init} \ - ${nofetch:+--no-fetch} \ - ${rebase:+--rebase} \ - ${merge:+--merge} \ - ${checkout:+--checkout} \ + $quiet \ + $force \ + $progress \ + $remote \ + $recursive \ + $init \ + $no_fetch \ + $rebase \ + $merge \ + $checkout \ ${ref_format:+"$ref_format"} \ ${reference:+"$reference"} \ - ${dissociate:+"--dissociate"} \ + $dissociate \ ${depth:+"$depth"} \ - ${require_init:+--require-init} \ - ${dissociate:+"--dissociate"} \ + $require_init \ $single_branch \ $recommend_shallow \ $jobs \ @@ -408,9 +404,7 @@ cmd_update() # $@ = requested path # cmd_set_branch() { - default= - branch= - + # parse $args after "submodule ... set-branch". while test $# -ne 0 do case "$1" in @@ -418,13 +412,16 @@ cmd_set_branch() { # we don't do anything with this but we need to accept it ;; -d|--default) - default=1 + default=$1 ;; -b|--branch) case "$2" in '') usage ;; esac - branch=$2 + branch="--branch=$2" shift ;; + -b*|--branch=*) + branch="$1" + ;; --) shift break @@ -440,9 +437,9 @@ cmd_set_branch() { done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-branch \ - ${quiet:+--quiet} \ - ${branch:+--branch "$branch"} \ - ${default:+--default} \ + $quiet \ + ${branch:+"$branch"} \ + $default \ -- \ "$@" } @@ -453,11 +450,12 @@ cmd_set_branch() { # $@ = requested path, requested url # cmd_set_url() { + # parse $args after "submodule ... set-url". while test $# -ne 0 do case "$1" in -q|--quiet) - quiet=1 + quiet=$1 ;; --) shift @@ -474,7 +472,7 @@ cmd_set_url() { done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-url \ - ${quiet:+--quiet} \ + $quiet \ -- \ "$@" } @@ -488,31 +486,26 @@ cmd_set_url() { # $@ = [commit (default 'HEAD'),] requested paths (default all) # cmd_summary() { - summary_limit=-1 - for_status= - diff_cmd=diff-index - # parse $args after "submodule ... summary". while test $# -ne 0 do case "$1" in --cached) - cached=1 + cached=$1 ;; --files) - files="$1" + files=$1 ;; --for-status) - for_status="$1" + for_status=$1 ;; -n|--summary-limit) - summary_limit="$2" - isnumber "$summary_limit" || usage + case "$2" in '') usage ;; esac + summary_limit="--summary-limit=$2" shift ;; - --summary-limit=*) - summary_limit="${1#--summary-limit=}" - isnumber "$summary_limit" || usage + -n*|--summary-limit=*) + summary_limit="$1" ;; --) shift @@ -529,10 +522,10 @@ cmd_summary() { done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary \ - ${files:+--files} \ - ${cached:+--cached} \ - ${for_status:+--for-status} \ - ${summary_limit:+-n $summary_limit} \ + $files \ + $cached \ + $for_status \ + ${summary_limit:+"$summary_limit"} \ -- \ "$@" } @@ -553,13 +546,13 @@ cmd_status() do case "$1" in -q|--quiet) - quiet=1 + quiet=$1 ;; --cached) - cached=1 + cached=$1 ;; --recursive) - recursive=1 + recursive=$1 ;; --) shift @@ -576,9 +569,9 @@ cmd_status() done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper status \ - ${quiet:+--quiet} \ - ${cached:+--cached} \ - ${recursive:+--recursive} \ + $quiet \ + $cached \ + $recursive \ -- \ "$@" } @@ -590,15 +583,16 @@ cmd_status() # cmd_sync() { + # parse $args after "submodule ... sync". while test $# -ne 0 do case "$1" in -q|--quiet) - quiet=1 + quiet=$1 shift ;; --recursive) - recursive=1 + recursive=$1 shift ;; --) @@ -615,8 +609,8 @@ cmd_sync() done git ${wt_prefix:+-C "$wt_prefix"} submodule--helper sync \ - ${quiet:+--quiet} \ - ${recursive:+--recursive} \ + $quiet \ + $recursive \ -- \ "$@" } @@ -639,10 +633,10 @@ do command=$1 ;; -q|--quiet) - quiet=1 + quiet=$1 ;; --cached) - cached=1 + cached=$1 ;; --) break diff --git a/git-svn.perl b/git-svn.perl index 01e7a70de1c0eb..32c648c3956fa4 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.008001; +require v5.26; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); use strict; use vars qw/ $AUTHOR $VERSION @@ -9,7 +9,7 @@ $_revision $_repository $_q $_authors $_authors_prog %users/; $AUTHOR = 'Eric Wong <normalperson@yhbt.net>'; -$VERSION = '@@GIT_VERSION@@'; +$VERSION = '@GIT_VERSION@'; use Carp qw/croak/; use File::Basename qw/dirname basename/; diff --git a/git-zlib.c b/git-zlib.c index d43bbeb6daa4c1..651dd9e07cd1bf 100644 --- a/git-zlib.c +++ b/git-zlib.c @@ -59,7 +59,8 @@ static void zlib_post_call(git_zstream *s) s->total_out = s->z.total_out; s->total_in = s->z.total_in; - s->next_in = s->z.next_in; + /* zlib-ng marks `next_in` as `const`, so we have to cast it away. */ + s->next_in = (unsigned char *) s->z.next_in; s->next_out = s->z.next_out; s->avail_in -= bytes_consumed; s->avail_out -= bytes_produced; @@ -147,10 +148,6 @@ int git_inflate(git_zstream *strm, int flush) return status; } -#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200 -#define deflateBound(c,s) ((s) + (((s) + 7) >> 3) + (((s) + 63) >> 6) + 11) -#endif - unsigned long git_deflate_bound(git_zstream *strm, unsigned long size) { return deflateBound(&strm->z, size); diff --git a/git-zlib.h b/git-zlib.h index d8a670aff9fbc4..1e8d9aabcb4cb2 100644 --- a/git-zlib.h +++ b/git-zlib.h @@ -1,6 +1,8 @@ #ifndef GIT_ZLIB_H #define GIT_ZLIB_H +#include "compat/zlib-compat.h" + typedef struct git_zstream { z_stream z; unsigned long avail_in; diff --git a/git.c b/git.c index 2fbea24ec921e0..f969a76e8c9831 100644 --- a/git.c +++ b/git.c @@ -55,7 +55,7 @@ static void list_builtins(struct string_list *list, unsigned int exclude_option) static void exclude_helpers_from_list(struct string_list *list) { - int i = 0; + size_t i = 0; while (i < list->nr) { if (strstr(list->items[i].string, "--")) @@ -75,7 +75,6 @@ static int match_token(const char *spec, int len, const char *token) static int list_cmds(const char *spec) { struct string_list list = STRING_LIST_INIT_DUP; - int i; int nongit; /* @@ -113,7 +112,7 @@ static int list_cmds(const char *spec) if (*spec == ',') spec++; } - for (i = 0; i < list.nr; i++) + for (size_t i = 0; i < list.nr; i++) puts(list.items[i].string); string_list_clear(&list, 0); return 0; @@ -126,7 +125,7 @@ static void commit_pager_choice(void) setenv("GIT_PAGER", "cat", 1); break; case 1: - setup_pager(); + setup_pager(the_repository); break; default: break; @@ -137,7 +136,7 @@ void setup_auto_pager(const char *cmd, int def) { if (use_pager != -1 || pager_in_use()) return; - use_pager = check_pager_config(cmd); + use_pager = check_pager_config(the_repository, cmd); if (use_pager == -1) use_pager = def; commit_pager_choice(); @@ -322,10 +321,9 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) trace2_cmd_name("_query_"); if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; - int i; list_builtins(&list, NO_PARSEOPT); - for (i = 0; i < list.nr; i++) + for (size_t i = 0; i < list.nr; i++) printf("%s ", list.items[i].string); string_list_clear(&list, 0); exit(0); @@ -362,7 +360,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) return (*argv) - orig_argv; } -static int handle_alias(int *argcp, const char ***argv) +static int handle_alias(struct strvec *args) { int envchanged = 0, ret = 0, saved_errno = errno; int count, option_count; @@ -370,10 +368,10 @@ static int handle_alias(int *argcp, const char ***argv) const char *alias_command; char *alias_string; - alias_command = (*argv)[0]; + alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { - if (*argcp > 1 && !strcmp((*argv)[1], "-h")) + if (args->nr > 1 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); if (alias_string[0] == '!') { @@ -390,7 +388,7 @@ static int handle_alias(int *argcp, const char ***argv) child.wait_after_clean = 1; child.trace2_child_class = "shell_alias"; strvec_push(&child.args, alias_string + 1); - strvec_pushv(&child.args, (*argv) + 1); + strvec_pushv(&child.args, args->v + 1); trace2_cmd_alias(alias_command, child.args.v); trace2_cmd_name("_run_shell_alias_"); @@ -423,15 +421,13 @@ static int handle_alias(int *argcp, const char ***argv) trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); - - REALLOC_ARRAY(new_argv, count + *argcp); - /* insert after command name */ - COPY_ARRAY(new_argv + count, *argv + 1, *argcp); - trace2_cmd_alias(alias_command, new_argv); - *argv = new_argv; - *argcp += count - 1; + /* Replace the alias with the new arguments. */ + strvec_splice(args, 0, 1, new_argv, count); + + free(alias_string); + free(new_argv); ret = 1; } @@ -444,6 +440,7 @@ static int handle_alias(int *argcp, const char ***argv) static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct repository *repo) { int status, help; + int no_repo = 1; struct stat st; const char *prefix; int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY)); @@ -455,9 +452,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct if (run_setup & RUN_SETUP) { prefix = setup_git_directory(); + no_repo = 0; } else if (run_setup & RUN_SETUP_GENTLY) { - int nongit_ok; - prefix = setup_git_directory_gently(&nongit_ok); + prefix = setup_git_directory_gently(&no_repo); } else { prefix = NULL; } @@ -465,12 +462,12 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct precompose_argv_prefix(argc, argv, NULL); if (use_pager == -1 && run_setup && !(p->option & DELAY_PAGER_CONFIG)) - use_pager = check_pager_config(p->cmd); + use_pager = check_pager_config(the_repository, p->cmd); if (use_pager == -1 && p->option & USE_PAGER) use_pager = 1; if (run_setup && startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */ - trace_repo_setup(); + trace_repo_setup(the_repository); commit_pager_choice(); if (!help && p->option & NEED_WORK_TREE) @@ -480,7 +477,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct trace2_cmd_name(p->cmd); validate_cache_entries(repo->index); - status = p->fn(argc, argv, prefix, (p->option & RUN_SETUP)? repo : NULL); + status = p->fn(argc, argv, prefix, no_repo ? NULL : repo); validate_cache_entries(repo->index); if (status) @@ -509,6 +506,7 @@ static struct cmd_struct commands[] = { { "annotate", cmd_annotate, RUN_SETUP }, { "apply", cmd_apply, RUN_SETUP_GENTLY }, { "archive", cmd_archive, RUN_SETUP_GENTLY }, + { "backfill", cmd_backfill, RUN_SETUP }, { "bisect", cmd_bisect, RUN_SETUP }, { "blame", cmd_blame, RUN_SETUP }, { "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG }, @@ -590,7 +588,9 @@ static struct cmd_struct commands[] = { { "name-rev", cmd_name_rev, RUN_SETUP }, { "notes", cmd_notes, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP }, +#ifndef WITH_BREAKING_CHANGES { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, +#endif { "pack-refs", cmd_pack_refs, RUN_SETUP }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "pickaxe", cmd_blame, RUN_SETUP }, @@ -629,6 +629,7 @@ static struct cmd_struct commands[] = { { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, { "stripspace", cmd_stripspace }, { "submodule--helper", cmd_submodule__helper, RUN_SETUP }, + { "survey", cmd_survey, RUN_SETUP }, { "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE }, { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, { "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG }, @@ -652,8 +653,7 @@ static struct cmd_struct commands[] = { static struct cmd_struct *get_builtin(const char *s) { - int i; - for (i = 0; i < ARRAY_SIZE(commands); i++) { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { struct cmd_struct *p = commands + i; if (!strcmp(s, p->cmd)) return p; @@ -668,8 +668,7 @@ int is_builtin(const char *s) static void list_builtins(struct string_list *out, unsigned int exclude_option) { - int i; - for (i = 0; i < ARRAY_SIZE(commands); i++) { + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) { if (exclude_option && (commands[i].option & exclude_option)) continue; @@ -680,7 +679,6 @@ static void list_builtins(struct string_list *out, unsigned int exclude_option) void load_builtin_commands(const char *prefix, struct cmdnames *cmds) { const char *name; - int i; /* * Callers can ask for a subset of the commands based on a certain @@ -691,53 +689,63 @@ void load_builtin_commands(const char *prefix, struct cmdnames *cmds) if (!skip_prefix(prefix, "git-", &prefix)) BUG("prefix '%s' must start with 'git-'", prefix); - for (i = 0; i < ARRAY_SIZE(commands); i++) + for (size_t i = 0; i < ARRAY_SIZE(commands); i++) if (skip_prefix(commands[i].cmd, prefix, &name)) add_cmdname(cmds, name, strlen(name)); } #ifdef STRIP_EXTENSION -static void strip_extension(const char **argv) +static void strip_extension(struct strvec *args) { size_t len; - if (strip_suffix(argv[0], STRIP_EXTENSION, &len)) - argv[0] = xmemdupz(argv[0], len); + if (strip_suffix(args->v[0], STRIP_EXTENSION, &len)) { + char *stripped = xmemdupz(args->v[0], len); + strvec_replace(args, 0, stripped); + free(stripped); + } } #else #define strip_extension(cmd) #endif -static void handle_builtin(int argc, const char **argv) +static void handle_builtin(struct strvec *args) { - struct strvec args = STRVEC_INIT; const char *cmd; struct cmd_struct *builtin; - strip_extension(argv); - cmd = argv[0]; + strip_extension(args); + cmd = args->v[0]; /* Turn "git cmd --help" into "git help --exclude-guides cmd" */ - if (argc > 1 && !strcmp(argv[1], "--help")) { - int i; + if (args->nr > 1 && !strcmp(args->v[1], "--help")) { + const char *exclude_guides_arg[] = { "--exclude-guides" }; + + strvec_replace(args, 1, args->v[0]); + strvec_replace(args, 0, "help"); + cmd = "help"; + strvec_splice(args, 2, 0, exclude_guides_arg, + ARRAY_SIZE(exclude_guides_arg)); + } - argv[1] = argv[0]; - argv[0] = cmd = "help"; + builtin = get_builtin(cmd); + if (builtin) { + const char **argv_copy = NULL; + int ret; - for (i = 0; i < argc; i++) { - strvec_push(&args, argv[i]); - if (!i) - strvec_push(&args, "--exclude-guides"); - } + /* + * `run_builtin()` will modify the argv array, so we need to + * create a shallow copy such that we can free all of its + * strings. + */ + if (args->nr) + DUP_ARRAY(argv_copy, args->v, args->nr + 1); - argc++; - argv = args.v; + ret = run_builtin(builtin, args->nr, argv_copy, the_repository); + strvec_clear(args); + free(argv_copy); + exit(ret); } - - builtin = get_builtin(cmd); - if (builtin) - exit(run_builtin(builtin, argc, argv, the_repository)); - strvec_clear(&args); } static void execv_dashed_external(const char **argv) @@ -746,7 +754,7 @@ static void execv_dashed_external(const char **argv) int status; if (use_pager == -1 && !is_builtin(argv[0])) - use_pager = check_pager_config(argv[0]); + use_pager = check_pager_config(the_repository, argv[0]); commit_pager_choice(); strvec_pushf(&cmd.args, "git-%s", argv[0]); @@ -783,10 +791,10 @@ static void execv_dashed_external(const char **argv) exit(128); } -static int run_argv(int *argcp, const char ***argv) +static int run_argv(struct strvec *args) { int done_alias = 0; - struct string_list cmd_list = STRING_LIST_INIT_NODUP; + struct string_list cmd_list = STRING_LIST_INIT_DUP; struct string_list_item *seen; while (1) { @@ -800,10 +808,10 @@ static int run_argv(int *argcp, const char ***argv) * process. */ if (!done_alias) - handle_builtin(*argcp, *argv); - else if (get_builtin(**argv)) { + handle_builtin(args); + else if (get_builtin(args->v[0])) { struct child_process cmd = CHILD_PROCESS_INIT; - int i; + int err; /* * The current process is committed to launching a @@ -817,8 +825,8 @@ static int run_argv(int *argcp, const char ***argv) commit_pager_choice(); strvec_push(&cmd.args, "git"); - for (i = 0; i < *argcp; i++) - strvec_push(&cmd.args, (*argv)[i]); + for (size_t i = 0; i < args->nr; i++) + strvec_push(&cmd.args, args->v[i]); trace_argv_printf(cmd.args.v, "trace: exec:"); @@ -830,20 +838,19 @@ static int run_argv(int *argcp, const char ***argv) cmd.clean_on_exit = 1; cmd.wait_after_clean = 1; cmd.trace2_child_class = "git_alias"; - i = run_command(&cmd); - if (i >= 0 || errno != ENOENT) - exit(i); - die("could not execute builtin %s", **argv); + err = run_command(&cmd); + if (err >= 0 || errno != ENOENT) + exit(err); + die("could not execute builtin %s", args->v[0]); } /* .. then try the external ones */ - execv_dashed_external(*argv); + execv_dashed_external(args->v); - seen = unsorted_string_list_lookup(&cmd_list, *argv[0]); + seen = unsorted_string_list_lookup(&cmd_list, args->v[0]); if (seen) { - int i; struct strbuf sb = STRBUF_INIT; - for (i = 0; i < cmd_list.nr; i++) { + for (size_t i = 0; i < cmd_list.nr; i++) { struct string_list_item *item = &cmd_list.items[i]; strbuf_addf(&sb, "\n %s", item->string); @@ -856,14 +863,14 @@ static int run_argv(int *argcp, const char ***argv) " not terminate:%s"), cmd_list.items[0].string, sb.buf); } - string_list_append(&cmd_list, *argv[0]); + string_list_append(&cmd_list, args->v[0]); /* * It could be an alias -- this works around the insanity * of overriding "git log" with "git show" by having * alias.log = show */ - if (!handle_alias(argcp, argv)) + if (!handle_alias(args)) break; done_alias = 1; } @@ -875,6 +882,7 @@ static int run_argv(int *argcp, const char ***argv) int cmd_main(int argc, const char **argv) { + struct strvec args = STRVEC_INIT; const char *cmd; int done_help = 0; @@ -900,8 +908,10 @@ int cmd_main(int argc, const char **argv) * that one cannot handle it. */ if (skip_prefix(cmd, "git-", &cmd)) { - argv[0] = cmd; - handle_builtin(argc, argv); + strvec_push(&args, cmd); + strvec_pushv(&args, argv + 1); + handle_builtin(&args); + strvec_clear(&args); die(_("cannot handle %s as a builtin"), cmd); } @@ -934,25 +944,34 @@ int cmd_main(int argc, const char **argv) */ setup_path(); + for (int i = 0; i < argc; i++) + strvec_push(&args, argv[i]); + while (1) { - int was_alias = run_argv(&argc, &argv); + int was_alias = run_argv(&args); if (errno != ENOENT) break; if (was_alias) { fprintf(stderr, _("expansion of alias '%s' failed; " "'%s' is not a git command\n"), - cmd, argv[0]); + cmd, args.v[0]); + strvec_clear(&args); exit(1); } if (!done_help) { - cmd = argv[0] = help_unknown_cmd(cmd); + char *assumed = help_unknown_cmd(cmd); + strvec_replace(&args, 0, assumed); + free(assumed); + cmd = args.v[0]; done_help = 1; - } else + } else { break; + } } fprintf(stderr, _("failed to run command '%s': %s\n"), cmd, strerror(errno)); + strvec_clear(&args); return 1; } diff --git a/git.rc b/git.rc.in similarity index 67% rename from git.rc rename to git.rc.in index cc3fdc6cc6cb83..e69444eef3f0c5 100644 --- a/git.rc +++ b/git.rc.in @@ -1,6 +1,6 @@ 1 VERSIONINFO -FILEVERSION MAJOR,MINOR,MICRO,PATCHLEVEL -PRODUCTVERSION MAJOR,MINOR,MICRO,PATCHLEVEL +FILEVERSION @GIT_MAJOR_VERSION@,@GIT_MINOR_VERSION@,@GIT_MICRO_VERSION@,@GIT_PATCH_LEVEL@ +PRODUCTVERSION @GIT_MAJOR_VERSION@,@GIT_MINOR_VERSION@,@GIT_MICRO_VERSION@,@GIT_PATCH_LEVEL@ BEGIN BLOCK "StringFileInfo" BEGIN @@ -11,7 +11,7 @@ BEGIN VALUE "InternalName", "git\0" VALUE "OriginalFilename", "git.exe\0" VALUE "ProductName", "Git\0" - VALUE "ProductVersion", GIT_VERSION "\0" + VALUE "ProductVersion", "@GIT_VERSION@\0" END END diff --git a/gitk-git/Makefile b/gitk-git/Makefile index e1f0aff4a191d3..3a3c56c318bad6 100644 --- a/gitk-git/Makefile +++ b/gitk-git/Makefile @@ -8,6 +8,7 @@ gitk_libdir ?= $(sharedir)/gitk/lib msgsdir ?= $(gitk_libdir)/msgs msgsdir_SQ = $(subst ','\'',$(msgsdir)) +SHELL_PATH ?= /bin/sh TCL_PATH ?= tclsh TCLTK_PATH ?= wish INSTALL ?= install @@ -64,9 +65,7 @@ clean:: gitk-wish: gitk GIT-TCLTK-VARS $(QUIET_GEN)$(RM) $@ $@+ && \ - sed -e '1,3s|^exec .* "$$0"|exec $(subst |,'\|',$(TCLTK_PATH_SQ)) "$$0"|' <gitk >$@+ && \ - chmod +x $@+ && \ - mv -f $@+ $@ + $(SHELL_PATH) ./generate-tcl.sh "$(TCLTK_PATH_SQ)" "$<" "$@" $(PO_TEMPLATE): gitk $(XGETTEXT) -kmc -LTcl -o $@ gitk diff --git a/gitk-git/generate-tcl.sh b/gitk-git/generate-tcl.sh new file mode 100755 index 00000000000000..46bba6d246468a --- /dev/null +++ b/gitk-git/generate-tcl.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +WISH=$(echo "$1" | sed 's/|/\\|/g') +INPUT="$2" +OUTPUT="$3" + +sed -e "1,3s|^exec .* \"\$0\"|exec $WISH \"\$0\"|" "$INPUT" >"$OUTPUT"+ +chmod a+x "$OUTPUT"+ +mv "$OUTPUT"+ "$OUTPUT" diff --git a/gitk-git/gitk b/gitk-git/gitk index 7a087f123d7563..bc9efa18566fb8 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -9,6 +9,141 @@ exec wish "$0" -- "$@" package require Tk +###################################################################### +## +## Enabling platform-specific code paths + +proc is_MacOSX {} { + if {[tk windowingsystem] eq {aqua}} { + return 1 + } + return 0 +} + +proc is_Windows {} { + if {$::tcl_platform(platform) eq {windows}} { + return 1 + } + return 0 +} + +set _iscygwin {} +proc is_Cygwin {} { + global _iscygwin + if {$_iscygwin eq {}} { + if {[string match "CYGWIN_*" $::tcl_platform(os)]} { + set _iscygwin 1 + } else { + set _iscygwin 0 + } + } + return $_iscygwin +} + +###################################################################### +## +## PATH lookup + +set _search_path {} +proc _which {what args} { + global env _search_exe _search_path + + if {$_search_path eq {}} { + if {[is_Cygwin] && [regexp {^(/|\.:)} $env(PATH)]} { + set _search_path [split [exec cygpath \ + --windows \ + --path \ + --absolute \ + $env(PATH)] {;}] + set _search_exe .exe + } elseif {[is_Windows]} { + set gitguidir [file dirname [info script]] + regsub -all ";" $gitguidir "\\;" gitguidir + set env(PATH) "$gitguidir;$env(PATH)" + set _search_path [split $env(PATH) {;}] + # Skip empty `PATH` elements + set _search_path [lsearch -all -inline -not -exact \ + $_search_path ""] + set _search_exe .exe + } else { + set _search_path [split $env(PATH) :] + set _search_exe {} + } + } + + if {[is_Windows] && [lsearch -exact $args -script] >= 0} { + set suffix {} + } else { + set suffix $_search_exe + } + + foreach p $_search_path { + set p [file join $p $what$suffix] + if {[file exists $p]} { + return [file normalize $p] + } + } + return {} +} + +proc sanitize_command_line {command_line from_index} { + set i $from_index + while {$i < [llength $command_line]} { + set cmd [lindex $command_line $i] + if {[file pathtype $cmd] ne "absolute"} { + set fullpath [_which $cmd] + if {$fullpath eq ""} { + throw {NOT-FOUND} "$cmd not found in PATH" + } + lset command_line $i $fullpath + } + + # handle piped commands, e.g. `exec A | B` + for {incr i} {$i < [llength $command_line]} {incr i} { + if {[lindex $command_line $i] eq "|"} { + incr i + break + } + } + } + return $command_line +} + +# Override `exec` to avoid unsafe PATH lookup + +rename exec real_exec + +proc exec {args} { + # skip options + for {set i 0} {$i < [llength $args]} {incr i} { + set arg [lindex $args $i] + if {$arg eq "--"} { + incr i + break + } + if {[string range $arg 0 0] ne "-"} { + break + } + } + set args [sanitize_command_line $args $i] + uplevel 1 real_exec $args +} + +# Override `open` to avoid unsafe PATH lookup + +rename open real_open + +proc open {args} { + set arg0 [lindex $args 0] + if {[string range $arg0 0 0] eq "|"} { + set command_line [string trim [string range $arg0 1 end]] + lset args 0 "| [sanitize_command_line $command_line 0]" + } + uplevel 1 real_open $args +} + +# End of safe PATH lookup stuff + proc hasworktree {} { return [expr {[exec git rev-parse --is-bare-repository] == "false" && [exec git rev-parse --is-inside-git-dir] == "false"}] @@ -1969,6 +2104,10 @@ proc confirm_popup {msg {owner .}} { return $confirm_ok } +proc haveselectionclipboard {} { + return [expr {[tk windowingsystem] eq "x11"}] +} + proc setoptions {} { global use_ttk @@ -2089,7 +2228,7 @@ proc makewindow {} { global diffcontextstring diffcontext global ignorespace global maincursor textcursor curtextcursor - global rowctxmenu fakerowmenu mergemax wrapcomment + global rowctxmenu fakerowmenu mergemax wrapcomment wrapdefault global highlight_files gdttype global searchstring sstring global bgcolor fgcolor bglist fglist diffcolors diffbgcolors selectbgcolor @@ -2099,7 +2238,7 @@ proc makewindow {} { global headctxmenu progresscanv progressitem progresscoords statusw global fprogitem fprogcoord lastprogupdate progupdatepending global rprogitem rprogcoord rownumsel numcommits - global have_tk85 use_ttk NS + global have_tk85 have_tk86 use_ttk NS global git_version global worddiff @@ -2223,7 +2362,7 @@ proc makewindow {} { set sha1entry .tf.bar.sha1 set entries $sha1entry set sha1but .tf.bar.sha1label - button $sha1but -text "[mc "SHA1 ID:"] " -state disabled -relief flat \ + button $sha1but -text "[mc "Commit ID:"] " -state disabled -relief flat \ -command gotocommit -width 8 $sha1but conf -disabledforeground [$sha1but cget -foreground] pack .tf.bar.sha1label -side left @@ -2431,7 +2570,7 @@ proc makewindow {} { set ctext .bleft.bottom.ctext text $ctext -background $bgcolor -foreground $fgcolor \ -state disabled -undo 0 -font textfont \ - -yscrollcommand scrolltext -wrap none \ + -yscrollcommand scrolltext -wrap $wrapdefault \ -xscrollcommand ".bleft.bottom.sbhorizontal set" if {$have_tk85} { $ctext conf -tabstyle wordprocessor @@ -2597,8 +2736,13 @@ proc makewindow {} { bind . <Key-Down> "selnextline 1" bind . <Shift-Key-Up> "dofind -1 0" bind . <Shift-Key-Down> "dofind 1 0" - bindkey <Key-Right> "goforw" - bindkey <Key-Left> "goback" + if {$have_tk86} { + bindkey <<NextChar>> "goforw" + bindkey <<PrevChar>> "goback" + } else { + bindkey <Key-Right> "goforw" + bindkey <Key-Left> "goback" + } bind . <Key-Prior> "selnextpage -1" bind . <Key-Next> "selnextpage 1" bind . <$M1B-Home> "allcanvs yview moveto 0.0" @@ -7344,7 +7488,7 @@ proc selectline {l isnew {desired_loc {}} {switch_to_patch 0}} { global mergemax numcommits pending_select global cmitmode showneartags allcommits global targetrow targetid lastscrollrows - global autoselect autosellen jump_to_here + global autocopy autoselect autosellen jump_to_here global vinlinediff unset -nocomplain pending_select @@ -7410,9 +7554,13 @@ proc selectline {l isnew {desired_loc {}} {switch_to_patch 0}} { $sha1entry delete 0 end $sha1entry insert 0 $id - if {$autoselect} { + if {$autoselect && [haveselectionclipboard]} { $sha1entry selection range 0 $autosellen } + if {$autocopy} { + clipboard clear + clipboard append [string range $id 0 [expr $autosellen - 1]] + } rhighlight_sel $id $ctext conf -state normal @@ -7712,7 +7860,7 @@ proc gettreeline {gtf id} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] lappend treefilelist($id) $fname } if {![eof $gtf]} { @@ -7974,7 +8122,7 @@ proc gettreediffline {gdtf ids} { if {[string index $file 0] eq "\""} { set file [lindex $file 0] } - set file [encoding convertfrom $file] + set file [encoding convertfrom utf-8 $file] if {$file ne [lindex $treediff end]} { lappend treediff $file lappend sublist $file @@ -8119,7 +8267,7 @@ proc makediffhdr {fname ids} { global ctext curdiffstart treediffs diffencoding global ctext_file_names jump_to_here targetline diffline - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] set diffencoding [get_path_encoding $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { @@ -8181,7 +8329,7 @@ proc parseblobdiffline {ids line} { if {![string compare -length 5 "diff " $line]} { if {![regexp {^diff (--cc|--git) } $line m type]} { - set line [encoding convertfrom $line] + set line [encoding convertfrom utf-8 $line] $ctext insert end "$line\n" hunksep continue } @@ -8230,7 +8378,7 @@ proc parseblobdiffline {ids line} { makediffhdr $fname $ids } elseif {![string compare -length 16 "* Unmerged path " $line]} { - set fname [encoding convertfrom [string range $line 16 end]] + set fname [encoding convertfrom utf-8 [string range $line 16 end]] $ctext insert end "\n" set curdiffstart [$ctext index "end - 1c"] lappend ctext_file_names $fname @@ -8283,7 +8431,7 @@ proc parseblobdiffline {ids line} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom $fname] + set fname [encoding convertfrom utf-8 $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { setinlist difffilestart $i $curdiffstart @@ -8302,6 +8450,7 @@ proc parseblobdiffline {ids line} { set diffinhdr 0 return } + set line [encoding convertfrom utf-8 $line] $ctext insert end "$line\n" filesep } else { @@ -8756,7 +8905,7 @@ proc sha1change {n1 n2 op} { if {$state == "normal"} { $sha1but conf -state normal -relief raised -text "[mc "Goto:"] " } else { - $sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] " + $sha1but conf -state disabled -relief flat -text "[mc "Commit ID:"] " } } @@ -8775,7 +8924,7 @@ proc gotocommit {} { set matches [longid $id] if {$matches ne {}} { if {[llength $matches] > 1} { - error_popup [mc "Short SHA1 id %s is ambiguous" $id] + error_popup [mc "Short commit ID %s is ambiguous" $id] return } set id [lindex $matches 0] @@ -8792,7 +8941,7 @@ proc gotocommit {} { return } if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} { - set msg [mc "SHA1 id %s is not known" $sha1string] + set msg [mc "Commit ID %s is not known" $sha1string] } else { set msg [mc "Revision %s is not in the current view" $sha1string] } @@ -10060,7 +10209,7 @@ proc showrefs {} { text $top.list -background $bgcolor -foreground $fgcolor \ -selectbackground $selectbgcolor -font mainfont \ -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \ - -width 30 -height 20 -cursor $maincursor \ + -width 60 -height 20 -cursor $maincursor \ -spacing1 1 -spacing3 1 -state disabled $top.list tag configure highlight -background $selectbgcolor if {![lsearch -exact $bglist $top.list]} { @@ -11576,12 +11725,13 @@ proc create_prefs_page {w} { proc prefspage_general {notebook} { global NS maxwidth maxgraphpct showneartags showlocalchanges - global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs + global tabstop wrapcomment wrapdefault limitdiffs + global autocopy autoselect autosellen extdifftool perfile_attrs global hideremotes want_ttk have_ttk maxrefs web_browser set page [create_prefs_page $notebook.general] - ${NS}::label $page.ldisp -text [mc "Commit list display options"] + ${NS}::label $page.ldisp -text [mc "Commit list display options"] -font mainfontbold grid $page.ldisp - -sticky w -pady 10 ${NS}::label $page.spacer -text " " ${NS}::label $page.maxwidthl -text [mc "Maximum graph width (lines)"] @@ -11594,19 +11744,38 @@ proc prefspage_general {notebook} { ${NS}::checkbutton $page.showlocal -text [mc "Show local changes"] \ -variable showlocalchanges grid x $page.showlocal -sticky w - ${NS}::checkbutton $page.autoselect -text [mc "Auto-select SHA1 (length)"] \ - -variable autoselect - spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen - grid x $page.autoselect $page.autosellen -sticky w ${NS}::checkbutton $page.hideremotes -text [mc "Hide remote refs"] \ -variable hideremotes grid x $page.hideremotes -sticky w - ${NS}::label $page.ddisp -text [mc "Diff display options"] + ${NS}::checkbutton $page.autocopy -text [mc "Copy commit ID to clipboard"] \ + -variable autocopy + grid x $page.autocopy -sticky w + if {[haveselectionclipboard]} { + ${NS}::checkbutton $page.autoselect -text [mc "Copy commit ID to X11 selection"] \ + -variable autoselect + grid x $page.autoselect -sticky w + } + spinbox $page.autosellen -from 1 -to 40 -width 4 -textvariable autosellen + ${NS}::label $page.autosellenl -text [mc "Length of commit ID to copy"] + grid x $page.autosellenl $page.autosellen -sticky w + + ${NS}::label $page.ddisp -text [mc "Diff display options"] -font mainfontbold grid $page.ddisp - -sticky w -pady 10 ${NS}::label $page.tabstopl -text [mc "Tab spacing"] spinbox $page.tabstop -from 1 -to 20 -width 4 -textvariable tabstop grid x $page.tabstopl $page.tabstop -sticky w + + ${NS}::label $page.wrapcommentl -text [mc "Wrap comment text"] + ${NS}::combobox $page.wrapcomment -values {none char word} -state readonly \ + -textvariable wrapcomment + grid x $page.wrapcommentl $page.wrapcomment -sticky w + + ${NS}::label $page.wrapdefaultl -text [mc "Wrap other text"] + ${NS}::combobox $page.wrapdefault -values {none char word} -state readonly \ + -textvariable wrapdefault + grid x $page.wrapdefaultl $page.wrapdefault -sticky w + ${NS}::checkbutton $page.ntag -text [mc "Display nearby tags/heads"] \ -variable showneartags grid x $page.ntag -sticky w @@ -11635,7 +11804,7 @@ proc prefspage_general {notebook} { pack configure $page.webbrowserf.l -padx 10 grid x $page.webbrowserf $page.webbrowser -sticky ew - ${NS}::label $page.lgen -text [mc "General options"] + ${NS}::label $page.lgen -text [mc "General options"] -font mainfontbold grid $page.lgen - -sticky w -pady 10 ${NS}::checkbutton $page.want_ttk -variable want_ttk \ -text [mc "Use themed widgets"] @@ -11654,7 +11823,7 @@ proc prefspage_colors {notebook} { set page [create_prefs_page $notebook.colors] - ${NS}::label $page.cdisp -text [mc "Colors: press to choose"] + ${NS}::label $page.cdisp -text [mc "Colors: press to choose"] -font mainfontbold grid $page.cdisp - -sticky w -pady 10 label $page.ui -padx 40 -relief sunk -background $uicolor ${NS}::button $page.uibut -text [mc "Interface"] \ @@ -11712,7 +11881,7 @@ proc prefspage_colors {notebook} { proc prefspage_fonts {notebook} { global NS set page [create_prefs_page $notebook.fonts] - ${NS}::label $page.cfont -text [mc "Fonts: press to choose"] + ${NS}::label $page.cfont -text [mc "Fonts: press to choose"] -font mainfontbold grid $page.cfont - -sticky w -pady 10 mkfontdisp mainfont $page [mc "Main font"] mkfontdisp textfont $page [mc "Diff display font"] @@ -11725,7 +11894,7 @@ proc doprefs {} { global oldprefs prefstop showneartags showlocalchanges global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor global tabstop limitdiffs autoselect autosellen extdifftool perfile_attrs - global hideremotes want_ttk have_ttk + global hideremotes want_ttk have_ttk wrapcomment wrapdefault set top .gitkprefs set prefstop $top @@ -11734,7 +11903,7 @@ proc doprefs {} { return } foreach v {maxwidth maxgraphpct showneartags showlocalchanges \ - limitdiffs tabstop perfile_attrs hideremotes want_ttk} { + limitdiffs tabstop perfile_attrs hideremotes want_ttk wrapcomment wrapdefault} { set oldprefs($v) [set $v] } ttk_toplevel $top @@ -11860,7 +12029,7 @@ proc prefscan {} { global oldprefs prefstop foreach v {maxwidth maxgraphpct showneartags showlocalchanges \ - limitdiffs tabstop perfile_attrs hideremotes want_ttk} { + limitdiffs tabstop perfile_attrs hideremotes want_ttk wrapcomment wrapdefault} { global $v set $v $oldprefs($v) } @@ -11874,7 +12043,8 @@ proc prefsok {} { global oldprefs prefstop showneartags showlocalchanges global fontpref mainfont textfont uifont global limitdiffs treediffs perfile_attrs - global hideremotes + global hideremotes wrapcomment wrapdefault + global ctext catch {destroy $prefstop} unset prefstop @@ -11923,6 +12093,12 @@ proc prefsok {} { if {$hideremotes != $oldprefs(hideremotes)} { rereadrefs } + if {$wrapcomment != $oldprefs(wrapcomment)} { + $ctext tag conf comment -wrap $wrapcomment + } + if {$wrapdefault != $oldprefs(wrapdefault)} { + $ctext configure -wrap $wrapdefault + } } proc formatdate {d} { @@ -12270,7 +12446,7 @@ proc cache_gitattr {attr pathlist} { foreach row [split $rlist "\n"] { if {[regexp "(.*): $attr: (.*)" $row m path value]} { if {[string index $path 0] eq "\""} { - set path [encoding convertfrom [lindex $path 0]] + set path [encoding convertfrom utf-8 [lindex $path 0]] } set path_attr_cache($attr,$path) $value } @@ -12300,7 +12476,6 @@ if { [info exists ::env(GITK_MSGSDIR)] } { set gitk_prefix [file dirname [file dirname [file normalize $argv0]]] set gitk_libdir [file join $gitk_prefix share gitk lib] set gitk_msgsdir [file join $gitk_libdir msgs] - unset gitk_prefix } ## Internationalization (i18n) through msgcat and gettext. See @@ -12392,6 +12567,7 @@ set downarrowlen 5 set mingaplen 100 set cmitmode "patch" set wrapcomment "none" +set wrapdefault "none" set showneartags 1 set hideremotes 0 set maxrefs 20 @@ -12400,6 +12576,7 @@ set maxlinelen 200 set showlocalchanges 1 set limitdiffs 1 set datetimeformat "%Y-%m-%d %H:%M:%S" +set autocopy 0 set autoselect 1 set autosellen 40 set perfile_attrs 0 @@ -12497,7 +12674,8 @@ config_check_tmp_exists 50 set config_variables { mainfont textfont uifont tabstop findmergefiles maxgraphpct maxwidth - cmitmode wrapcomment autoselect autosellen showneartags maxrefs visiblerefs + cmitmode wrapcomment wrapdefault autocopy autoselect autosellen + showneartags maxrefs visiblerefs hideremotes showlocalchanges datetimeformat limitdiffs uicolor want_ttk bgcolor fgcolor uifgcolor uifgdisabledcolor colors diffcolors mergecolors markbgcolor diffcontext selectbgcolor foundbgcolor currentsearchhitbgcolor @@ -12599,6 +12777,7 @@ set nullid2 "0000000000000000000000000000000000000001" set nullfile "/dev/null" set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}] +set have_tk86 [expr {[package vcompare $tk_version "8.6"] >= 0}] if {![info exists have_ttk]} { set have_ttk [llength [info commands ::ttk::style]] } @@ -12663,31 +12842,35 @@ if {[expr {[exec git rev-parse --is-inside-work-tree] == "true"}]} { set worktree [gitworktree] setcoords makewindow -catch { - image create photo gitlogo -width 16 -height 16 +if {$::tcl_platform(platform) eq {windows} && [file exists $gitk_prefix/etc/git.ico]} { + wm iconbitmap . -default $gitk_prefix/etc/git.ico +} else { + catch { + image create photo gitlogo -width 16 -height 16 - image create photo gitlogominus -width 4 -height 2 - gitlogominus put #C00000 -to 0 0 4 2 - gitlogo copy gitlogominus -to 1 5 - gitlogo copy gitlogominus -to 6 5 - gitlogo copy gitlogominus -to 11 5 - image delete gitlogominus + image create photo gitlogominus -width 4 -height 2 + gitlogominus put #C00000 -to 0 0 4 2 + gitlogo copy gitlogominus -to 1 5 + gitlogo copy gitlogominus -to 6 5 + gitlogo copy gitlogominus -to 11 5 + image delete gitlogominus - image create photo gitlogoplus -width 4 -height 4 - gitlogoplus put #008000 -to 1 0 3 4 - gitlogoplus put #008000 -to 0 1 4 3 - gitlogo copy gitlogoplus -to 1 9 - gitlogo copy gitlogoplus -to 6 9 - gitlogo copy gitlogoplus -to 11 9 - image delete gitlogoplus + image create photo gitlogoplus -width 4 -height 4 + gitlogoplus put #008000 -to 1 0 3 4 + gitlogoplus put #008000 -to 0 1 4 3 + gitlogo copy gitlogoplus -to 1 9 + gitlogo copy gitlogoplus -to 6 9 + gitlogo copy gitlogoplus -to 11 9 + image delete gitlogoplus - image create photo gitlogo32 -width 32 -height 32 - gitlogo32 copy gitlogo -zoom 2 2 + image create photo gitlogo32 -width 32 -height 32 + gitlogo32 copy gitlogo -zoom 2 2 - wm iconphoto . -default gitlogo gitlogo32 + wm iconphoto . -default gitlogo gitlogo32 + } } # wait for the window to become visible -tkwait visibility . +if {![winfo viewable .]} {tkwait visibility .} set_window_title update readrefs diff --git a/gitk-git/meson.build b/gitk-git/meson.build new file mode 100644 index 00000000000000..ca3c0cec583247 --- /dev/null +++ b/gitk-git/meson.build @@ -0,0 +1,30 @@ +project('gitk') + +shell = find_program('sh') +wish = find_program('wish') + +# Verify that dependencies of "generate-tcl.sh" are satisfied. +foreach dependency : [ 'chmod', 'mv', 'sed' ] + find_program(dependency) +endforeach + +custom_target( + command: [ + shell, + meson.current_source_dir() / 'generate-tcl.sh', + wish.full_path(), + '@INPUT@', + '@OUTPUT@', + ], + input: 'gitk', + output: 'gitk', + depend_files: [ + 'generate-tcl.sh', + ], + install: true, + install_dir: get_option('bindir'), +) + +if find_program('msgfmt').found() + subdir('po') +endif diff --git a/gitk-git/po/bg.po b/gitk-git/po/bg.po index 87ab1fac24d6aa..773a04983116aa 100644 --- a/gitk-git/po/bg.po +++ b/gitk-git/po/bg.po @@ -1,15 +1,15 @@ # Bulgarian translation of gitk po-file. -# Copyright (C) 2014, 2015, 2019 Alexander Shopov <ash@kambanaria.org>. +# Copyright (C) 2014, 2015, 2019, 2020, 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, 2019. +# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2019, 2020, 2024. # # msgid "" msgstr "" "Project-Id-Version: gitk master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-04 11:27+0100\n" -"PO-Revision-Date: 2019-03-04 11:39+0100\n" +"POT-Creation-Date: 2024-12-24 11:01+0100\n" +"PO-Revision-Date: 2024-12-24 11:05+0100\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -18,32 +18,32 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gitk:140 +#: gitk:139 msgid "Couldn't get list of unmerged files:" -msgstr "Списъкът с неслети файлове не може да бъде получен:" +msgstr "Списъкът с неслети файлове не може да се получи:" -#: gitk:212 gitk:2403 +#: gitk:211 gitk:2430 msgid "Color words" msgstr "Оцветяване на думите" -#: gitk:217 gitk:2403 gitk:8249 gitk:8282 +#: gitk:216 gitk:2430 gitk:8335 gitk:8368 msgid "Markup words" msgstr "Отбелязване на думите" -#: gitk:324 +#: gitk:323 msgid "Error parsing revisions:" msgstr "Грешка при анализ на версиите:" -#: gitk:380 +#: gitk:389 msgid "Error executing --argscmd command:" msgstr "Грешка при изпълнение на командата с „--argscmd“." -#: gitk:393 +#: gitk:402 msgid "No files selected: --merge specified but no files are unmerged." msgstr "" "Не са избрани файлове — указана е опцията „--merge“, но няма неслети файлове." -#: gitk:396 +#: gitk:405 msgid "" "No files selected: --merge specified but no unmerged files are within file " "limit." @@ -51,326 +51,326 @@ msgstr "" "Не са избрани файлове — указана е опцията „--merge“, но няма неслети файлове " "в ограниченията." -#: gitk:418 gitk:566 +#: gitk:430 gitk:585 msgid "Error executing git log:" msgstr "Грешка при изпълнение на „git log“:" -#: gitk:436 gitk:582 +#: gitk:448 gitk:601 msgid "Reading" msgstr "Прочитане" -#: gitk:496 gitk:4549 +#: gitk:508 gitk:4596 msgid "Reading commits..." msgstr "Прочитане на подаванията…" -#: gitk:499 gitk:1641 gitk:4552 +#: gitk:511 gitk:1660 gitk:4599 msgid "No commits selected" msgstr "Не са избрани подавания" -#: gitk:1449 gitk:4069 gitk:12583 +#: gitk:1468 gitk:4116 gitk:12738 msgid "Command line" msgstr "Команден ред" -#: gitk:1515 +#: gitk:1534 msgid "Can't parse git log output:" msgstr "Изходът от „git log“ не може да се анализира:" -#: gitk:1744 +#: gitk:1763 msgid "No commit information available" msgstr "Липсва информация за подавания" -#: gitk:1907 gitk:1936 gitk:4339 gitk:9789 gitk:11388 gitk:11668 +#: gitk:1930 gitk:1959 gitk:4386 gitk:9875 gitk:11485 gitk:11805 msgid "OK" msgstr "Добре" -#: gitk:1938 gitk:4341 gitk:9225 gitk:9304 gitk:9434 gitk:9520 gitk:9791 -#: gitk:11389 gitk:11669 +#: gitk:1961 gitk:4388 gitk:9311 gitk:9390 gitk:9520 gitk:9606 gitk:9877 +#: gitk:11486 gitk:11806 msgid "Cancel" msgstr "Отказ" -#: gitk:2087 +#: gitk:2114 msgid "&Update" msgstr "&Обновяване" -#: gitk:2088 +#: gitk:2115 msgid "&Reload" msgstr "&Презареждане" -#: gitk:2089 +#: gitk:2116 msgid "Reread re&ferences" -msgstr "&Наново прочитане" +msgstr "Прочитане &наново" -#: gitk:2090 +#: gitk:2117 msgid "&List references" msgstr "&Изброяване на указателите" -#: gitk:2092 +#: gitk:2119 msgid "Start git &gui" msgstr "&Стартиране на „git gui“" -#: gitk:2094 +#: gitk:2121 msgid "&Quit" msgstr "&Спиране на програмата" -#: gitk:2086 +#: gitk:2113 msgid "&File" msgstr "&Файл" -#: gitk:2098 +#: gitk:2125 msgid "&Preferences" msgstr "&Настройки" -#: gitk:2097 +#: gitk:2124 msgid "&Edit" msgstr "&Редактиране" -#: gitk:2102 +#: gitk:2129 msgid "&New view..." msgstr "&Нов изглед…" -#: gitk:2103 +#: gitk:2130 msgid "&Edit view..." msgstr "&Редактиране на изгледа…" -#: gitk:2104 +#: gitk:2131 msgid "&Delete view" msgstr "&Изтриване на изгледа" -#: gitk:2106 +#: gitk:2133 msgid "&All files" msgstr "&Всички файлове" -#: gitk:2101 +#: gitk:2128 msgid "&View" msgstr "&Изглед" -#: gitk:2111 gitk:2121 +#: gitk:2138 gitk:2148 msgid "&About gitk" msgstr "&Относно gitk" -#: gitk:2112 gitk:2126 +#: gitk:2139 gitk:2153 msgid "&Key bindings" msgstr "&Клавишни комбинации" -#: gitk:2110 gitk:2125 +#: gitk:2137 gitk:2152 msgid "&Help" msgstr "Помо&щ" -#: gitk:2203 gitk:8681 -msgid "SHA1 ID:" -msgstr "SHA1:" +#: gitk:2230 gitk:8767 +msgid "Commit ID:" +msgstr "Подаване:" -#: gitk:2247 +#: gitk:2274 msgid "Row" msgstr "Ред" -#: gitk:2285 +#: gitk:2312 msgid "Find" msgstr "Търсене" -#: gitk:2313 +#: gitk:2340 msgid "commit" msgstr "подаване" -#: gitk:2317 gitk:2319 gitk:4711 gitk:4734 gitk:4758 gitk:6779 gitk:6851 -#: gitk:6936 +#: gitk:2344 gitk:2346 gitk:4758 gitk:4781 gitk:4805 gitk:6826 gitk:6898 +#: gitk:6983 msgid "containing:" msgstr "съдържащо:" -#: gitk:2320 gitk:3550 gitk:3555 gitk:4787 +#: gitk:2347 gitk:3597 gitk:3602 gitk:4834 msgid "touching paths:" msgstr "в пътищата:" -#: gitk:2321 gitk:4801 +#: gitk:2348 gitk:4848 msgid "adding/removing string:" msgstr "добавящо/премахващо низ" -#: gitk:2322 gitk:4803 +#: gitk:2349 gitk:4850 msgid "changing lines matching:" msgstr "променящо редове напасващи:" -#: gitk:2331 gitk:2333 gitk:4790 +#: gitk:2358 gitk:2360 gitk:4837 msgid "Exact" msgstr "Точно" -#: gitk:2333 gitk:4878 gitk:6747 +#: gitk:2360 gitk:4925 gitk:6794 msgid "IgnCase" msgstr "Без регистър" -#: gitk:2333 gitk:4760 gitk:4876 gitk:6743 +#: gitk:2360 gitk:4807 gitk:4923 gitk:6790 msgid "Regexp" msgstr "Рег. израз" -#: gitk:2335 gitk:2336 gitk:4898 gitk:4928 gitk:4935 gitk:6872 gitk:6940 +#: gitk:2362 gitk:2363 gitk:4945 gitk:4975 gitk:4982 gitk:6919 gitk:6987 msgid "All fields" msgstr "Всички полета" -#: gitk:2336 gitk:4895 gitk:4928 gitk:6810 +#: gitk:2363 gitk:4942 gitk:4975 gitk:6857 msgid "Headline" msgstr "Първи ред" -#: gitk:2337 gitk:4895 gitk:6810 gitk:6940 gitk:7413 +#: gitk:2364 gitk:4942 gitk:6857 gitk:6987 gitk:7499 msgid "Comments" msgstr "Коментари" -#: gitk:2337 gitk:4895 gitk:4900 gitk:4935 gitk:6810 gitk:7348 gitk:8859 -#: gitk:8874 +#: gitk:2364 gitk:4942 gitk:4947 gitk:4982 gitk:6857 gitk:7434 gitk:8945 +#: gitk:8960 msgid "Author" msgstr "Автор" -#: gitk:2337 gitk:4895 gitk:6810 gitk:7350 +#: gitk:2364 gitk:4942 gitk:6857 gitk:7436 msgid "Committer" msgstr "Подаващ" -#: gitk:2371 +#: gitk:2398 msgid "Search" msgstr "Търсене" -#: gitk:2379 +#: gitk:2406 msgid "Diff" msgstr "Разлики" -#: gitk:2381 +#: gitk:2408 msgid "Old version" msgstr "Стара версия" -#: gitk:2383 +#: gitk:2410 msgid "New version" msgstr "Нова версия" -#: gitk:2386 +#: gitk:2413 msgid "Lines of context" msgstr "Контекст в редове" -#: gitk:2396 +#: gitk:2423 msgid "Ignore space change" msgstr "Празните знаци без значение" -#: gitk:2400 gitk:2402 gitk:7983 gitk:8235 +#: gitk:2427 gitk:2429 gitk:8069 gitk:8321 msgid "Line diff" msgstr "Поредови разлики" -#: gitk:2467 +#: gitk:2502 msgid "Patch" msgstr "Кръпка" -#: gitk:2469 +#: gitk:2504 msgid "Tree" msgstr "Дърво" -#: gitk:2639 gitk:2660 +#: gitk:2674 gitk:2695 msgid "Diff this -> selected" msgstr "Разлики между това и избраното" -#: gitk:2640 gitk:2661 +#: gitk:2675 gitk:2696 msgid "Diff selected -> this" msgstr "Разлики между избраното и това" -#: gitk:2641 gitk:2662 +#: gitk:2676 gitk:2697 msgid "Make patch" msgstr "Създаване на кръпка" -#: gitk:2642 gitk:9283 +#: gitk:2677 gitk:9369 msgid "Create tag" msgstr "Създаване на етикет" -#: gitk:2643 -msgid "Copy commit summary" -msgstr "Копиране на информацията за подаване" +#: gitk:2678 +msgid "Copy commit reference" +msgstr "Копиране на указателя на подаване" -#: gitk:2644 gitk:9414 +#: gitk:2679 gitk:9500 msgid "Write commit to file" msgstr "Запазване на подаването във файл" -#: gitk:2645 +#: gitk:2680 msgid "Create new branch" msgstr "Създаване на нов клон" -#: gitk:2646 +#: gitk:2681 msgid "Cherry-pick this commit" msgstr "Отбиране на това подаване" -#: gitk:2647 +#: gitk:2682 msgid "Reset HEAD branch to here" msgstr "Привеждане на върха на клона към текущото подаване" -#: gitk:2648 +#: gitk:2683 msgid "Mark this commit" msgstr "Отбелязване на това подаване" -#: gitk:2649 +#: gitk:2684 msgid "Return to mark" msgstr "Връщане към отбелязаното подаване" -#: gitk:2650 +#: gitk:2685 msgid "Find descendant of this and mark" msgstr "Откриване и отбелязване на наследниците" -#: gitk:2651 +#: gitk:2686 msgid "Compare with marked commit" msgstr "Сравнение с отбелязаното подаване" -#: gitk:2652 gitk:2663 +#: gitk:2687 gitk:2698 msgid "Diff this -> marked commit" msgstr "Разлики между това и отбелязаното" -#: gitk:2653 gitk:2664 +#: gitk:2688 gitk:2699 msgid "Diff marked commit -> this" msgstr "Разлики между отбелязаното и това" -#: gitk:2654 +#: gitk:2689 msgid "Revert this commit" msgstr "Отмяна на това подаване" -#: gitk:2670 +#: gitk:2705 msgid "Check out this branch" msgstr "Изтегляне на този клон" -#: gitk:2671 +#: gitk:2706 msgid "Rename this branch" msgstr "Преименуване на този клон" -#: gitk:2672 +#: gitk:2707 msgid "Remove this branch" msgstr "Изтриване на този клон" -#: gitk:2673 +#: gitk:2708 msgid "Copy branch name" msgstr "Копиране на името на клона" -#: gitk:2680 +#: gitk:2715 msgid "Highlight this too" msgstr "Отбелязване и на това" -#: gitk:2681 +#: gitk:2716 msgid "Highlight this only" msgstr "Отбелязване само на това" -#: gitk:2682 +#: gitk:2717 msgid "External diff" msgstr "Външна програма за разлики" -#: gitk:2683 +#: gitk:2718 msgid "Blame parent commit" msgstr "Анотиране на родителското подаване" -#: gitk:2684 +#: gitk:2719 msgid "Copy path" msgstr "Копиране на пътя" -#: gitk:2691 +#: gitk:2726 msgid "Show origin of this line" msgstr "Показване на произхода на този ред" -#: gitk:2692 +#: gitk:2727 msgid "Run git gui blame on this line" msgstr "Изпълнение на „git gui blame“ върху този ред" -#: gitk:3036 +#: gitk:3081 msgid "About gitk" msgstr "Относно gitk" -#: gitk:3038 +#: gitk:3083 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -386,324 +386,324 @@ msgstr "" "\n" "Използвайте и разпространявайте при условията на ОПЛ на ГНУ" -#: gitk:3046 gitk:3113 gitk:10004 +#: gitk:3091 gitk:3158 gitk:10090 msgid "Close" msgstr "Затваряне" -#: gitk:3067 +#: gitk:3112 msgid "Gitk key bindings" msgstr "Клавишни комбинации" -#: gitk:3070 +#: gitk:3115 msgid "Gitk key bindings:" msgstr "Клавишни комбинации:" -#: gitk:3072 +#: gitk:3117 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tСпиране на програмата" -#: gitk:3073 +#: gitk:3118 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tЗатваряне на прозореца" -#: gitk:3074 +#: gitk:3119 msgid "<Home>\t\tMove to first commit" msgstr "<Home>\t\tКъм първото подаване" -#: gitk:3075 +#: gitk:3120 msgid "<End>\t\tMove to last commit" msgstr "<End>\t\tКъм последното подаване" -#: gitk:3076 +#: gitk:3121 msgid "<Up>, p, k\tMove up one commit" msgstr "<Up>, p, k\tЕдно подаване нагоре" -#: gitk:3077 +#: gitk:3122 msgid "<Down>, n, j\tMove down one commit" msgstr "<Down>, n, j\tЕдно подаване надолу" -#: gitk:3078 +#: gitk:3123 msgid "<Left>, z, h\tGo back in history list" msgstr "<Left>, z, h\tНазад в историята" -#: gitk:3079 +#: gitk:3124 msgid "<Right>, x, l\tGo forward in history list" msgstr "<Right>, x, l\tНапред в историята" -#: gitk:3080 +#: gitk:3125 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" msgstr "<%s-n>\tКъм n-тия родител на текущото подаване в историята" -#: gitk:3081 +#: gitk:3126 msgid "<PageUp>\tMove up one page in commit list" msgstr "<PageUp>\tСтраница нагоре в списъка с подаванията" -#: gitk:3082 +#: gitk:3127 msgid "<PageDown>\tMove down one page in commit list" msgstr "<PageDown>\tСтраница надолу в списъка с подаванията" -#: gitk:3083 +#: gitk:3128 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tКъм началото на списъка с подаванията" -#: gitk:3084 +#: gitk:3129 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tКъм края на списъка с подаванията" -#: gitk:3085 +#: gitk:3130 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Up>\tРед нагоре в списъка с подавания" -#: gitk:3086 +#: gitk:3131 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Down>\tРед надолу в списъка с подавания" -#: gitk:3087 +#: gitk:3132 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tСтраница нагоре в списъка с подавания" -#: gitk:3088 +#: gitk:3133 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tСтраница надолу в списъка с подавания" -#: gitk:3089 +#: gitk:3134 msgid "<Shift-Up>\tFind backwards (upwards, later commits)" msgstr "<Shift-Up>\tТърсене назад (визуално нагоре, исторически — последващи)" -#: gitk:3090 +#: gitk:3135 msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)" msgstr "" "<Shift-Down>\tТърсене напред (визуално надолу, исторически — предхождащи)" -#: gitk:3091 +#: gitk:3136 msgid "<Delete>, b\tScroll diff view up one page" msgstr "<Delete>, b\tСтраница нагоре в изгледа за разлики" -#: gitk:3092 +#: gitk:3137 msgid "<Backspace>\tScroll diff view up one page" msgstr "<Backspace>\tСтраница надолу в изгледа за разлики" -#: gitk:3093 +#: gitk:3138 msgid "<Space>\t\tScroll diff view down one page" msgstr "<Space>\t\tСтраница надолу в изгледа за разлики" -#: gitk:3094 +#: gitk:3139 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\t18 реда нагоре в изгледа за разлики" -#: gitk:3095 +#: gitk:3140 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\t18 реда надолу в изгледа за разлики" -#: gitk:3096 +#: gitk:3141 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tТърсене" -#: gitk:3097 +#: gitk:3142 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tКъм следващата поява" -#: gitk:3098 +#: gitk:3143 msgid "<Return>\tMove to next find hit" msgstr "<Return>\tКъм следващата поява" -#: gitk:3099 +#: gitk:3144 msgid "g\t\tGo to commit" msgstr "g\t\tКъм последното подаване" -#: gitk:3100 +#: gitk:3145 msgid "/\t\tFocus the search box" msgstr "/\t\tФокус върху полето за търсене" -#: gitk:3101 +#: gitk:3146 msgid "?\t\tMove to previous find hit" msgstr "?\t\tКъм предишната поява" -#: gitk:3102 +#: gitk:3147 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tСледващ файл в изгледа за разлики" -#: gitk:3103 +#: gitk:3148 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tТърсене на следващата поява в изгледа за разлики" -#: gitk:3104 +#: gitk:3149 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tТърсене на предишната поява в изгледа за разлики" -#: gitk:3105 +#: gitk:3150 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-KP+>\tПо-голям размер на шрифта" -#: gitk:3106 +#: gitk:3151 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tПо-голям размер на шрифта" -#: gitk:3107 +#: gitk:3152 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-KP->\tПо-малък размер на шрифта" -#: gitk:3108 +#: gitk:3153 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tПо-малък размер на шрифта" -#: gitk:3109 +#: gitk:3154 msgid "<F5>\t\tUpdate" msgstr "<F5>\t\tОбновяване" -#: gitk:3574 gitk:3583 +#: gitk:3621 gitk:3630 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Грешка при създаването на временната директория „%s“:" -#: gitk:3596 +#: gitk:3643 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Грешка при получаването на „%s“ от %s:" -#: gitk:3659 +#: gitk:3706 msgid "command failed:" msgstr "неуспешно изпълнение на команда:" -#: gitk:3808 +#: gitk:3855 msgid "No such commit" msgstr "Такова подаване няма" -#: gitk:3822 +#: gitk:3869 msgid "git gui blame: command failed:" msgstr "„git gui blame“: неуспешно изпълнение на команда:" -#: gitk:3853 +#: gitk:3900 #, tcl-format msgid "Couldn't read merge head: %s" -msgstr "Върхът за сливане не може да бъде прочетен: %s" +msgstr "Върхът за сливане не може да се прочете: %s" -#: gitk:3861 +#: gitk:3908 #, tcl-format msgid "Error reading index: %s" msgstr "Грешка при прочитане на индекса: %s" -#: gitk:3886 +#: gitk:3933 #, tcl-format msgid "Couldn't start git blame: %s" -msgstr "Командата „git blame“ не може да бъде стартирана: %s" +msgstr "Командата „git blame“ не може да се стартира: %s" -#: gitk:3889 gitk:6778 +#: gitk:3936 gitk:6825 msgid "Searching" msgstr "Търсене" -#: gitk:3921 +#: gitk:3968 #, tcl-format msgid "Error running git blame: %s" msgstr "Грешка при изпълнението на „git blame“: %s" -#: gitk:3949 +#: gitk:3996 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Този ред идва от подаването %s, което не е в изгледа" -#: gitk:3963 +#: gitk:4010 msgid "External diff viewer failed:" msgstr "Неуспешно изпълнение на външната програма за разлики:" -#: gitk:4067 +#: gitk:4114 msgid "All files" msgstr "Всички файлове" -#: gitk:4091 +#: gitk:4138 msgid "View" msgstr "Изглед" -#: gitk:4094 +#: gitk:4141 msgid "Gitk view definition" msgstr "Дефиниция на изглед в Gitk" -#: gitk:4098 +#: gitk:4145 msgid "Remember this view" msgstr "Запазване на този изглед" -#: gitk:4099 +#: gitk:4146 msgid "References (space separated list):" msgstr "Указатели (списък с разделител интервал):" -#: gitk:4100 +#: gitk:4147 msgid "Branches & tags:" msgstr "Клони и етикети:" -#: gitk:4101 +#: gitk:4148 msgid "All refs" msgstr "Всички указатели" -#: gitk:4102 +#: gitk:4149 msgid "All (local) branches" msgstr "Всички (локални) клони" -#: gitk:4103 +#: gitk:4150 msgid "All tags" msgstr "Всички етикети" -#: gitk:4104 +#: gitk:4151 msgid "All remote-tracking branches" msgstr "Всички следящи клони" -#: gitk:4105 +#: gitk:4152 msgid "Commit Info (regular expressions):" msgstr "Информация за подаване (рег. изр.):" -#: gitk:4106 +#: gitk:4153 msgid "Author:" msgstr "Автор:" -#: gitk:4107 +#: gitk:4154 msgid "Committer:" msgstr "Подал:" -#: gitk:4108 +#: gitk:4155 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: gitk:4109 +#: gitk:4156 msgid "Matches all Commit Info criteria" msgstr "Съвпадение по всички характеристики на подаването" -#: gitk:4110 +#: gitk:4157 msgid "Matches no Commit Info criteria" msgstr "Не съвпада по никоя от характеристиките на подаването" -#: gitk:4111 +#: gitk:4158 msgid "Changes to Files:" msgstr "Промени по файловете:" -#: gitk:4112 +#: gitk:4159 msgid "Fixed String" msgstr "Дословен низ" -#: gitk:4113 +#: gitk:4160 msgid "Regular Expression" msgstr "Регулярен израз" -#: gitk:4114 +#: gitk:4161 msgid "Search string:" msgstr "Низ за търсене:" -#: gitk:4115 +#: gitk:4162 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -711,204 +711,208 @@ msgstr "" "Дата на подаване („2 weeks ago“ (преди 2 седмици), „2009-03-17 15:27:38“, " "„March 17, 2009 15:27:38“):" -#: gitk:4116 +#: gitk:4163 msgid "Since:" msgstr "От:" -#: gitk:4117 +#: gitk:4164 msgid "Until:" msgstr "До:" -#: gitk:4118 +#: gitk:4165 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "" "Ограничаване и/или прескачане на определен брой версии (неотрицателно цяло " "число):" -#: gitk:4119 +#: gitk:4166 msgid "Number to show:" msgstr "Брой показани:" -#: gitk:4120 +#: gitk:4167 msgid "Number to skip:" msgstr "Брой прескочени:" -#: gitk:4121 +#: gitk:4168 msgid "Miscellaneous options:" msgstr "Разни:" -#: gitk:4122 +#: gitk:4169 msgid "Strictly sort by date" msgstr "Подреждане по дата" -#: gitk:4123 +#: gitk:4170 msgid "Mark branch sides" msgstr "Отбелязване на страните по клона" -#: gitk:4124 +#: gitk:4171 msgid "Limit to first parent" msgstr "Само първия родител" -#: gitk:4125 +#: gitk:4172 msgid "Simple history" msgstr "Опростена история" -#: gitk:4126 +#: gitk:4173 msgid "Additional arguments to git log:" msgstr "Допълнителни аргументи към „git log“:" -#: gitk:4127 +#: gitk:4174 msgid "Enter files and directories to include, one per line:" msgstr "Въведете файловете и директориите за включване, по елемент на ред" -#: gitk:4128 +#: gitk:4175 msgid "Command to generate more commits to include:" msgstr "" -"Команда за генерирането на допълнителни подавания, които да бъдат включени:" +"Команда за генерирането на допълнителни подавания, които да се включат:" -#: gitk:4252 +#: gitk:4299 msgid "Gitk: edit view" msgstr "Gitk: редактиране на изглед" -#: gitk:4260 +#: gitk:4307 msgid "-- criteria for selecting revisions" msgstr "— критерии за избор на версии" -#: gitk:4265 +#: gitk:4312 msgid "View Name" msgstr "Име на изглед" -#: gitk:4340 +#: gitk:4387 msgid "Apply (F5)" msgstr "Прилагане (F5)" -#: gitk:4378 +#: gitk:4425 msgid "Error in commit selection arguments:" msgstr "Грешка в аргументите за избор на подавания:" -#: gitk:4433 gitk:4486 gitk:4948 gitk:4962 gitk:6232 gitk:12524 gitk:12525 +#: gitk:4480 gitk:4533 gitk:4995 gitk:5009 gitk:6279 gitk:12679 gitk:12680 msgid "None" msgstr "Няма" -#: gitk:5045 gitk:5050 +#: gitk:5092 gitk:5097 msgid "Descendant" msgstr "Наследник" -#: gitk:5046 +#: gitk:5093 msgid "Not descendant" msgstr "Не е наследник" -#: gitk:5053 gitk:5058 +#: gitk:5100 gitk:5105 msgid "Ancestor" msgstr "Предшественик" -#: gitk:5054 +#: gitk:5101 msgid "Not ancestor" msgstr "Не е предшественик" -#: gitk:5348 +#: gitk:5395 msgid "Local changes checked in to index but not committed" msgstr "Локални промени добавени към индекса, но неподадени" -#: gitk:5384 +#: gitk:5431 msgid "Local uncommitted changes, not checked in to index" msgstr "Локални промени извън индекса" -#: gitk:7158 +#: gitk:7179 +msgid "Error starting web browser:" +msgstr "Грешка при стартирането на уеб браузър:" + +#: gitk:7240 msgid "and many more" msgstr "и още много" -#: gitk:7161 +#: gitk:7243 msgid "many" msgstr "много" -#: gitk:7352 +#: gitk:7438 msgid "Tags:" msgstr "Етикети:" -#: gitk:7369 gitk:7375 gitk:8854 +#: gitk:7455 gitk:7461 gitk:8940 msgid "Parent" msgstr "Родител" -#: gitk:7380 +#: gitk:7466 msgid "Child" msgstr "Дете" -#: gitk:7389 +#: gitk:7475 msgid "Branch" msgstr "Клон" -#: gitk:7392 +#: gitk:7478 msgid "Follows" msgstr "Следва" -#: gitk:7395 +#: gitk:7481 msgid "Precedes" msgstr "Предшества" -#: gitk:7990 +#: gitk:8076 #, tcl-format msgid "Error getting diffs: %s" msgstr "Грешка при получаването на разликите: %s" -#: gitk:8679 +#: gitk:8765 msgid "Goto:" msgstr "Към ред:" -#: gitk:8700 +#: gitk:8786 #, tcl-format -msgid "Short SHA1 id %s is ambiguous" -msgstr "Съкратената сума по SHA1 %s не е еднозначна" +msgid "Short commit ID %s is ambiguous" +msgstr "Съкратената контролна сума %s не е еднозначна" -#: gitk:8707 +#: gitk:8793 #, tcl-format msgid "Revision %s is not known" msgstr "Непозната версия %s" -#: gitk:8717 +#: gitk:8803 #, tcl-format -msgid "SHA1 id %s is not known" -msgstr "Непозната сума по SHA1 %s" +msgid "Commit ID %s is not known" +msgstr "Непозната контролна сума %s" -#: gitk:8719 +#: gitk:8805 #, tcl-format msgid "Revision %s is not in the current view" msgstr "Версия %s не е в текущия изглед" -#: gitk:8861 gitk:8876 +#: gitk:8947 gitk:8962 msgid "Date" msgstr "Дата" -#: gitk:8864 +#: gitk:8950 msgid "Children" msgstr "Деца" -#: gitk:8927 +#: gitk:9013 #, tcl-format msgid "Reset %s branch to here" msgstr "Зануляване на клона „%s“ към текущото подаване" -#: gitk:8929 +#: gitk:9015 msgid "Detached head: can't reset" msgstr "Несвързан връх: невъзможно зануляване" -#: gitk:9034 gitk:9040 +#: gitk:9120 gitk:9126 msgid "Skipping merge commit " msgstr "Пропускане на подаването на сливането" -#: gitk:9049 gitk:9054 +#: gitk:9135 gitk:9140 msgid "Error getting patch ID for " msgstr "Грешка при получаването на идентификатора на " -#: gitk:9050 gitk:9055 +#: gitk:9136 gitk:9141 msgid " - stopping\n" msgstr " — спиране\n" -#: gitk:9060 gitk:9063 gitk:9071 gitk:9085 gitk:9094 +#: gitk:9146 gitk:9149 gitk:9157 gitk:9171 gitk:9180 msgid "Commit " msgstr "Подаване" -#: gitk:9064 +#: gitk:9150 msgid "" " is the same patch as\n" " " @@ -916,7 +920,7 @@ msgstr "" " е същата кръпка като\n" " " -#: gitk:9072 +#: gitk:9158 msgid "" " differs from\n" " " @@ -924,7 +928,7 @@ msgstr "" " се различава от\n" " " -#: gitk:9074 +#: gitk:9160 msgid "" "Diff of commits:\n" "\n" @@ -932,147 +936,147 @@ msgstr "" "Разлика между подаванията:\n" "\n" -#: gitk:9086 gitk:9095 +#: gitk:9172 gitk:9181 #, tcl-format msgid " has %s children - stopping\n" msgstr " има %s деца — спиране\n" -#: gitk:9114 +#: gitk:9200 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Грешка при запазването на подаването във файл: %s" -#: gitk:9120 +#: gitk:9206 #, tcl-format msgid "Error diffing commits: %s" msgstr "Грешка при изчисляването на разликите между подаванията: %s" -#: gitk:9166 +#: gitk:9252 msgid "Top" msgstr "Най-горе" -#: gitk:9167 +#: gitk:9253 msgid "From" msgstr "От" -#: gitk:9172 +#: gitk:9258 msgid "To" msgstr "До" -#: gitk:9196 +#: gitk:9282 msgid "Generate patch" msgstr "Генериране на кръпка" -#: gitk:9198 +#: gitk:9284 msgid "From:" msgstr "От:" -#: gitk:9207 +#: gitk:9293 msgid "To:" msgstr "До:" -#: gitk:9216 +#: gitk:9302 msgid "Reverse" msgstr "Обръщане" -#: gitk:9218 gitk:9428 +#: gitk:9304 gitk:9514 msgid "Output file:" msgstr "Запазване във файла:" -#: gitk:9224 +#: gitk:9310 msgid "Generate" msgstr "Генериране" -#: gitk:9262 +#: gitk:9348 msgid "Error creating patch:" msgstr "Грешка при създаването на кръпка:" -#: gitk:9285 gitk:9416 gitk:9504 +#: gitk:9371 gitk:9502 gitk:9590 msgid "ID:" msgstr "Идентификатор:" -#: gitk:9294 +#: gitk:9380 msgid "Tag name:" msgstr "Име на етикет:" -#: gitk:9297 +#: gitk:9383 msgid "Tag message is optional" msgstr "Съобщението за етикет е незадължително" -#: gitk:9299 +#: gitk:9385 msgid "Tag message:" msgstr "Съобщение за етикет:" -#: gitk:9303 gitk:9474 +#: gitk:9389 gitk:9560 msgid "Create" msgstr "Създаване" -#: gitk:9321 +#: gitk:9407 msgid "No tag name specified" msgstr "Липсва име на етикет" -#: gitk:9325 +#: gitk:9411 #, tcl-format msgid "Tag \"%s\" already exists" msgstr "Етикетът „%s“ вече съществува" -#: gitk:9335 +#: gitk:9421 msgid "Error creating tag:" msgstr "Грешка при създаването на етикет:" -#: gitk:9425 +#: gitk:9511 msgid "Command:" msgstr "Команда:" -#: gitk:9433 +#: gitk:9519 msgid "Write" msgstr "Запазване" -#: gitk:9451 +#: gitk:9537 msgid "Error writing commit:" msgstr "Грешка при запазването на подаването:" -#: gitk:9473 +#: gitk:9559 msgid "Create branch" msgstr "Създаване на клон" -#: gitk:9489 +#: gitk:9575 #, tcl-format msgid "Rename branch %s" msgstr "Преименуване на клона „%s“" -#: gitk:9490 +#: gitk:9576 msgid "Rename" msgstr "Преименуване" -#: gitk:9514 +#: gitk:9600 msgid "Name:" msgstr "Име:" -#: gitk:9538 +#: gitk:9624 msgid "Please specify a name for the new branch" msgstr "Укажете име за новия клон" -#: gitk:9543 +#: gitk:9629 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" -msgstr "Клонът „%s“ вече съществува. Да бъде ли презаписан?" +msgstr "Клонът „%s“ вече съществува. Да се презапише ли?" -#: gitk:9587 +#: gitk:9673 msgid "Please specify a new name for the branch" msgstr "Укажете ново име за клона" -#: gitk:9650 +#: gitk:9736 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" -"Подаването „%s“ вече е включено в клона „%s“ — да бъде ли приложено отново?" +"Подаването „%s“ вече е включено в клона „%s“ — да се приложи ли отново?" -#: gitk:9655 +#: gitk:9741 msgid "Cherry-picking" msgstr "Отбиране" -#: gitk:9664 +#: gitk:9750 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" @@ -1081,7 +1085,7 @@ msgstr "" "Неуспешно отбиране, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги скатайте и пробвайте отново." -#: gitk:9670 +#: gitk:9756 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1089,20 +1093,20 @@ msgstr "" "Неуспешно отбиране поради конфликти при сливане.\n" "Искате ли да ги коригирате чрез „git citool“?" -#: gitk:9686 gitk:9744 +#: gitk:9772 gitk:9830 msgid "No changes committed" msgstr "Не са подадени промени" -#: gitk:9713 +#: gitk:9799 #, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" -msgstr "Подаването „%s“ не е включено в клона „%s“. Да бъде ли отменено?" +msgstr "Подаването „%s“ не е включено в клона „%s“. Да се отменени ли?" -#: gitk:9718 +#: gitk:9804 msgid "Reverting" msgstr "Отмяна" -#: gitk:9726 +#: gitk:9812 #, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " @@ -1111,7 +1115,7 @@ msgstr "" "Неуспешна отмяна, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги скатайте и пробвайте отново." -#: gitk:9730 +#: gitk:9816 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" @@ -1119,53 +1123,53 @@ msgstr "" "Неуспешно отмяна поради конфликти при сливане.\n" "Искате ли да ги коригирате чрез „git citool“?" -#: gitk:9773 +#: gitk:9859 msgid "Confirm reset" msgstr "Потвърждаване на зануляването" -#: gitk:9775 +#: gitk:9861 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Да се занули ли клонът „%s“ към „%s“?" -#: gitk:9777 +#: gitk:9863 msgid "Reset type:" msgstr "Вид зануляване:" -#: gitk:9780 +#: gitk:9866 msgid "Soft: Leave working tree and index untouched" msgstr "Слабо: работното дърво и индекса остават същите" -#: gitk:9783 +#: gitk:9869 msgid "Mixed: Leave working tree untouched, reset index" msgstr "Смесено: работното дърво остава същото, индексът се занулява" -#: gitk:9786 +#: gitk:9872 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" msgstr "" "Силно: зануляване и на работното дърво, и на индекса\n" -"(ВСИЧКИ локални промени ще бъдат безвъзвратно загубени)" +"(ВСИЧКИ локални промени ще се загубят безвъзвратно)" -#: gitk:9803 +#: gitk:9889 msgid "Resetting" msgstr "Зануляване" -#: gitk:9876 +#: gitk:9962 #, tcl-format msgid "A local branch named %s exists already" msgstr "Вече съществува локален клон „%s“." -#: gitk:9884 +#: gitk:9970 msgid "Checking out" msgstr "Изтегляне" -#: gitk:9943 +#: gitk:10029 msgid "Cannot delete the currently checked-out branch" -msgstr "Текущо изтегленият клон не може да бъде изтрит" +msgstr "Текущо изтегленият клон не може да се изтрие" -#: gitk:9949 +#: gitk:10035 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1174,16 +1178,16 @@ msgstr "" "Подаванията на клона „%s“ не са на никой друг клон.\n" "Наистина ли искате да изтриете клона „%s“?" -#: gitk:9980 +#: gitk:10066 #, tcl-format msgid "Tags and heads: %s" msgstr "Етикети и върхове: %s" -#: gitk:9997 +#: gitk:10083 msgid "Filter" msgstr "Филтриране" -#: gitk:10293 +#: gitk:10390 msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1191,201 +1195,237 @@ msgstr "" "Грешка при прочитането на топологията на подаванията. Информацията за клона " "и предшестващите/следващите етикети ще е непълна." -#: gitk:11270 +#: gitk:11367 msgid "Tag" msgstr "Етикет" -#: gitk:11274 +#: gitk:11371 msgid "Id" msgstr "Идентификатор" -#: gitk:11357 +#: gitk:11454 msgid "Gitk font chooser" msgstr "Избор на шрифт за Gitk" -#: gitk:11374 +#: gitk:11471 msgid "B" msgstr "Ч" -#: gitk:11377 +#: gitk:11474 msgid "I" msgstr "К" -#: gitk:11495 +#: gitk:11593 msgid "Commit list display options" msgstr "Настройки на списъка с подавания" -#: gitk:11498 +#: gitk:11596 msgid "Maximum graph width (lines)" msgstr "Максимална широчина на графа (в редове)" -#: gitk:11502 +#: gitk:11600 #, no-tcl-format msgid "Maximum graph width (% of pane)" msgstr "Максимална широчина на графа (% от панела)" -#: gitk:11505 +#: gitk:11603 msgid "Show local changes" msgstr "Показване на локалните промени" -#: gitk:11508 -msgid "Auto-select SHA1 (length)" -msgstr "Автоматично избиране на SHA1 (дължина)" - -#: gitk:11512 +#: gitk:11606 msgid "Hide remote refs" msgstr "Скриване на отдалечените указатели" -#: gitk:11516 +#: gitk:11610 +msgid "Copy commit ID to clipboard" +msgstr "Копиране на контролната сума към буфера за обмен" + +#: gitk:11614 +msgid "Copy commit ID to X11 selection" +msgstr "Копиране на контролната сума в селекцията на X11" + +#: gitk:11619 +msgid "Length of commit ID to copy" +msgstr "Дължина на контролната сума, която се копира" + +#: gitk:11622 msgid "Diff display options" msgstr "Настройки на показването на разликите" -#: gitk:11518 +#: gitk:11624 msgid "Tab spacing" msgstr "Широчина на табулатора" -#: gitk:11521 +#: gitk:11628 +msgid "Wrap comment text" +msgstr "Пренасяне на думите в коментарите" + +#: gitk:11633 +msgid "Wrap other text" +msgstr "Пренасяне на другия текст" + +#: gitk:11638 msgid "Display nearby tags/heads" msgstr "Извеждане на близките етикети и върхове" -#: gitk:11524 +#: gitk:11641 msgid "Maximum # tags/heads to show" msgstr "Максимален брой етикети/върхове за показване" -#: gitk:11527 +#: gitk:11644 msgid "Limit diffs to listed paths" msgstr "Разлика само в избраните пътища" -#: gitk:11530 +#: gitk:11647 msgid "Support per-file encodings" msgstr "Поддръжка на различни кодирания за всеки файл" -#: gitk:11536 gitk:11683 +#: gitk:11653 gitk:11820 msgid "External diff tool" msgstr "Външен инструмент за разлики" -#: gitk:11537 +#: gitk:11654 msgid "Choose..." msgstr "Избор…" -#: gitk:11542 +#: gitk:11661 +msgid "Web browser" +msgstr "Уеб браузър" + +#: gitk:11666 msgid "General options" msgstr "Общи настройки" -#: gitk:11545 +#: gitk:11669 msgid "Use themed widgets" msgstr "Използване на тема за графичните обекти" -#: gitk:11547 +#: gitk:11671 msgid "(change requires restart)" msgstr "(промяната изисква рестартиране на Gitk)" -#: gitk:11549 +#: gitk:11673 msgid "(currently unavailable)" msgstr "(в момента недостъпно)" -#: gitk:11560 +#: gitk:11685 msgid "Colors: press to choose" msgstr "Цветове: избира се с натискане" -#: gitk:11563 +#: gitk:11688 msgid "Interface" msgstr "Интерфейс" -#: gitk:11564 +#: gitk:11689 msgid "interface" msgstr "интерфейс" -#: gitk:11567 +#: gitk:11692 msgid "Background" msgstr "Фон" -#: gitk:11568 gitk:11598 +#: gitk:11693 gitk:11735 msgid "background" msgstr "фон" -#: gitk:11571 +#: gitk:11696 msgid "Foreground" msgstr "Знаци" -#: gitk:11572 +#: gitk:11697 msgid "foreground" msgstr "знаци" -#: gitk:11575 +#: gitk:11700 msgid "Diff: old lines" msgstr "Разлика: стари редове" -#: gitk:11576 +#: gitk:11701 msgid "diff old lines" msgstr "разлика, стари редове" -#: gitk:11580 +#: gitk:11705 +msgid "Diff: old lines bg" +msgstr "Разлика: фон на стари редове" + +#: gitk:11707 +msgid "diff old lines bg" +msgstr "разлика, фон на стари редове" + +#: gitk:11711 msgid "Diff: new lines" msgstr "Разлика: нови редове" -#: gitk:11581 +#: gitk:11712 msgid "diff new lines" msgstr "разлика, нови редове" -#: gitk:11585 +#: gitk:11716 +msgid "Diff: new lines bg" +msgstr "Разлика: фон на нови редове" + +#: gitk:11718 +msgid "diff new lines bg" +msgstr "разлика, фон на нови редове" + +#: gitk:11722 msgid "Diff: hunk header" msgstr "Разлика: начало на парче" -#: gitk:11587 +#: gitk:11724 msgid "diff hunk header" msgstr "разлика, начало на парче" -#: gitk:11591 +#: gitk:11728 msgid "Marked line bg" msgstr "Фон на отбелязан ред" -#: gitk:11593 +#: gitk:11730 msgid "marked line background" msgstr "фон на отбелязан ред" -#: gitk:11597 +#: gitk:11734 msgid "Select bg" msgstr "Избор на фон" -#: gitk:11606 +#: gitk:11743 msgid "Fonts: press to choose" msgstr "Шрифтове: избира се с натискане" -#: gitk:11608 +#: gitk:11745 msgid "Main font" msgstr "Основен шрифт" -#: gitk:11609 +#: gitk:11746 msgid "Diff display font" msgstr "Шрифт за разликите" -#: gitk:11610 +#: gitk:11747 msgid "User interface font" msgstr "Шрифт на интерфейса" -#: gitk:11632 +#: gitk:11769 msgid "Gitk preferences" msgstr "Настройки на Gitk" -#: gitk:11641 +#: gitk:11778 msgid "General" msgstr "Общи" -#: gitk:11642 +#: gitk:11779 msgid "Colors" msgstr "Цветове" -#: gitk:11643 +#: gitk:11780 msgid "Fonts" msgstr "Шрифтове" -#: gitk:11693 +#: gitk:11830 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: избор на цвят на „%s“" -#: gitk:12206 +#: gitk:12350 msgid "" "Sorry, gitk cannot run with this version of Tcl/Tk.\n" " Gitk requires at least Tcl/Tk 8.4." @@ -1393,15 +1433,15 @@ msgstr "" "Тази версия на Tcl/Tk не се поддържа от Gitk.\n" " Необходима ви е поне Tcl/Tk 8.4." -#: gitk:12416 +#: gitk:12571 msgid "Cannot find a git repository here." msgstr "Тук липсва хранилище на Git." -#: gitk:12463 +#: gitk:12618 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Нееднозначен аргумент „%s“: има и такава версия, и такъв файл" -#: gitk:12475 +#: gitk:12630 msgid "Bad arguments to gitk:" msgstr "Неправилни аргументи на gitk:" diff --git a/gitk-git/po/meson.build b/gitk-git/po/meson.build new file mode 100644 index 00000000000000..b1ed0198285815 --- /dev/null +++ b/gitk-git/po/meson.build @@ -0,0 +1,19 @@ +import('i18n').gettext('gitk', + languages: [ + 'bg', + 'ca', + 'de', + 'es', + 'fr', + 'hu', + 'it', + 'ja', + 'pt_br', + 'pt_pt', + 'ru', + 'sv', + 'vi', + 'zh_cn', + ], + install: true, +) diff --git a/gitk-git/po/sv.po b/gitk-git/po/sv.po index 2a06fe5bbcf826..5afbe6da1d6ab0 100644 --- a/gitk-git/po/sv.po +++ b/gitk-git/po/sv.po @@ -3,14 +3,14 @@ # This file is distributed under the same license as the gitk package. # # Mikael Magnusson <mikachu@gmail.com>, 2008. -# Peter Krefting <peter@softwolves.pp.se>, 2008, 2009, 2010, 2012, 2013, 2015. +# Peter Krefting <peter@softwolves.pp.se>, 2008-2023. # msgid "" msgstr "" "Project-Id-Version: sv\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-09 09:40+0100\n" -"PO-Revision-Date: 2015-12-11 09:46+0100\n" +"POT-Creation-Date: 2023-10-26 21:39+0100\n" +"PO-Revision-Date: 2023-10-26 21:42+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -18,35 +18,35 @@ 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 2.91.6\n" +"X-Generator: Gtranslator 3.38.0\n" -#: gitk:140 +#: gitk:139 msgid "Couldn't get list of unmerged files:" msgstr "Kunde inte hämta lista över ej sammanslagna filer:" -#: gitk:212 gitk:2381 +#: gitk:211 gitk:2406 msgid "Color words" msgstr "Färga ord" -#: gitk:217 gitk:2381 gitk:8221 gitk:8254 +#: gitk:216 gitk:2406 gitk:8307 gitk:8340 msgid "Markup words" msgstr "Märk upp ord" -#: gitk:324 +#: gitk:323 msgid "Error parsing revisions:" msgstr "Fel vid tolkning av revisioner:" -#: gitk:380 +#: gitk:379 msgid "Error executing --argscmd command:" msgstr "Fel vid körning av --argscmd-kommando:" -#: gitk:393 +#: gitk:392 msgid "No files selected: --merge specified but no files are unmerged." msgstr "" "Inga filer valdes: --merge angavs men det finns inga filer som inte har " "slagits samman." -#: gitk:396 +#: gitk:395 msgid "" "No files selected: --merge specified but no unmerged files are within file " "limit." @@ -54,322 +54,326 @@ msgstr "" "Inga filer valdes: --merge angavs men det finns inga filer inom " "filbegränsningen." -#: gitk:418 gitk:566 +#: gitk:417 gitk:565 msgid "Error executing git log:" msgstr "Fel vid körning av git log:" -#: gitk:436 gitk:582 +#: gitk:435 gitk:581 msgid "Reading" msgstr "Läser" -#: gitk:496 gitk:4526 +#: gitk:495 gitk:4572 msgid "Reading commits..." msgstr "Läser incheckningar..." -#: gitk:499 gitk:1637 gitk:4529 +#: gitk:498 gitk:1640 gitk:4575 msgid "No commits selected" msgstr "Inga incheckningar markerade" -#: gitk:1445 gitk:4046 gitk:12447 +#: gitk:1448 gitk:4092 gitk:12674 msgid "Command line" msgstr "Kommandorad" -#: gitk:1511 +#: gitk:1514 msgid "Can't parse git log output:" msgstr "Kan inte tolka utdata från git log:" -#: gitk:1740 +#: gitk:1743 msgid "No commit information available" msgstr "Ingen incheckningsinformation är tillgänglig" -#: gitk:1903 gitk:1932 gitk:4316 gitk:9684 gitk:11256 gitk:11536 +#: gitk:1910 gitk:1939 gitk:4362 gitk:9847 gitk:11451 gitk:11751 msgid "OK" msgstr "OK" -#: gitk:1934 gitk:4318 gitk:9197 gitk:9276 gitk:9406 gitk:9455 gitk:9686 -#: gitk:11257 gitk:11537 +#: gitk:1941 gitk:4364 gitk:9283 gitk:9362 gitk:9492 gitk:9578 gitk:9849 +#: gitk:11452 gitk:11752 msgid "Cancel" msgstr "Avbryt" -#: gitk:2069 +#: gitk:2090 msgid "&Update" msgstr "&Uppdatera" -#: gitk:2070 +#: gitk:2091 msgid "&Reload" msgstr "Läs &om" -#: gitk:2071 +#: gitk:2092 msgid "Reread re&ferences" msgstr "Läs om &referenser" -#: gitk:2072 +#: gitk:2093 msgid "&List references" msgstr "&Visa referenser" -#: gitk:2074 +#: gitk:2095 msgid "Start git &gui" msgstr "Starta git &gui" -#: gitk:2076 +#: gitk:2097 msgid "&Quit" msgstr "&Avsluta" -#: gitk:2068 +#: gitk:2089 msgid "&File" msgstr "&Arkiv" -#: gitk:2080 +#: gitk:2101 msgid "&Preferences" msgstr "&Inställningar" -#: gitk:2079 +#: gitk:2100 msgid "&Edit" msgstr "&Redigera" -#: gitk:2084 +#: gitk:2105 msgid "&New view..." msgstr "&Ny vy..." -#: gitk:2085 +#: gitk:2106 msgid "&Edit view..." msgstr "&Ändra vy..." -#: gitk:2086 +#: gitk:2107 msgid "&Delete view" msgstr "&Ta bort vy" -#: gitk:2088 +#: gitk:2109 msgid "&All files" msgstr "&Alla filer" -#: gitk:2083 +#: gitk:2104 msgid "&View" msgstr "&Visa" -#: gitk:2093 gitk:2103 +#: gitk:2114 gitk:2124 msgid "&About gitk" msgstr "&Om gitk" -#: gitk:2094 gitk:2108 +#: gitk:2115 gitk:2129 msgid "&Key bindings" msgstr "&Tangentbordsbindningar" -#: gitk:2092 gitk:2107 +#: gitk:2113 gitk:2128 msgid "&Help" msgstr "&Hjälp" -#: gitk:2185 gitk:8653 +#: gitk:2206 gitk:8739 msgid "SHA1 ID:" msgstr "SHA1-id:" -#: gitk:2229 +#: gitk:2250 msgid "Row" msgstr "Rad" -#: gitk:2267 +#: gitk:2288 msgid "Find" msgstr "Sök" -#: gitk:2295 +#: gitk:2316 msgid "commit" msgstr "incheckning" -#: gitk:2299 gitk:2301 gitk:4688 gitk:4711 gitk:4735 gitk:6756 gitk:6828 -#: gitk:6913 +#: gitk:2320 gitk:2322 gitk:4734 gitk:4757 gitk:4781 gitk:6802 gitk:6874 +#: gitk:6959 msgid "containing:" msgstr "som innehåller:" -#: gitk:2302 gitk:3527 gitk:3532 gitk:4764 +#: gitk:2323 gitk:3573 gitk:3578 gitk:4810 msgid "touching paths:" msgstr "som rör sökväg:" -#: gitk:2303 gitk:4778 +#: gitk:2324 gitk:4824 msgid "adding/removing string:" msgstr "som lägger/till tar bort sträng:" -#: gitk:2304 gitk:4780 +#: gitk:2325 gitk:4826 msgid "changing lines matching:" msgstr "ändrar rader som matchar:" -#: gitk:2313 gitk:2315 gitk:4767 +#: gitk:2334 gitk:2336 gitk:4813 msgid "Exact" msgstr "Exakt" -#: gitk:2315 gitk:4855 gitk:6724 +#: gitk:2336 gitk:4901 gitk:6770 msgid "IgnCase" msgstr "IgnVersaler" -#: gitk:2315 gitk:4737 gitk:4853 gitk:6720 +#: gitk:2336 gitk:4783 gitk:4899 gitk:6766 msgid "Regexp" msgstr "Reg.uttr." -#: gitk:2317 gitk:2318 gitk:4875 gitk:4905 gitk:4912 gitk:6849 gitk:6917 +#: gitk:2338 gitk:2339 gitk:4921 gitk:4951 gitk:4958 gitk:6895 gitk:6963 msgid "All fields" msgstr "Alla fält" -#: gitk:2318 gitk:4872 gitk:4905 gitk:6787 +#: gitk:2339 gitk:4918 gitk:4951 gitk:6833 msgid "Headline" msgstr "Rubrik" -#: gitk:2319 gitk:4872 gitk:6787 gitk:6917 gitk:7390 +#: gitk:2340 gitk:4918 gitk:6833 gitk:6963 gitk:7471 msgid "Comments" msgstr "Kommentarer" -#: gitk:2319 gitk:4872 gitk:4877 gitk:4912 gitk:6787 gitk:7325 gitk:8831 -#: gitk:8846 +#: gitk:2340 gitk:4918 gitk:4923 gitk:4958 gitk:6833 gitk:7406 gitk:8917 +#: gitk:8932 msgid "Author" msgstr "Författare" -#: gitk:2319 gitk:4872 gitk:6787 gitk:7327 +#: gitk:2340 gitk:4918 gitk:6833 gitk:7408 msgid "Committer" msgstr "Incheckare" -#: gitk:2350 +#: gitk:2374 msgid "Search" msgstr "Sök" -#: gitk:2358 +#: gitk:2382 msgid "Diff" msgstr "Diff" -#: gitk:2360 +#: gitk:2384 msgid "Old version" msgstr "Gammal version" -#: gitk:2362 +#: gitk:2386 msgid "New version" msgstr "Ny version" -#: gitk:2364 +#: gitk:2389 msgid "Lines of context" msgstr "Rader sammanhang" -#: gitk:2374 +#: gitk:2399 msgid "Ignore space change" msgstr "Ignorera ändringar i blanksteg" -#: gitk:2378 gitk:2380 gitk:7960 gitk:8207 +#: gitk:2403 gitk:2405 gitk:8041 gitk:8293 msgid "Line diff" msgstr "Rad-diff" -#: gitk:2445 +#: gitk:2478 msgid "Patch" msgstr "Patch" -#: gitk:2447 +#: gitk:2480 msgid "Tree" msgstr "Träd" -#: gitk:2617 gitk:2638 +#: gitk:2650 gitk:2671 msgid "Diff this -> selected" msgstr "Diff denna -> markerad" -#: gitk:2618 gitk:2639 +#: gitk:2651 gitk:2672 msgid "Diff selected -> this" msgstr "Diff markerad -> denna" -#: gitk:2619 gitk:2640 +#: gitk:2652 gitk:2673 msgid "Make patch" msgstr "Skapa patch" -#: gitk:2620 gitk:9255 +#: gitk:2653 gitk:9341 msgid "Create tag" msgstr "Skapa tagg" -#: gitk:2621 -msgid "Copy commit summary" -msgstr "Kopiera incheckningssammanfattning" +#: gitk:2654 +msgid "Copy commit reference" +msgstr "Kopiera incheckningsreferens" -#: gitk:2622 gitk:9386 +#: gitk:2655 gitk:9472 msgid "Write commit to file" msgstr "Skriv incheckning till fil" -#: gitk:2623 gitk:9443 +#: gitk:2656 msgid "Create new branch" msgstr "Skapa ny gren" -#: gitk:2624 +#: gitk:2657 msgid "Cherry-pick this commit" msgstr "Plocka denna incheckning" -#: gitk:2625 +#: gitk:2658 msgid "Reset HEAD branch to here" msgstr "Återställ HEAD-grenen hit" -#: gitk:2626 +#: gitk:2659 msgid "Mark this commit" msgstr "Markera denna incheckning" -#: gitk:2627 +#: gitk:2660 msgid "Return to mark" msgstr "Återgå till markering" -#: gitk:2628 +#: gitk:2661 msgid "Find descendant of this and mark" msgstr "Hitta efterföljare till denna och markera" -#: gitk:2629 +#: gitk:2662 msgid "Compare with marked commit" msgstr "Jämför med markerad incheckning" -#: gitk:2630 gitk:2641 +#: gitk:2663 gitk:2674 msgid "Diff this -> marked commit" msgstr "Diff denna -> markerad incheckning" -#: gitk:2631 gitk:2642 +#: gitk:2664 gitk:2675 msgid "Diff marked commit -> this" msgstr "Diff markerad incheckning -> denna" -#: gitk:2632 +#: gitk:2665 msgid "Revert this commit" msgstr "Ångra denna incheckning" -#: gitk:2648 +#: gitk:2681 msgid "Check out this branch" msgstr "Checka ut denna gren" -#: gitk:2649 +#: gitk:2682 +msgid "Rename this branch" +msgstr "Byt namn på denna gren" + +#: gitk:2683 msgid "Remove this branch" msgstr "Ta bort denna gren" -#: gitk:2650 +#: gitk:2684 msgid "Copy branch name" msgstr "Kopiera namn på gren" -#: gitk:2657 +#: gitk:2691 msgid "Highlight this too" msgstr "Markera även detta" -#: gitk:2658 +#: gitk:2692 msgid "Highlight this only" msgstr "Markera bara detta" -#: gitk:2659 +#: gitk:2693 msgid "External diff" msgstr "Extern diff" -#: gitk:2660 +#: gitk:2694 msgid "Blame parent commit" msgstr "Klandra föräldraincheckning" -#: gitk:2661 +#: gitk:2695 msgid "Copy path" msgstr "Kopiera sökväg" -#: gitk:2668 +#: gitk:2702 msgid "Show origin of this line" msgstr "Visa ursprunget för den här raden" -#: gitk:2669 +#: gitk:2703 msgid "Run git gui blame on this line" msgstr "Kör git gui blame på den här raden" -#: gitk:3013 +#: gitk:3057 msgid "About gitk" msgstr "Om gitk" -#: gitk:3015 +#: gitk:3059 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -385,525 +389,529 @@ msgstr "" "\n" "Använd och vidareförmedla enligt villkoren i GNU General Public License" -#: gitk:3023 gitk:3090 gitk:9872 +#: gitk:3067 gitk:3134 gitk:10062 msgid "Close" msgstr "Stäng" -#: gitk:3044 +#: gitk:3088 msgid "Gitk key bindings" msgstr "Tangentbordsbindningar för Gitk" -#: gitk:3047 +#: gitk:3091 msgid "Gitk key bindings:" msgstr "Tangentbordsbindningar för Gitk:" -#: gitk:3049 +#: gitk:3093 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tAvsluta" -#: gitk:3050 +#: gitk:3094 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tStäng fönster" -#: gitk:3051 +#: gitk:3095 msgid "<Home>\t\tMove to first commit" msgstr "<Home>\t\tGå till första incheckning" -#: gitk:3052 +#: gitk:3096 msgid "<End>\t\tMove to last commit" msgstr "<End>\t\tGå till sista incheckning" -#: gitk:3053 +#: gitk:3097 msgid "<Up>, p, k\tMove up one commit" msgstr "<Upp>, p, k\tGå en incheckning upp" -#: gitk:3054 +#: gitk:3098 msgid "<Down>, n, j\tMove down one commit" msgstr "<Ned>, n, j\tGå en incheckning ned" -#: gitk:3055 +#: gitk:3099 msgid "<Left>, z, h\tGo back in history list" msgstr "<Vänster>, z, h\tGå bakåt i historiken" -#: gitk:3056 +#: gitk:3100 msgid "<Right>, x, l\tGo forward in history list" msgstr "<Höger>, x, l\tGå framåt i historiken" -#: gitk:3057 +#: gitk:3101 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" msgstr "<%s-n>\tGå till aktuell inchecknings n:te förälder i historielistan" -#: gitk:3058 +#: gitk:3102 msgid "<PageUp>\tMove up one page in commit list" msgstr "<PageUp>\tGå upp en sida i incheckningslistan" -#: gitk:3059 +#: gitk:3103 msgid "<PageDown>\tMove down one page in commit list" msgstr "<PageDown>\tGå ned en sida i incheckningslistan" -#: gitk:3060 +#: gitk:3104 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tRulla till början av incheckningslistan" -#: gitk:3061 +#: gitk:3105 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tRulla till slutet av incheckningslistan" -#: gitk:3062 +#: gitk:3106 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Upp>\tRulla incheckningslistan upp ett steg" -#: gitk:3063 +#: gitk:3107 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Ned>\tRulla incheckningslistan ned ett steg" -#: gitk:3064 +#: gitk:3108 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tRulla incheckningslistan upp en sida" -#: gitk:3065 +#: gitk:3109 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tRulla incheckningslistan ned en sida" -#: gitk:3066 +#: gitk:3110 msgid "<Shift-Up>\tFind backwards (upwards, later commits)" msgstr "<Skift-Upp>\tSök bakåt (uppåt, senare incheckningar)" -#: gitk:3067 +#: gitk:3111 msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)" msgstr "<Skift-Ned>\tSök framåt (nedåt, tidigare incheckningar)" -#: gitk:3068 +#: gitk:3112 msgid "<Delete>, b\tScroll diff view up one page" msgstr "<Delete>, b\tRulla diffvisningen upp en sida" -#: gitk:3069 +#: gitk:3113 msgid "<Backspace>\tScroll diff view up one page" msgstr "<Baksteg>\tRulla diffvisningen upp en sida" -#: gitk:3070 +#: gitk:3114 msgid "<Space>\t\tScroll diff view down one page" msgstr "<Blanksteg>\tRulla diffvisningen ned en sida" -#: gitk:3071 +#: gitk:3115 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\tRulla diffvisningen upp 18 rader" -#: gitk:3072 +#: gitk:3116 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\tRulla diffvisningen ned 18 rader" -#: gitk:3073 +#: gitk:3117 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tSök" -#: gitk:3074 +#: gitk:3118 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tGå till nästa sökträff" -#: gitk:3075 +#: gitk:3119 msgid "<Return>\tMove to next find hit" msgstr "<Return>\t\tGå till nästa sökträff" -#: gitk:3076 +#: gitk:3120 msgid "g\t\tGo to commit" msgstr "g\t\tGå till incheckning" -#: gitk:3077 +#: gitk:3121 msgid "/\t\tFocus the search box" msgstr "/\t\tFokusera sökrutan" -#: gitk:3078 +#: gitk:3122 msgid "?\t\tMove to previous find hit" msgstr "?\t\tGå till föregående sökträff" -#: gitk:3079 +#: gitk:3123 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tRulla diffvisningen till nästa fil" -#: gitk:3080 +#: gitk:3124 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tGå till nästa sökträff i diffvisningen" -#: gitk:3081 +#: gitk:3125 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tGå till föregående sökträff i diffvisningen" -#: gitk:3082 +#: gitk:3126 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-Num+>\tÖka teckenstorlek" -#: gitk:3083 +#: gitk:3127 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tÖka teckenstorlek" -#: gitk:3084 +#: gitk:3128 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-Num->\tMinska teckenstorlek" -#: gitk:3085 +#: gitk:3129 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tMinska teckenstorlek" -#: gitk:3086 +#: gitk:3130 msgid "<F5>\t\tUpdate" msgstr "<F5>\t\tUppdatera" -#: gitk:3551 gitk:3560 +#: gitk:3597 gitk:3606 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Fel vid skapande av temporär katalog %s:" -#: gitk:3573 +#: gitk:3619 #, tcl-format msgid "Error getting \"%s\" from %s:" -msgstr "Fel vid hämtning av \"%s\" från %s:" +msgstr "Fel vid hämtning av ”%s” från %s:" -#: gitk:3636 +#: gitk:3682 msgid "command failed:" msgstr "kommando misslyckades:" -#: gitk:3785 +#: gitk:3831 msgid "No such commit" msgstr "Incheckning saknas" -#: gitk:3799 +#: gitk:3845 msgid "git gui blame: command failed:" msgstr "git gui blame: kommando misslyckades:" -#: gitk:3830 +#: gitk:3876 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Kunde inte läsa sammanslagningshuvud: %s" -#: gitk:3838 +#: gitk:3884 #, tcl-format msgid "Error reading index: %s" msgstr "Fel vid läsning av index: %s" -#: gitk:3863 +#: gitk:3909 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Kunde inte starta git blame: %s" -#: gitk:3866 gitk:6755 +#: gitk:3912 gitk:6801 msgid "Searching" msgstr "Söker" -#: gitk:3898 +#: gitk:3944 #, tcl-format msgid "Error running git blame: %s" msgstr "Fel vid körning av git blame: %s" -#: gitk:3926 +#: gitk:3972 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Raden kommer från incheckningen %s, som inte finns i denna vy" -#: gitk:3940 +#: gitk:3986 msgid "External diff viewer failed:" msgstr "Externt diff-verktyg misslyckades:" -#: gitk:4044 +#: gitk:4090 msgid "All files" msgstr "Alla filer" -#: gitk:4068 +#: gitk:4114 msgid "View" msgstr "Visa" -#: gitk:4071 +#: gitk:4117 msgid "Gitk view definition" msgstr "Definition av Gitk-vy" -#: gitk:4075 +#: gitk:4121 msgid "Remember this view" msgstr "Spara denna vy" -#: gitk:4076 +#: gitk:4122 msgid "References (space separated list):" msgstr "Referenser (blankstegsavdelad lista):" -#: gitk:4077 +#: gitk:4123 msgid "Branches & tags:" msgstr "Grenar & taggar:" -#: gitk:4078 +#: gitk:4124 msgid "All refs" msgstr "Alla referenser" -#: gitk:4079 +#: gitk:4125 msgid "All (local) branches" msgstr "Alla (lokala) grenar" -#: gitk:4080 +#: gitk:4126 msgid "All tags" msgstr "Alla taggar" -#: gitk:4081 +#: gitk:4127 msgid "All remote-tracking branches" msgstr "Alla fjärrspårande grenar" -#: gitk:4082 +#: gitk:4128 msgid "Commit Info (regular expressions):" msgstr "Incheckningsinfo (reguljära uttryck):" -#: gitk:4083 +#: gitk:4129 msgid "Author:" msgstr "Författare:" -#: gitk:4084 +#: gitk:4130 msgid "Committer:" msgstr "Incheckare:" -#: gitk:4085 +#: gitk:4131 msgid "Commit Message:" msgstr "Incheckningsmeddelande:" -#: gitk:4086 +#: gitk:4132 msgid "Matches all Commit Info criteria" msgstr "Motsvarar alla kriterier för incheckningsinfo" -#: gitk:4087 +#: gitk:4133 msgid "Matches no Commit Info criteria" msgstr "Motsvarar inga kriterier för incheckningsinfo" -#: gitk:4088 +#: gitk:4134 msgid "Changes to Files:" msgstr "Ändringar av filer:" -#: gitk:4089 +#: gitk:4135 msgid "Fixed String" msgstr "Fast sträng" -#: gitk:4090 +#: gitk:4136 msgid "Regular Expression" msgstr "Reguljärt uttryck" -#: gitk:4091 +#: gitk:4137 msgid "Search string:" msgstr "Söksträng:" -#: gitk:4092 +#: gitk:4138 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" msgstr "" -"Incheckingsdatum (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " -"15:27:38\"):" +"Incheckningsdatum (”2 weeks ago”, ”2009-03-17 15:27:38”, ”March 17, 2009 " +"15:27:38”):" -#: gitk:4093 +#: gitk:4139 msgid "Since:" msgstr "Från:" -#: gitk:4094 +#: gitk:4140 msgid "Until:" msgstr "Till:" -#: gitk:4095 +#: gitk:4141 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "Begränsa och/eller hoppa över ett antal revisioner (positivt heltal):" -#: gitk:4096 +#: gitk:4142 msgid "Number to show:" msgstr "Antal att visa:" -#: gitk:4097 +#: gitk:4143 msgid "Number to skip:" msgstr "Antal att hoppa över:" -#: gitk:4098 +#: gitk:4144 msgid "Miscellaneous options:" msgstr "Diverse alternativ:" -#: gitk:4099 +#: gitk:4145 msgid "Strictly sort by date" msgstr "Strikt datumsortering" -#: gitk:4100 +#: gitk:4146 msgid "Mark branch sides" msgstr "Markera sidogrenar" -#: gitk:4101 +#: gitk:4147 msgid "Limit to first parent" msgstr "Begränsa till första förälder" -#: gitk:4102 +#: gitk:4148 msgid "Simple history" msgstr "Enkel historik" -#: gitk:4103 +#: gitk:4149 msgid "Additional arguments to git log:" msgstr "Ytterligare argument till git log:" -#: gitk:4104 +#: gitk:4150 msgid "Enter files and directories to include, one per line:" msgstr "Ange filer och kataloger att ta med, en per rad:" -#: gitk:4105 +#: gitk:4151 msgid "Command to generate more commits to include:" msgstr "Kommando för att generera fler incheckningar att ta med:" -#: gitk:4229 +#: gitk:4275 msgid "Gitk: edit view" msgstr "Gitk: redigera vy" -#: gitk:4237 +#: gitk:4283 msgid "-- criteria for selecting revisions" msgstr " - kriterier för val av revisioner" -#: gitk:4242 +#: gitk:4288 msgid "View Name" msgstr "Namn på vy" -#: gitk:4317 +#: gitk:4363 msgid "Apply (F5)" msgstr "Använd (F5)" -#: gitk:4355 +#: gitk:4401 msgid "Error in commit selection arguments:" msgstr "Fel i argument för val av incheckningar:" -#: gitk:4410 gitk:4463 gitk:4925 gitk:4939 gitk:6209 gitk:12388 gitk:12389 +#: gitk:4456 gitk:4509 gitk:4971 gitk:4985 gitk:6255 gitk:12615 gitk:12616 msgid "None" msgstr "Inget" -#: gitk:5022 gitk:5027 +#: gitk:5068 gitk:5073 msgid "Descendant" msgstr "Avkomling" -#: gitk:5023 +#: gitk:5069 msgid "Not descendant" msgstr "Inte avkomling" -#: gitk:5030 gitk:5035 +#: gitk:5076 gitk:5081 msgid "Ancestor" msgstr "Förfader" -#: gitk:5031 +#: gitk:5077 msgid "Not ancestor" msgstr "Inte förfader" -#: gitk:5325 +#: gitk:5371 msgid "Local changes checked in to index but not committed" msgstr "Lokala ändringar sparade i indexet men inte incheckade" -#: gitk:5361 +#: gitk:5407 msgid "Local uncommitted changes, not checked in to index" msgstr "Lokala ändringar, ej sparade i indexet" -#: gitk:7135 +#: gitk:7155 +msgid "Error starting web browser:" +msgstr "Fel när webbläsaren skulle startas:" + +#: gitk:7216 msgid "and many more" msgstr "med många flera" -#: gitk:7138 +#: gitk:7219 msgid "many" msgstr "många" -#: gitk:7329 +#: gitk:7410 msgid "Tags:" msgstr "Taggar:" -#: gitk:7346 gitk:7352 gitk:8826 +#: gitk:7427 gitk:7433 gitk:8912 msgid "Parent" msgstr "Förälder" -#: gitk:7357 +#: gitk:7438 msgid "Child" msgstr "Barn" -#: gitk:7366 +#: gitk:7447 msgid "Branch" msgstr "Gren" -#: gitk:7369 +#: gitk:7450 msgid "Follows" msgstr "Följer" -#: gitk:7372 +#: gitk:7453 msgid "Precedes" msgstr "Föregår" -#: gitk:7967 +#: gitk:8048 #, tcl-format msgid "Error getting diffs: %s" msgstr "Fel vid hämtning av diff: %s" -#: gitk:8651 +#: gitk:8737 msgid "Goto:" msgstr "Gå till:" -#: gitk:8672 +#: gitk:8758 #, tcl-format msgid "Short SHA1 id %s is ambiguous" msgstr "Förkortat SHA1-id %s är tvetydigt" -#: gitk:8679 +#: gitk:8765 #, tcl-format msgid "Revision %s is not known" msgstr "Revisionen %s är inte känd" -#: gitk:8689 +#: gitk:8775 #, tcl-format msgid "SHA1 id %s is not known" msgstr "SHA-id:t %s är inte känt" -#: gitk:8691 +#: gitk:8777 #, tcl-format msgid "Revision %s is not in the current view" msgstr "Revisionen %s finns inte i den nuvarande vyn" -#: gitk:8833 gitk:8848 +#: gitk:8919 gitk:8934 msgid "Date" msgstr "Datum" -#: gitk:8836 +#: gitk:8922 msgid "Children" msgstr "Barn" -#: gitk:8899 +#: gitk:8985 #, tcl-format msgid "Reset %s branch to here" msgstr "Återställ grenen %s hit" -#: gitk:8901 +#: gitk:8987 msgid "Detached head: can't reset" msgstr "Frånkopplad head: kan inte återställa" -#: gitk:9006 gitk:9012 +#: gitk:9092 gitk:9098 msgid "Skipping merge commit " msgstr "Hoppar över sammanslagningsincheckning " -#: gitk:9021 gitk:9026 +#: gitk:9107 gitk:9112 msgid "Error getting patch ID for " msgstr "Fel vid hämtning av patch-id för " -#: gitk:9022 gitk:9027 +#: gitk:9108 gitk:9113 msgid " - stopping\n" msgstr " - stannar\n" -#: gitk:9032 gitk:9035 gitk:9043 gitk:9057 gitk:9066 +#: gitk:9118 gitk:9121 gitk:9129 gitk:9143 gitk:9152 msgid "Commit " msgstr "Incheckning " -#: gitk:9036 +#: gitk:9122 msgid "" " is the same patch as\n" " " @@ -911,7 +919,7 @@ msgstr "" " är samma patch som\n" " " -#: gitk:9044 +#: gitk:9130 msgid "" " differs from\n" " " @@ -919,7 +927,7 @@ msgstr "" " skiljer sig från\n" " " -#: gitk:9046 +#: gitk:9132 msgid "" "Diff of commits:\n" "\n" @@ -927,141 +935,158 @@ msgstr "" "Skillnad mellan incheckningar:\n" "\n" -#: gitk:9058 gitk:9067 +#: gitk:9144 gitk:9153 #, tcl-format msgid " has %s children - stopping\n" msgstr " har %s barn - stannar\n" -#: gitk:9086 +#: gitk:9172 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Fel vid skrivning av incheckning till fil: %s" -#: gitk:9092 +#: gitk:9178 #, tcl-format msgid "Error diffing commits: %s" msgstr "Fel vid jämförelse av incheckningar: %s" -#: gitk:9138 +#: gitk:9224 msgid "Top" msgstr "Topp" -#: gitk:9139 +#: gitk:9225 msgid "From" msgstr "Från" -#: gitk:9144 +#: gitk:9230 msgid "To" msgstr "Till" -#: gitk:9168 +#: gitk:9254 msgid "Generate patch" msgstr "Generera patch" -#: gitk:9170 +#: gitk:9256 msgid "From:" msgstr "Från:" -#: gitk:9179 +#: gitk:9265 msgid "To:" msgstr "Till:" -#: gitk:9188 +#: gitk:9274 msgid "Reverse" msgstr "Vänd" -#: gitk:9190 gitk:9400 +#: gitk:9276 gitk:9486 msgid "Output file:" msgstr "Utdatafil:" -#: gitk:9196 +#: gitk:9282 msgid "Generate" msgstr "Generera" -#: gitk:9234 +#: gitk:9320 msgid "Error creating patch:" msgstr "Fel vid generering av patch:" -#: gitk:9257 gitk:9388 gitk:9445 +#: gitk:9343 gitk:9474 gitk:9562 msgid "ID:" msgstr "Id:" -#: gitk:9266 +#: gitk:9352 msgid "Tag name:" msgstr "Taggnamn:" -#: gitk:9269 +#: gitk:9355 msgid "Tag message is optional" msgstr "Taggmeddelandet är valfritt" -#: gitk:9271 +#: gitk:9357 msgid "Tag message:" msgstr "Taggmeddelande:" -#: gitk:9275 gitk:9454 +#: gitk:9361 gitk:9532 msgid "Create" msgstr "Skapa" -#: gitk:9293 +#: gitk:9379 msgid "No tag name specified" msgstr "Inget taggnamn angavs" -#: gitk:9297 +#: gitk:9383 #, tcl-format msgid "Tag \"%s\" already exists" -msgstr "Taggen \"%s\" finns redan" +msgstr "Taggen ”%s” finns redan" -#: gitk:9307 +#: gitk:9393 msgid "Error creating tag:" msgstr "Fel vid skapande av tagg:" -#: gitk:9397 +#: gitk:9483 msgid "Command:" msgstr "Kommando:" -#: gitk:9405 +#: gitk:9491 msgid "Write" msgstr "Skriv" -#: gitk:9423 +#: gitk:9509 msgid "Error writing commit:" msgstr "Fel vid skrivning av incheckning:" -#: gitk:9450 +#: gitk:9531 +msgid "Create branch" +msgstr "Skapa gren" + +#: gitk:9547 +#, tcl-format +msgid "Rename branch %s" +msgstr "Byt namn på grenen %s" + +#: gitk:9548 +msgid "Rename" +msgstr "Byt namn" + +#: gitk:9572 msgid "Name:" msgstr "Namn:" -#: gitk:9473 +#: gitk:9596 msgid "Please specify a name for the new branch" msgstr "Ange ett namn för den nya grenen" -#: gitk:9478 +#: gitk:9601 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" -msgstr "Grenen \"%s\" finns redan. Skriva över?" +msgstr "Grenen ”%s” finns redan. Skriva över?" + +#: gitk:9645 +msgid "Please specify a new name for the branch" +msgstr "Ange ett nytt namn för grenen" -#: gitk:9545 +#: gitk:9708 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Incheckningen %s finns redan på grenen %s -- skall den verkligen appliceras " "på nytt?" -#: gitk:9550 +#: gitk:9713 msgid "Cherry-picking" msgstr "Plockar" -#: gitk:9559 +#: gitk:9722 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" "Please commit, reset or stash your changes and try again." msgstr "" -"Cherry-pick misslyckades på grund av lokala ändringar i filen \"%s\".\n" +"Cherry-pick misslyckades på grund av lokala ändringar i filen ”%s”.\n" "Checka in, återställ eller spara undan (stash) dina ändringar och försök " "igen." -#: gitk:9565 +#: gitk:9728 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1069,20 +1094,20 @@ msgstr "" "Cherry-pick misslyckades på grund av en sammanslagningskonflikt.\n" "Vill du köra git citool för att lösa den?" -#: gitk:9581 gitk:9639 +#: gitk:9744 gitk:9802 msgid "No changes committed" msgstr "Inga ändringar incheckade" -#: gitk:9608 +#: gitk:9771 #, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" msgstr "Incheckningen %s finns inte på grenen %s -- vill du verkligen ångra?" -#: gitk:9613 +#: gitk:9776 msgid "Reverting" msgstr "Ångrar" -#: gitk:9621 +#: gitk:9784 #, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " @@ -1092,7 +1117,7 @@ msgstr "" "Checka in, återställ eller spara undan (stash) dina ändringar och försök " "igen." -#: gitk:9625 +#: gitk:9788 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" @@ -1100,28 +1125,28 @@ msgstr "" "Misslyckades med att ångra på grund av en sammanslagningskonflikt.\n" " Vill du köra git citool för att lösa den?" -#: gitk:9668 +#: gitk:9831 msgid "Confirm reset" msgstr "Bekräfta återställning" -#: gitk:9670 +#: gitk:9833 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Återställa grenen %s till %s?" -#: gitk:9672 +#: gitk:9835 msgid "Reset type:" msgstr "Typ av återställning:" -#: gitk:9675 +#: gitk:9838 msgid "Soft: Leave working tree and index untouched" msgstr "Mjuk: Rör inte utcheckning och index" -#: gitk:9678 +#: gitk:9841 msgid "Mixed: Leave working tree untouched, reset index" msgstr "Blandad: Rör inte utcheckning, återställ index" -#: gitk:9681 +#: gitk:9844 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" @@ -1129,19 +1154,24 @@ msgstr "" "Hård: Återställ utcheckning och index\n" "(förkastar ALLA lokala ändringar)" -#: gitk:9698 +#: gitk:9861 msgid "Resetting" msgstr "Återställer" -#: gitk:9758 +#: gitk:9934 +#, tcl-format +msgid "A local branch named %s exists already" +msgstr "Det finns redan en lokal gren som heter %s" + +#: gitk:9942 msgid "Checking out" msgstr "Checkar ut" -#: gitk:9811 +#: gitk:10001 msgid "Cannot delete the currently checked-out branch" msgstr "Kan inte ta bort den just nu utcheckade grenen" -#: gitk:9817 +#: gitk:10007 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1150,16 +1180,16 @@ msgstr "" "Incheckningarna på grenen %s existerar inte på någon annan gren.\n" "Vill du verkligen ta bort grenen %s?" -#: gitk:9848 +#: gitk:10038 #, tcl-format msgid "Tags and heads: %s" msgstr "Taggar och huvuden: %s" -#: gitk:9865 +#: gitk:10055 msgid "Filter" msgstr "Filter" -#: gitk:10161 +#: gitk:10356 msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1167,201 +1197,221 @@ msgstr "" "Fel vid läsning av information om incheckningstopologi; information om " "grenar och föregående/senare taggar kommer inte vara komplett." -#: gitk:11138 +#: gitk:11333 msgid "Tag" msgstr "Tagg" -#: gitk:11142 +#: gitk:11337 msgid "Id" msgstr "Id" -#: gitk:11225 +#: gitk:11420 msgid "Gitk font chooser" msgstr "Teckensnittsväljare för Gitk" -#: gitk:11242 +#: gitk:11437 msgid "B" msgstr "F" -#: gitk:11245 +#: gitk:11440 msgid "I" msgstr "K" -#: gitk:11363 +#: gitk:11558 msgid "Commit list display options" msgstr "Alternativ för incheckningslistvy" -#: gitk:11366 +#: gitk:11561 msgid "Maximum graph width (lines)" msgstr "Maximal grafbredd (rader)" -#: gitk:11370 +#: gitk:11565 #, no-tcl-format msgid "Maximum graph width (% of pane)" msgstr "Maximal grafbredd (% av ruta)" -#: gitk:11373 +#: gitk:11568 msgid "Show local changes" msgstr "Visa lokala ändringar" -#: gitk:11376 +#: gitk:11571 msgid "Auto-select SHA1 (length)" msgstr "Välj SHA1 (längd) automatiskt" -#: gitk:11380 +#: gitk:11575 msgid "Hide remote refs" msgstr "Dölj fjärr-referenser" -#: gitk:11384 +#: gitk:11579 msgid "Diff display options" msgstr "Alternativ för diffvy" -#: gitk:11386 +#: gitk:11581 msgid "Tab spacing" msgstr "Blanksteg för tabulatortecken" -#: gitk:11389 +#: gitk:11584 msgid "Display nearby tags/heads" msgstr "Visa närliggande taggar/huvuden" -#: gitk:11392 +#: gitk:11587 msgid "Maximum # tags/heads to show" msgstr "Maximalt antal taggar/huvuden att visa" -#: gitk:11395 +#: gitk:11590 msgid "Limit diffs to listed paths" msgstr "Begränsa diff till listade sökvägar" -#: gitk:11398 +#: gitk:11593 msgid "Support per-file encodings" msgstr "Stöd för filspecifika teckenkodningar" -#: gitk:11404 gitk:11551 +#: gitk:11599 gitk:11766 msgid "External diff tool" msgstr "Externt diff-verktyg" -#: gitk:11405 +#: gitk:11600 msgid "Choose..." msgstr "Välj..." -#: gitk:11410 +#: gitk:11607 +msgid "Web browser" +msgstr "Webbläsare" + +#: gitk:11612 msgid "General options" msgstr "Allmänna inställningar" -#: gitk:11413 +#: gitk:11615 msgid "Use themed widgets" msgstr "Använd tema på fönsterelement" -#: gitk:11415 +#: gitk:11617 msgid "(change requires restart)" msgstr "(ändringen kräver omstart)" -#: gitk:11417 +#: gitk:11619 msgid "(currently unavailable)" msgstr "(för närvarande inte tillgängligt)" -#: gitk:11428 +#: gitk:11631 msgid "Colors: press to choose" msgstr "Färger: tryck för att välja" -#: gitk:11431 +#: gitk:11634 msgid "Interface" msgstr "Gränssnitt" -#: gitk:11432 +#: gitk:11635 msgid "interface" msgstr "gränssnitt" -#: gitk:11435 +#: gitk:11638 msgid "Background" msgstr "Bakgrund" -#: gitk:11436 gitk:11466 +#: gitk:11639 gitk:11681 msgid "background" msgstr "bakgrund" -#: gitk:11439 +#: gitk:11642 msgid "Foreground" msgstr "Förgrund" -#: gitk:11440 +#: gitk:11643 msgid "foreground" msgstr "förgrund" -#: gitk:11443 +#: gitk:11646 msgid "Diff: old lines" msgstr "Diff: gamla rader" -#: gitk:11444 +#: gitk:11647 msgid "diff old lines" msgstr "diff gamla rader" -#: gitk:11448 +#: gitk:11651 +msgid "Diff: old lines bg" +msgstr "Diff: gamla rader bg" + +#: gitk:11653 +msgid "diff old lines bg" +msgstr "diff gamla rader bg" + +#: gitk:11657 msgid "Diff: new lines" msgstr "Diff: nya rader" -#: gitk:11449 +#: gitk:11658 msgid "diff new lines" msgstr "diff nya rader" -#: gitk:11453 +#: gitk:11662 +msgid "Diff: new lines bg" +msgstr "Diff: nya rader bg" + +#: gitk:11664 +msgid "diff new lines bg" +msgstr "diff nya rader bg" + +#: gitk:11668 msgid "Diff: hunk header" msgstr "Diff: delhuvud" -#: gitk:11455 +#: gitk:11670 msgid "diff hunk header" msgstr "diff delhuvud" -#: gitk:11459 +#: gitk:11674 msgid "Marked line bg" msgstr "Markerad rad bakgrund" -#: gitk:11461 +#: gitk:11676 msgid "marked line background" msgstr "markerad rad bakgrund" -#: gitk:11465 +#: gitk:11680 msgid "Select bg" msgstr "Markerad bakgrund" -#: gitk:11474 +#: gitk:11689 msgid "Fonts: press to choose" msgstr "Teckensnitt: tryck för att välja" -#: gitk:11476 +#: gitk:11691 msgid "Main font" msgstr "Huvudteckensnitt" -#: gitk:11477 +#: gitk:11692 msgid "Diff display font" msgstr "Teckensnitt för diffvisning" -#: gitk:11478 +#: gitk:11693 msgid "User interface font" msgstr "Teckensnitt för användargränssnitt" -#: gitk:11500 +#: gitk:11715 msgid "Gitk preferences" msgstr "Inställningar för Gitk" -#: gitk:11509 +#: gitk:11724 msgid "General" msgstr "Allmänt" -#: gitk:11510 +#: gitk:11725 msgid "Colors" msgstr "Färger" -#: gitk:11511 +#: gitk:11726 msgid "Fonts" msgstr "Teckensnitt" -#: gitk:11561 +#: gitk:11776 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: välj färg för %s" -#: gitk:12074 +#: gitk:12289 msgid "" "Sorry, gitk cannot run with this version of Tcl/Tk.\n" " Gitk requires at least Tcl/Tk 8.4." @@ -1369,45 +1419,15 @@ msgstr "" "Gitk kan tyvärr inte köra med denna version av Tcl/Tk.\n" " Gitk kräver åtminstone Tcl/Tk 8.4." -#: gitk:12284 +#: gitk:12507 msgid "Cannot find a git repository here." msgstr "Hittar inget git-arkiv här." -#: gitk:12331 +#: gitk:12554 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" -msgstr "Tvetydigt argument \"%s\": både revision och filnamn" +msgstr "Tvetydigt argument ”%s”: både revision och filnamn" -#: gitk:12343 +#: gitk:12566 msgid "Bad arguments to gitk:" msgstr "Felaktiga argument till gitk:" - -#~ msgid "mc" -#~ msgstr "mc" - -#~ msgid "next" -#~ msgstr "nästa" - -#~ msgid "prev" -#~ msgstr "föreg" - -#~ msgid "CDate" -#~ msgstr "Skapat datum" - -#~ msgid "Cannot find the git directory \"%s\"." -#~ msgstr "Hittar inte git-katalogen \"%s\"." - -#~ msgid "SHA1 ID: " -#~ msgstr "SHA1-id: " - -#~ msgid "- stopping\n" -#~ msgstr "- stannar\n" - -#~ msgid "Tag/Head %s is not known" -#~ msgstr "Tagg/huvud %s är okänt" - -#~ msgid "/\t\tMove to next find hit, or redo find" -#~ msgstr "/\t\tGå till nästa sökträff, eller sök på nytt" - -#~ msgid "Name" -#~ msgstr "Namn" diff --git a/gitweb/GITWEB-BUILD-OPTIONS.in b/gitweb/GITWEB-BUILD-OPTIONS.in new file mode 100644 index 00000000000000..41ac20654c4f79 --- /dev/null +++ b/gitweb/GITWEB-BUILD-OPTIONS.in @@ -0,0 +1,24 @@ +PERL_PATH=@PERL_PATH@ +JSMIN=@JSMIN@ +CSSMIN=@CSSMIN@ +GIT_BINDIR=@GIT_BINDIR@ +GITWEB_CONFIG=@GITWEB_CONFIG@ +GITWEB_CONFIG_SYSTEM=@GITWEB_CONFIG_SYSTEM@ +GITWEB_CONFIG_COMMON=@GITWEB_CONFIG_COMMON@ +GITWEB_HOME_LINK_STR=@GITWEB_HOME_LINK_STR@ +GITWEB_SITENAME=@GITWEB_SITENAME@ +GITWEB_PROJECTROOT=@GITWEB_PROJECTROOT@ +GITWEB_PROJECT_MAXDEPTH=@GITWEB_PROJECT_MAXDEPTH@ +GITWEB_EXPORT_OK=@GITWEB_EXPORT_OK@ +GITWEB_STRICT_EXPORT=@GITWEB_STRICT_EXPORT@ +GITWEB_BASE_URL=@GITWEB_BASE_URL@ +GITWEB_LIST=@GITWEB_LIST@ +GITWEB_HOMETEXT=@GITWEB_HOMETEXT@ +GITWEB_CSS=@GITWEB_CSS@ +GITWEB_LOGO=@GITWEB_LOGO@ +GITWEB_FAVICON=@GITWEB_FAVICON@ +GITWEB_JS=@GITWEB_JS@ +GITWEB_SITE_HTML_HEAD_STRING=@GITWEB_SITE_HTML_HEAD_STRING@ +GITWEB_SITE_HEADER=@GITWEB_SITE_HEADER@ +GITWEB_SITE_FOOTER=@GITWEB_SITE_FOOTER@ +HIGHLIGHT_BIN=@HIGHLIGHT_BIN@ diff --git a/gitweb/Makefile b/gitweb/Makefile index 3b68ab2d672c4a..d5748e93594eb6 100644 --- a/gitweb/Makefile +++ b/gitweb/Makefile @@ -77,48 +77,48 @@ GITWEB_JSLIB_FILES += static/js/javascript-detection.js GITWEB_JSLIB_FILES += static/js/adjust-timezone.js GITWEB_JSLIB_FILES += static/js/blame_incremental.js - -GITWEB_REPLACE = \ - -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \ - -e 's|++GIT_BINDIR++|$(bindir)|g' \ - -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \ - -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \ - -e 's|++GITWEB_CONFIG_COMMON++|$(GITWEB_CONFIG_COMMON)|g' \ - -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \ - -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \ - -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \ - -e 's|"++GITWEB_PROJECT_MAXDEPTH++"|$(GITWEB_PROJECT_MAXDEPTH)|g' \ - -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \ - -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \ - -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \ - -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \ - -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \ - -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \ - -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \ - -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \ - -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \ - -e 's|++GITWEB_SITE_HTML_HEAD_STRING++|$(GITWEB_SITE_HTML_HEAD_STRING)|g' \ - -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \ - -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \ - -e 's|++HIGHLIGHT_BIN++|$(HIGHLIGHT_BIN)|g' - .PHONY: FORCE $(MAK_DIR_GITWEB)GITWEB-BUILD-OPTIONS: FORCE - @rm -f $@+ - @echo "x" '$(PERL_PATH_SQ)' $(GITWEB_REPLACE) "$(JSMIN)|$(CSSMIN)" >$@+ + @sed -e 's|@PERL_PATH@|$(PERL_PATH_SQ)|' \ + -e 's|@JSMIN@|$(JSMIN)|' \ + -e 's|@CSSMIN@|$(CSSMIN)|' \ + -e 's|@GIT_VERSION@|$(GIT_VERSION)|' \ + -e 's|@GIT_BINDIR@|$(bindir)|' \ + -e 's|@GITWEB_CONFIG@|$(GITWEB_CONFIG)|' \ + -e 's|@GITWEB_CONFIG_SYSTEM@|$(GITWEB_CONFIG_SYSTEM)|' \ + -e 's|@GITWEB_CONFIG_COMMON@|$(GITWEB_CONFIG_COMMON)|' \ + -e 's|@GITWEB_HOME_LINK_STR@|$(GITWEB_HOME_LINK_STR)|' \ + -e 's|@GITWEB_SITENAME@|$(GITWEB_SITENAME)|' \ + -e 's|@GITWEB_PROJECTROOT@|$(GITWEB_PROJECTROOT)|' \ + -e 's|@GITWEB_PROJECT_MAXDEPTH@|$(GITWEB_PROJECT_MAXDEPTH)|' \ + -e 's|@GITWEB_EXPORT_OK@|$(GITWEB_EXPORT_OK)|' \ + -e 's|@GITWEB_STRICT_EXPORT@|$(GITWEB_STRICT_EXPORT)|' \ + -e 's|@GITWEB_BASE_URL@|$(GITWEB_BASE_URL)|' \ + -e 's|@GITWEB_LIST@|$(GITWEB_LIST)|' \ + -e 's|@GITWEB_HOMETEXT@|$(GITWEB_HOMETEXT)|' \ + -e 's|@GITWEB_CSS@|$(GITWEB_CSS)|' \ + -e 's|@GITWEB_LOGO@|$(GITWEB_LOGO)|' \ + -e 's|@GITWEB_FAVICON@|$(GITWEB_FAVICON)|' \ + -e 's|@GITWEB_JS@|$(GITWEB_JS)|' \ + -e 's|@GITWEB_SITE_HTML_HEAD_STRING@|$(GITWEB_SITE_HTML_HEAD_STRING)|' \ + -e 's|@GITWEB_SITE_HEADER@|$(GITWEB_SITE_HEADER)|' \ + -e 's|@GITWEB_SITE_FOOTER@|$(GITWEB_SITE_FOOTER)|' \ + -e 's|@HIGHLIGHT_BIN@|$(HIGHLIGHT_BIN)|' \ + $(MAK_DIR_GITWEB)GITWEB-BUILD-OPTIONS.in >"$@+" @cmp -s $@+ $@ && rm -f $@+ || mv -f $@+ $@ +$(MAK_DIR_GITWEB)gitweb.cgi: $(MAK_DIR_GITWEB)generate-gitweb-cgi.sh $(MAK_DIR_GITWEB)gitweb.cgi: $(MAK_DIR_GITWEB)GITWEB-BUILD-OPTIONS +$(MAK_DIR_GITWEB)gitweb.cgi: GIT-VERSION-FILE $(MAK_DIR_GITWEB)gitweb.cgi: $(MAK_DIR_GITWEB)gitweb.perl $(QUIET_GEN)$(RM) $@ $@+ && \ - sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ - $(GITWEB_REPLACE) $< >$@+ && \ - chmod +x $@+ && \ + $(MAK_DIR_GITWEB)generate-gitweb-cgi.sh $(MAK_DIR_GITWEB)/GITWEB-BUILD-OPTIONS ./GIT-VERSION-FILE $< $@+ && \ mv $@+ $@ +$(MAK_DIR_GITWEB)static/gitweb.js: $(MAK_DIR_GITWEB)generate-gitweb-js.sh $(MAK_DIR_GITWEB)static/gitweb.js: $(addprefix $(MAK_DIR_GITWEB),$(GITWEB_JSLIB_FILES)) $(QUIET_GEN)$(RM) $@ $@+ && \ - cat $^ >$@+ && \ + $(MAK_DIR_GITWEB)generate-gitweb-js.sh $@+ $^ && \ mv $@+ $@ ### Installation rules diff --git a/gitweb/generate-gitweb-cgi.sh b/gitweb/generate-gitweb-cgi.sh new file mode 100755 index 00000000000000..ede9038c3352d2 --- /dev/null +++ b/gitweb/generate-gitweb-cgi.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +set -e + +if test $# -ne 4 +then + echo >&2 "USAGE: $0 <GITWEB-BUILD-OPTIONS> <GIT-VERSION-FILE> <INPUT> <OUTPUT>" + exit 1 +fi + +GITWEB_BUILD_OPTIONS="$1" +GIT_VERSION_FILE="$2" +INPUT="$3" +OUTPUT="$4" + +. "$GITWEB_BUILD_OPTIONS" +. "$GIT_VERSION_FILE" + +sed -e "1s|#!/usr/bin/perl|#!$PERL_PATH|" \ + -e "s|@PERL_PATH@|$PERL_PATH|" \ + -e "s|@JSMIN@|$JSMIN|" \ + -e "s|@CSSMIN@|$CSSMIN|" \ + -e "s|@GIT_VERSION@|$GIT_VERSION|" \ + -e "s|@GIT_BINDIR@|$GIT_BINDIR|" \ + -e "s|@GITWEB_CONFIG@|$GITWEB_CONFIG|" \ + -e "s|@GITWEB_CONFIG_SYSTEM@|$GITWEB_CONFIG_SYSTEM|" \ + -e "s|@GITWEB_CONFIG_COMMON@|$GITWEB_CONFIG_COMMON|" \ + -e "s|@GITWEB_HOME_LINK_STR@|$GITWEB_HOME_LINK_STR|" \ + -e "s|@GITWEB_SITENAME@|$GITWEB_SITENAME|" \ + -e "s|@GITWEB_PROJECTROOT@|$GITWEB_PROJECTROOT|" \ + -e "s|@GITWEB_PROJECT_MAXDEPTH@|$GITWEB_PROJECT_MAXDEPTH|" \ + -e "s|@GITWEB_EXPORT_OK@|$GITWEB_EXPORT_OK|" \ + -e "s|@GITWEB_STRICT_EXPORT@|$GITWEB_STRICT_EXPORT|" \ + -e "s|@GITWEB_BASE_URL@|$GITWEB_BASE_URL|" \ + -e "s|@GITWEB_LIST@|$GITWEB_LIST|" \ + -e "s|@GITWEB_HOMETEXT@|$GITWEB_HOMETEXT|" \ + -e "s|@GITWEB_CSS@|$GITWEB_CSS|" \ + -e "s|@GITWEB_LOGO@|$GITWEB_LOGO|" \ + -e "s|@GITWEB_FAVICON@|$GITWEB_FAVICON|" \ + -e "s|@GITWEB_JS@|$GITWEB_JS|" \ + -e "s|@GITWEB_SITE_HTML_HEAD_STRING@|$GITWEB_SITE_HTML_HEAD_STRING|" \ + -e "s|@GITWEB_SITE_HEADER@|$GITWEB_SITE_HEADER|" \ + -e "s|@GITWEB_SITE_FOOTER@|$GITWEB_SITE_FOOTER|" \ + -e "s|@HIGHLIGHT_BIN@|$HIGHLIGHT_BIN|" \ + "$INPUT" >"$OUTPUT" + +chmod a+x "$OUTPUT" diff --git a/gitweb/generate-gitweb-js.sh b/gitweb/generate-gitweb-js.sh new file mode 100755 index 00000000000000..01bb22b04b8d89 --- /dev/null +++ b/gitweb/generate-gitweb-js.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +if test "$#" -lt 2 +then + echo >&2 "USAGE: $0 <OUTPUT> <INPUT>..." + exit 1 +fi + +OUTPUT="$1" +shift + +cat "$@" >"$OUTPUT" diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index b09a8d052383fd..b5490dfecf2da7 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -7,7 +7,7 @@ # # This program is licensed under the GPLv2 -use 5.008001; +require v5.26; use strict; use warnings; # handle ACL in file access tests @@ -35,7 +35,7 @@ BEGIN CGI->compile() if $ENV{'MOD_PERL'}; } -our $version = "++GIT_VERSION++"; +our $version = "@GIT_VERSION@"; our ($my_url, $my_uri, $base_url, $path_info, $home_link); sub evaluate_uri { @@ -80,46 +80,46 @@ sub evaluate_uri { # core git executable to use # this can just be "git" if your webserver has a sensible PATH -our $GIT = "++GIT_BINDIR++/git"; +our $GIT = "@GIT_BINDIR@/git"; # absolute fs-path which will be prepended to the project path #our $projectroot = "/pub/scm"; -our $projectroot = "++GITWEB_PROJECTROOT++"; +our $projectroot = "@GITWEB_PROJECTROOT@"; # fs traversing limit for getting project list # the number is relative to the projectroot -our $project_maxdepth = "++GITWEB_PROJECT_MAXDEPTH++"; +our $project_maxdepth = @GITWEB_PROJECT_MAXDEPTH@; # string of the home link on top of all pages -our $home_link_str = "++GITWEB_HOME_LINK_STR++"; +our $home_link_str = "@GITWEB_HOME_LINK_STR@"; # extra breadcrumbs preceding the home link our @extra_breadcrumbs = (); # name of your site or organization to appear in page titles # replace this with something more descriptive for clearer bookmarks -our $site_name = "++GITWEB_SITENAME++" +our $site_name = "@GITWEB_SITENAME@" || ($ENV{'SERVER_NAME'} || "Untitled") . " Git"; # html snippet to include in the <head> section of each page -our $site_html_head_string = "++GITWEB_SITE_HTML_HEAD_STRING++"; +our $site_html_head_string = "@GITWEB_SITE_HTML_HEAD_STRING@"; # filename of html text to include at top of each page -our $site_header = "++GITWEB_SITE_HEADER++"; +our $site_header = "@GITWEB_SITE_HEADER@"; # html text to include at home page -our $home_text = "++GITWEB_HOMETEXT++"; +our $home_text = "@GITWEB_HOMETEXT@"; # filename of html text to include at bottom of each page -our $site_footer = "++GITWEB_SITE_FOOTER++"; +our $site_footer = "@GITWEB_SITE_FOOTER@"; # URI of stylesheets -our @stylesheets = ("++GITWEB_CSS++"); +our @stylesheets = ("@GITWEB_CSS@"); # URI of a single stylesheet, which can be overridden in GITWEB_CONFIG. our $stylesheet = undef; # URI of GIT logo (72x27 size) -our $logo = "++GITWEB_LOGO++"; +our $logo = "@GITWEB_LOGO@"; # URI of GIT favicon, assumed to be image/png type -our $favicon = "++GITWEB_FAVICON++"; +our $favicon = "@GITWEB_FAVICON@"; # URI of gitweb.js (JavaScript code for gitweb) -our $javascript = "++GITWEB_JS++"; +our $javascript = "@GITWEB_JS@"; # URI and label (title) of GIT logo link #our $logo_url = "https://www.kernel.org/pub/software/scm/git/docs/"; @@ -128,7 +128,7 @@ sub evaluate_uri { our $logo_label = "git homepage"; # source of projects list -our $projects_list = "++GITWEB_LIST++"; +our $projects_list = "@GITWEB_LIST@"; # the width (in characters) of the projects list "Description" column our $projects_list_description_width = 25; @@ -147,7 +147,7 @@ sub evaluate_uri { # show repository only if this file exists # (only effective if this variable evaluates to true) -our $export_ok = "++GITWEB_EXPORT_OK++"; +our $export_ok = "@GITWEB_EXPORT_OK@"; # don't generate age column on the projects list page our $omit_age_column = 0; @@ -161,11 +161,11 @@ sub evaluate_uri { our $export_auth_hook = undef; # only allow viewing of repositories also shown on the overview page -our $strict_export = "++GITWEB_STRICT_EXPORT++"; +our $strict_export = "@GITWEB_STRICT_EXPORT@"; # list of git base URLs used for URL to where fetch project from, # i.e. full URL is "$git_base_url/$project" -our @git_base_url_list = grep { $_ ne '' } ("++GITWEB_BASE_URL++"); +our @git_base_url_list = grep { $_ ne '' } ("@GITWEB_BASE_URL@"); # default blob_plain mimetype and default charset for text/plain blob our $default_blob_plain_mimetype = 'text/plain'; @@ -200,7 +200,7 @@ sub evaluate_uri { # 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++"; +our $highlight_bin = "@HIGHLIGHT_BIN@"; # information about snapshot formats that gitweb is capable of serving our %known_snapshot_formats = ( @@ -741,9 +741,9 @@ sub read_config_file { our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM, $GITWEB_CONFIG_COMMON); sub evaluate_gitweb_config { - our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++"; - our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++"; - our $GITWEB_CONFIG_COMMON = $ENV{'GITWEB_CONFIG_COMMON'} || "++GITWEB_CONFIG_COMMON++"; + our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "@GITWEB_CONFIG@"; + our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "@GITWEB_CONFIG_SYSTEM@"; + our $GITWEB_CONFIG_COMMON = $ENV{'GITWEB_CONFIG_COMMON'} || "@GITWEB_CONFIG_COMMON@"; # Protect against duplications of file names, to not read config twice. # Only one of $GITWEB_CONFIG and $GITWEB_CONFIG_SYSTEM is used, so @@ -1188,7 +1188,7 @@ sub evaluate_and_validate_params { if ($search_use_regexp) { $search_regexp = $searchtext; if (!eval { qr/$search_regexp/; 1; }) { - (my $error = $@) =~ s/ at \S+ line \d+.*\n?//; + my $error = $@ =~ s/ at \S+ line \d+.*\n?//r; die_error(400, "Invalid search regexp '$search_regexp'", esc_html($error)); } @@ -2094,7 +2094,7 @@ sub format_log_line_html { ( # The output of "git describe", e.g. v2.10.0-297-gf6727b0 # or hadoop-20160921-113441-20-g094fb7d - (?<!-) # see strbuf_check_tag_ref(). Tags can't start with - + (?<!-) # see check_tag_ref(). Tags can't start with - [A-Za-z0-9.-]+ (?!\.) # refs can't end with ".", see check_refname_format() -g$regex @@ -2700,7 +2700,7 @@ sub git_cmd { # Try to avoid using this function wherever possible. sub quote_command { return join(' ', - map { my $a = $_; $a =~ s/(['!])/'\\$1'/g; "'$a'" } @_ ); + map { my $a = $_ =~ s/(['!])/'\\$1'/gr; "'$a'" } @_ ); } # get HEAD ref of given project as hash diff --git a/gitweb/meson.build b/gitweb/meson.build new file mode 100644 index 00000000000000..89b403dc9de768 --- /dev/null +++ b/gitweb/meson.build @@ -0,0 +1,89 @@ +gitweb_config = configuration_data() +gitweb_config.set_quoted('PERL_PATH', perl.full_path()) +gitweb_config.set_quoted('CSSMIN', '') +gitweb_config.set_quoted('JSMIN', '') +gitweb_config.set_quoted('GIT_BINDIR', get_option('prefix') / get_option('bindir')) +gitweb_config.set_quoted('GITWEB_CONFIG', get_option('gitweb_config')) +gitweb_config.set_quoted('GITWEB_CONFIG_SYSTEM', get_option('gitweb_config_system')) +gitweb_config.set_quoted('GITWEB_CONFIG_COMMON', get_option('gitweb_config_common')) +gitweb_config.set_quoted('GITWEB_HOME_LINK_STR', get_option('gitweb_home_link_str')) +gitweb_config.set_quoted('GITWEB_SITENAME', get_option('gitweb_sitename')) +gitweb_config.set_quoted('GITWEB_PROJECTROOT', get_option('gitweb_projectroot')) +gitweb_config.set_quoted('GITWEB_PROJECT_MAXDEPTH', get_option('gitweb_project_maxdepth')) +gitweb_config.set_quoted('GITWEB_EXPORT_OK', get_option('gitweb_export_ok')) +gitweb_config.set_quoted('GITWEB_STRICT_EXPORT', get_option('gitweb_strict_export')) +gitweb_config.set_quoted('GITWEB_BASE_URL', get_option('gitweb_base_url')) +gitweb_config.set_quoted('GITWEB_LIST', get_option('gitweb_list')) +gitweb_config.set_quoted('GITWEB_HOMETEXT', get_option('gitweb_hometext')) +gitweb_config.set_quoted('GITWEB_CSS', get_option('gitweb_css')) +gitweb_config.set_quoted('GITWEB_LOGO', get_option('gitweb_logo')) +gitweb_config.set_quoted('GITWEB_FAVICON', get_option('gitweb_favicon')) +gitweb_config.set_quoted('GITWEB_JS', get_option('gitweb_js')) +gitweb_config.set_quoted('GITWEB_SITE_HTML_HEAD_STRING', get_option('gitweb_site_html_head_string')) +gitweb_config.set_quoted('GITWEB_SITE_HEADER', get_option('gitweb_site_header')) +gitweb_config.set_quoted('GITWEB_SITE_FOOTER', get_option('gitweb_site_footer')) +gitweb_config.set_quoted('HIGHLIGHT_BIN', get_option('highlight_bin')) + +configure_file( + input: 'GITWEB-BUILD-OPTIONS.in', + output: 'GITWEB-BUILD-OPTIONS', + configuration: gitweb_config, +) + +test_dependencies += custom_target( + input: 'gitweb.perl', + output: 'gitweb.cgi', + command: [ + shell, + meson.current_source_dir() / 'generate-gitweb-cgi.sh', + meson.current_build_dir() / 'GITWEB-BUILD-OPTIONS', + git_version_file.full_path(), + '@INPUT@', + '@OUTPUT@', + ], + install: true, + install_dir: get_option('datadir') / 'gitweb', + depends: [git_version_file], +) + +javascript_files = [ + meson.current_source_dir() / 'static/js/adjust-timezone.js', + meson.current_source_dir() / 'static/js/blame_incremental.js', + meson.current_source_dir() / 'static/js/javascript-detection.js', + meson.current_source_dir() / 'static/js/lib/common-lib.js', + meson.current_source_dir() / 'static/js/lib/cookies.js', + meson.current_source_dir() / 'static/js/lib/datetime.js', +] + +test_dependencies += custom_target( + input: javascript_files, + output: 'gitweb.js', + command: [ + shell, + meson.current_source_dir() / 'generate-gitweb-js.sh', + '@OUTPUT@', + ] + javascript_files, + install: true, + install_dir: get_option('datadir') / 'gitweb/static', +) + +foreach asset : [ + 'static/git-favicon.png', + 'static/git-logo.png', + 'static/gitweb.css', +] + if meson.version().version_compare('>=1.3.0') + fs.copyfile(asset, + install: true, + install_dir: get_option('datadir') / 'gitweb' / fs.parent(asset), + ) + else + configure_file( + input: asset, + output: fs.stem(asset), + copy: true, + install: true, + install_dir: get_option('datadir') / 'gitweb' / fs.parent(asset), + ) + endif +endforeach diff --git a/gpg-interface.c b/gpg-interface.c index 07335987a6b9ce..0896458de5a988 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -127,9 +127,7 @@ static struct gpg_format *use_format = &gpg_format[0]; static struct gpg_format *get_format_by_name(const char *str) { - int i; - - for (i = 0; i < ARRAY_SIZE(gpg_format); i++) + for (size_t i = 0; i < ARRAY_SIZE(gpg_format); i++) if (!strcmp(gpg_format[i].name, str)) return gpg_format + i; return NULL; @@ -137,9 +135,9 @@ static struct gpg_format *get_format_by_name(const char *str) static struct gpg_format *get_format_by_sig(const char *sig) { - int i, j; + int j; - for (i = 0; i < ARRAY_SIZE(gpg_format); i++) + for (size_t i = 0; i < ARRAY_SIZE(gpg_format); i++) for (j = 0; gpg_format[i].sigs[j]; j++) if (starts_with(sig, gpg_format[i].sigs[j])) return gpg_format + i; @@ -227,7 +225,7 @@ static void parse_gpg_output(struct signature_check *sigc) { const char *buf = sigc->gpg_status; const char *line, *next; - int i, j; + int j; int seen_exclusive_status = 0; /* Iterate over all lines */ @@ -242,7 +240,7 @@ static void parse_gpg_output(struct signature_check *sigc) continue; /* Iterate over all search strings */ - for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) { + for (size_t i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) { if (skip_prefix(line, sigcheck_gpg_status[i].check, &line)) { /* * GOODSIG, BADSIG etc. can occur only once for @@ -699,7 +697,7 @@ size_t parse_signed_buffer(const char *buf, size_t size) match = len; eol = memchr(buf + len, '\n', size - len); - len += eol ? eol - (buf + len) + 1 : size - len; + len += eol ? (size_t) (eol - (buf + len) + 1) : size - len; } return match; } diff --git a/graph.c b/graph.c index 091c14cf4fbcf5..26f6fbf000aef5 100644 --- a/graph.c +++ b/graph.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" @@ -76,10 +76,7 @@ static void graph_show_line_prefix(const struct diff_options *diffopt) if (!diffopt || !diffopt->line_prefix) return; - fwrite(diffopt->line_prefix, - sizeof(char), - diffopt->line_prefix_length, - diffopt->file); + fputs(diffopt->line_prefix, diffopt->file); } static const char **column_colors; @@ -312,22 +309,28 @@ struct git_graph { * stored as an index into the array column_colors. */ unsigned short default_column_color; + + /* + * Scratch buffer for generating prefixes to be used with + * diff_output_prefix_callback(). + */ + struct strbuf prefix_buf; }; -static struct strbuf *diff_output_prefix_callback(struct diff_options *opt, void *data) +static const char *diff_output_prefix_callback(struct diff_options *opt, void *data) { struct git_graph *graph = data; - static struct strbuf msgbuf = STRBUF_INIT; assert(opt); - strbuf_reset(&msgbuf); + if (!graph) + return opt->line_prefix; + + strbuf_reset(&graph->prefix_buf); if (opt->line_prefix) - strbuf_add(&msgbuf, opt->line_prefix, - opt->line_prefix_length); - if (graph) - graph_padding_line(graph, &msgbuf); - return &msgbuf; + strbuf_addstr(&graph->prefix_buf, opt->line_prefix); + graph_padding_line(graph, &graph->prefix_buf); + return graph->prefix_buf.buf; } static const struct diff_options *default_diffopt; @@ -347,7 +350,7 @@ struct git_graph *graph_init(struct rev_info *opt) if (!column_colors) { char *string; - if (git_config_get_string("log.graphcolors", &string)) { + if (repo_config_get_string(opt->repo, "log.graphcolors", &string)) { /* not configured -- use default */ graph_set_column_colors(column_colors_ansi, column_colors_ansi_max); @@ -397,6 +400,7 @@ struct git_graph *graph_init(struct rev_info *opt) * The diff output prefix callback, with this we can make * all the diff output to align with the graph lines. */ + strbuf_init(&graph->prefix_buf, 0); opt->diffopt.output_prefix = diff_output_prefix_callback; opt->diffopt.output_prefix_data = graph; @@ -412,6 +416,7 @@ void graph_clear(struct git_graph *graph) free(graph->new_columns); free(graph->mapping); free(graph->old_mapping); + strbuf_release(&graph->prefix_buf); free(graph); } diff --git a/grep.c b/grep.c index e5761426e4f0f3..4e155ee9e66367 100644 --- a/grep.c +++ b/grep.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "gettext.h" @@ -756,6 +758,7 @@ static struct grep_expr *grep_splice_or(struct grep_expr *x, struct grep_expr *y assert(x->node == GREP_NODE_OR); if (x->u.binary.right && x->u.binary.right->node == GREP_NODE_TRUE) { + free(x->u.binary.right); x->u.binary.right = y; break; } @@ -843,11 +846,11 @@ static void free_grep_pat(struct grep_pat *pattern) free_pcre2_pattern(p); else regfree(&p->regexp); - free(p->pattern); break; default: break; } + free(p->pattern); free(p); } } @@ -906,15 +909,17 @@ static int patmatch(struct grep_pat *p, const char *line, const char *eol, regmatch_t *match, int eflags) { - int hit; - if (p->pcre2_pattern) - hit = !pcre2match(p, line, eol, match, eflags); - else - hit = !regexec_buf(&p->regexp, line, eol - line, 1, match, - eflags); + return !pcre2match(p, line, eol, match, eflags); - return hit; + switch (regexec_buf(&p->regexp, line, eol - line, 1, match, eflags)) { + case 0: + return 1; + case REG_NOMATCH: + return 0; + default: + return -1; + } } static void strip_timestamp(const char *bol, const char **eol_p) @@ -952,6 +957,8 @@ static int headerless_match_one_pattern(struct grep_pat *p, again: hit = patmatch(p, bol, eol, pmatch, eflags); + if (hit < 0) + hit = 0; if (hit && p->word_regexp) { if ((pmatch[0].rm_so < 0) || @@ -1461,6 +1468,8 @@ static int look_ahead(struct grep_opt *opt, regmatch_t m; hit = patmatch(p, bol, bol + *left_p, &m, 0); + if (hit < 0) + return -1; if (!hit || m.rm_so < 0 || m.rm_eo < 0) continue; if (earliest < 0 || m.rm_so < earliest) @@ -1655,9 +1664,13 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle if (try_lookahead && !(last_hit && (show_function || - lno <= last_hit + opt->post_context)) - && look_ahead(opt, &left, &lno, &bol)) - break; + lno <= last_hit + opt->post_context))) { + hit = look_ahead(opt, &left, &lno, &bol); + if (hit < 0) + try_lookahead = 0; + else if (hit) + break; + } eol = end_of_line(bol, &left); if ((ctx == GREP_CONTEXT_HEAD) && (eol == bol)) diff --git a/hash.h b/hash.h index 72ffbc862e557a..4367acfec5098a 100644 --- a/hash.h +++ b/hash.h @@ -15,6 +15,36 @@ #include "block-sha1/sha1.h" #endif +#if defined(SHA1_APPLE_UNSAFE) +# include <CommonCrypto/CommonDigest.h> +# define platform_SHA_CTX_unsafe CC_SHA1_CTX +# define platform_SHA1_Init_unsafe CC_SHA1_Init +# define platform_SHA1_Update_unsafe CC_SHA1_Update +# define platform_SHA1_Final_unsafe CC_SHA1_Final +#elif defined(SHA1_OPENSSL_UNSAFE) +# include <openssl/sha.h> +# if defined(OPENSSL_API_LEVEL) && OPENSSL_API_LEVEL >= 3 +# define SHA1_NEEDS_CLONE_HELPER_UNSAFE +# include "sha1/openssl.h" +# define platform_SHA_CTX_unsafe openssl_SHA1_CTX +# define platform_SHA1_Init_unsafe openssl_SHA1_Init +# define platform_SHA1_Clone_unsafe openssl_SHA1_Clone +# define platform_SHA1_Update_unsafe openssl_SHA1_Update +# define platform_SHA1_Final_unsafe openssl_SHA1_Final +# else +# define platform_SHA_CTX_unsafe SHA_CTX +# define platform_SHA1_Init_unsafe SHA1_Init +# define platform_SHA1_Update_unsafe SHA1_Update +# define platform_SHA1_Final_unsafe SHA1_Final +# endif +#elif defined(SHA1_BLK_UNSAFE) +# include "block-sha1/sha1.h" +# define platform_SHA_CTX_unsafe blk_SHA_CTX +# define platform_SHA1_Init_unsafe blk_SHA1_Init +# define platform_SHA1_Update_unsafe blk_SHA1_Update +# define platform_SHA1_Final_unsafe blk_SHA1_Final +#endif + #if defined(SHA256_NETTLE) #include "sha256/nettle.h" #elif defined(SHA256_GCRYPT) @@ -44,14 +74,35 @@ #define platform_SHA1_Final SHA1_Final #endif +#ifndef platform_SHA_CTX_unsafe +# define platform_SHA_CTX_unsafe platform_SHA_CTX +# define platform_SHA1_Init_unsafe platform_SHA1_Init +# define platform_SHA1_Update_unsafe platform_SHA1_Update +# define platform_SHA1_Final_unsafe platform_SHA1_Final +# ifdef platform_SHA1_Clone +# define platform_SHA1_Clone_unsafe platform_SHA1_Clone +# endif +# ifdef SHA1_NEEDS_CLONE_HELPER +# define SHA1_NEEDS_CLONE_HELPER_UNSAFE +# endif +#endif + #define git_SHA_CTX platform_SHA_CTX #define git_SHA1_Init platform_SHA1_Init #define git_SHA1_Update platform_SHA1_Update #define git_SHA1_Final platform_SHA1_Final +#define git_SHA_CTX_unsafe platform_SHA_CTX_unsafe +#define git_SHA1_Init_unsafe platform_SHA1_Init_unsafe +#define git_SHA1_Update_unsafe platform_SHA1_Update_unsafe +#define git_SHA1_Final_unsafe platform_SHA1_Final_unsafe + #ifdef platform_SHA1_Clone #define git_SHA1_Clone platform_SHA1_Clone #endif +#ifdef platform_SHA1_Clone_unsafe +# define git_SHA1_Clone_unsafe platform_SHA1_Clone_unsafe +#endif #ifndef platform_SHA256_CTX #define platform_SHA256_CTX SHA256_CTX @@ -81,6 +132,13 @@ static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src) memcpy(dst, src, sizeof(*dst)); } #endif +#ifndef SHA1_NEEDS_CLONE_HELPER_UNSAFE +static inline void git_SHA1_Clone_unsafe(git_SHA_CTX_unsafe *dst, + const git_SHA_CTX_unsafe *src) +{ + memcpy(dst, src, sizeof(*dst)); +} +#endif #ifndef SHA256_NEEDS_CLONE_HELPER static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src) @@ -176,17 +234,20 @@ enum get_oid_result { #endif /* A suitably aligned type for stack allocations of hash contexts. */ -union git_hash_ctx { - git_SHA_CTX sha1; - git_SHA256_CTX sha256; +struct git_hash_ctx { + const struct git_hash_algo *algop; + union { + git_SHA_CTX sha1; + git_SHA_CTX_unsafe sha1_unsafe; + git_SHA256_CTX sha256; + } state; }; -typedef union git_hash_ctx git_hash_ctx; -typedef void (*git_hash_init_fn)(git_hash_ctx *ctx); -typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src); -typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len); -typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx); -typedef void (*git_hash_final_oid_fn)(struct object_id *oid, git_hash_ctx *ctx); +typedef void (*git_hash_init_fn)(struct git_hash_ctx *ctx); +typedef void (*git_hash_clone_fn)(struct git_hash_ctx *dst, const struct git_hash_ctx *src); +typedef void (*git_hash_update_fn)(struct git_hash_ctx *ctx, const void *in, size_t len); +typedef void (*git_hash_final_fn)(unsigned char *hash, struct git_hash_ctx *ctx); +typedef void (*git_hash_final_oid_fn)(struct object_id *oid, struct git_hash_ctx *ctx); struct git_hash_algo { /* @@ -230,9 +291,32 @@ struct git_hash_algo { /* The all-zeros OID. */ const struct object_id *null_oid; + + /* The unsafe variant of this hash function, if one exists. */ + const struct git_hash_algo *unsafe; }; extern const struct git_hash_algo hash_algos[GIT_HASH_NALGOS]; +static inline void git_hash_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src) +{ + src->algop->clone_fn(dst, src); +} + +static inline void git_hash_update(struct git_hash_ctx *ctx, const void *in, size_t len) +{ + ctx->algop->update_fn(ctx, in, len); +} + +static inline void git_hash_final(unsigned char *hash, struct git_hash_ctx *ctx) +{ + ctx->algop->final_fn(hash, ctx); +} + +static inline void git_hash_final_oid(struct object_id *oid, struct git_hash_ctx *ctx) +{ + ctx->algop->final_oid_fn(oid, ctx); +} + /* * Return a GIT_HASH_* constant based on the name. Returns GIT_HASH_UNKNOWN if * the name doesn't match a known algorithm. @@ -245,9 +329,17 @@ int hash_algo_by_length(int len); /* Identical, except for a pointer to struct git_hash_algo. */ static inline int hash_algo_by_ptr(const struct git_hash_algo *p) { - return p - hash_algos; + size_t i; + for (i = 0; i < GIT_HASH_NALGOS; i++) { + const struct git_hash_algo *algop = &hash_algos[i]; + if (p == algop) + return i; + } + return GIT_HASH_UNKNOWN; } +const struct git_hash_algo *unsafe_hash_algo(const struct git_hash_algo *algop); + const struct object_id *null_oid(void); static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop) diff --git a/help.c b/help.c index 4ad4ebdd2cfddb..c54bd9918a5be8 100644 --- a/help.c +++ b/help.c @@ -1,6 +1,8 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" +#include "git-zlib.h" #include "config.h" #include "builtin.h" #include "exec-cmd.h" @@ -546,37 +548,61 @@ int is_in_cmdlist(struct cmdnames *c, const char *s) return 0; } -static int autocorrect; -static struct cmdnames aliases; +struct help_unknown_cmd_config { + int autocorrect; + struct cmdnames aliases; +}; +#define AUTOCORRECT_SHOW (-4) #define AUTOCORRECT_PROMPT (-3) #define AUTOCORRECT_NEVER (-2) #define AUTOCORRECT_IMMEDIATELY (-1) +static int parse_autocorrect(const char *value) +{ + switch (git_parse_maybe_bool_text(value)) { + case 1: + return AUTOCORRECT_IMMEDIATELY; + case 0: + return AUTOCORRECT_SHOW; + default: /* other random text */ + break; + } + + if (!strcmp(value, "prompt")) + return AUTOCORRECT_PROMPT; + if (!strcmp(value, "never")) + return AUTOCORRECT_NEVER; + if (!strcmp(value, "immediate")) + return AUTOCORRECT_IMMEDIATELY; + if (!strcmp(value, "show")) + return AUTOCORRECT_SHOW; + + return 0; +} + static int git_unknown_cmd_config(const char *var, const char *value, const struct config_context *ctx, - void *cb UNUSED) + void *cb) { + struct help_unknown_cmd_config *cfg = cb; const char *p; if (!strcmp(var, "help.autocorrect")) { - if (!value) - return config_error_nonbool(var); - if (!strcmp(value, "never")) { - autocorrect = AUTOCORRECT_NEVER; - } else if (!strcmp(value, "immediate")) { - autocorrect = AUTOCORRECT_IMMEDIATELY; - } else if (!strcmp(value, "prompt")) { - autocorrect = AUTOCORRECT_PROMPT; - } else { - int v = git_config_int(var, value, ctx->kvi); - autocorrect = (v < 0) - ? AUTOCORRECT_IMMEDIATELY : v; + int v = parse_autocorrect(value); + + if (!v) { + v = git_config_int(var, value, ctx->kvi); + if (v < 0 || v == 1) + v = AUTOCORRECT_IMMEDIATELY; } + + cfg->autocorrect = v; } + /* Also use aliases for command lookup */ if (skip_prefix(var, "alias.", &p)) - add_cmdname(&aliases, p, strlen(p)); + add_cmdname(&cfg->aliases, p, strlen(p)); return 0; } @@ -609,32 +635,30 @@ static const char bad_interpreter_advice[] = N_("'%s' appears to be a git command, but we were not\n" "able to execute it. Maybe git-%s is broken?"); -const char *help_unknown_cmd(const char *cmd) +char *help_unknown_cmd(const char *cmd) { + struct help_unknown_cmd_config cfg = { 0 }; int i, n, best_similarity = 0; - struct cmdnames main_cmds, other_cmds; + struct cmdnames main_cmds = { 0 }; + struct cmdnames other_cmds = { 0 }; struct cmdname_help *common_cmds; - memset(&main_cmds, 0, sizeof(main_cmds)); - memset(&other_cmds, 0, sizeof(other_cmds)); - memset(&aliases, 0, sizeof(aliases)); - - read_early_config(the_repository, git_unknown_cmd_config, NULL); + read_early_config(the_repository, git_unknown_cmd_config, &cfg); /* * Disable autocorrection prompt in a non-interactive session */ - if ((autocorrect == AUTOCORRECT_PROMPT) && (!isatty(0) || !isatty(2))) - autocorrect = AUTOCORRECT_NEVER; + if ((cfg.autocorrect == AUTOCORRECT_PROMPT) && (!isatty(0) || !isatty(2))) + cfg.autocorrect = AUTOCORRECT_NEVER; - if (autocorrect == AUTOCORRECT_NEVER) { + if (cfg.autocorrect == AUTOCORRECT_NEVER) { fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd); exit(1); } load_command_list("git-", &main_cmds, &other_cmds); - add_cmd_list(&main_cmds, &aliases); + add_cmd_list(&main_cmds, &cfg.aliases); add_cmd_list(&main_cmds, &other_cmds); QSORT(main_cmds.names, main_cmds.cnt, cmdname_compare); uniq(&main_cmds); @@ -693,20 +717,20 @@ const char *help_unknown_cmd(const char *cmd) n++) ; /* still counting */ } - if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) { - const char *assumed = main_cmds.names[0]->name; - main_cmds.names[0] = NULL; - cmdnames_release(&main_cmds); + if (cfg.autocorrect && cfg.autocorrect != AUTOCORRECT_SHOW && n == 1 && + SIMILAR_ENOUGH(best_similarity)) { + char *assumed = xstrdup(main_cmds.names[0]->name); + fprintf_ln(stderr, _("WARNING: You called a Git command named '%s', " "which does not exist."), cmd); - if (autocorrect == AUTOCORRECT_IMMEDIATELY) + if (cfg.autocorrect == AUTOCORRECT_IMMEDIATELY) fprintf_ln(stderr, _("Continuing under the assumption that " "you meant '%s'."), assumed); - else if (autocorrect == AUTOCORRECT_PROMPT) { + else if (cfg.autocorrect == AUTOCORRECT_PROMPT) { char *answer; struct strbuf msg = STRBUF_INIT; strbuf_addf(&msg, _("Run '%s' instead [y/N]? "), assumed); @@ -719,9 +743,13 @@ const char *help_unknown_cmd(const char *cmd) fprintf_ln(stderr, _("Continuing in %0.1f seconds, " "assuming that you meant '%s'."), - (float)autocorrect/10.0, assumed); - sleep_millisec(autocorrect * 100); + (float)cfg.autocorrect/10.0, assumed); + sleep_millisec(cfg.autocorrect * 100); } + + cmdnames_release(&cfg.aliases); + cmdnames_release(&main_cmds); + cmdnames_release(&other_cmds); return assumed; } @@ -770,7 +798,9 @@ void get_version_info(struct strbuf *buf, int show_build_options) #if defined OPENSSL_VERSION_TEXT strbuf_addf(buf, "OpenSSL: %s\n", OPENSSL_VERSION_TEXT); #endif -#if defined ZLIB_VERSION +#if defined ZLIBNG_VERSION + strbuf_addf(buf, "zlib-ng: %s\n", ZLIBNG_VERSION); +#elif defined ZLIB_VERSION strbuf_addf(buf, "zlib: %s\n", ZLIB_VERSION); #endif } diff --git a/help.h b/help.h index e716ee27ea174c..c54bf0977dac4d 100644 --- a/help.h +++ b/help.h @@ -32,7 +32,7 @@ void list_all_other_cmds(struct string_list *list); void list_cmds_by_category(struct string_list *list, const char *category); void list_cmds_by_config(struct string_list *list); -const char *help_unknown_cmd(const char *cmd); +char *help_unknown_cmd(const char *cmd); void load_command_list(const char *prefix, struct cmdnames *main_cmds, struct cmdnames *other_cmds); @@ -60,8 +60,7 @@ static inline void list_config_item(struct string_list *list, #define define_list_config_array(array) \ void list_config_##array(struct string_list *list, const char *prefix) \ { \ - int i; \ - for (i = 0; i < ARRAY_SIZE(array); i++) \ + for (size_t i = 0; i < ARRAY_SIZE(array); i++) \ if (array[i]) \ list_config_item(list, prefix, array[i]); \ } \ @@ -70,11 +69,10 @@ struct string_list #define define_list_config_array_extra(array, values) \ void list_config_##array(struct string_list *list, const char *prefix) \ { \ - int i; \ static const char *extra[] = values; \ - for (i = 0; i < ARRAY_SIZE(extra); i++) \ + for (size_t i = 0; i < ARRAY_SIZE(extra); i++) \ list_config_item(list, prefix, extra[i]); \ - for (i = 0; i < ARRAY_SIZE(array); i++) \ + for (size_t i = 0; i < ARRAY_SIZE(array); i++) \ if (array[i]) \ list_config_item(list, prefix, array[i]); \ } \ diff --git a/hex.c b/hex.c index 5ca78a7744113b..865a232167553d 100644 --- a/hex.c +++ b/hex.c @@ -7,8 +7,7 @@ static int get_hash_hex_algop(const char *hex, unsigned char *hash, const struct git_hash_algo *algop) { - int i; - for (i = 0; i < algop->rawsz; i++) { + for (size_t i = 0; i < algop->rawsz; i++) { int val = hex2chr(hex); if (val < 0) return -1; @@ -83,7 +82,6 @@ char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, { static const char hex[] = "0123456789abcdef"; char *buf = buffer; - int i; /* * Our struct object_id has been memset to 0, so default to printing @@ -92,7 +90,7 @@ char *hash_to_hex_algop_r(char *buffer, const unsigned char *hash, if (algop == &hash_algos[0]) algop = the_hash_algo; - for (i = 0; i < algop->rawsz; i++) { + for (size_t i = 0; i < algop->rawsz; i++) { unsigned int val = *hash++; *buf++ = hex[val >> 4]; *buf++ = hex[val & 0xf]; diff --git a/hook.c b/hook.c index a9320cb0ce95e5..b3de1048bf44b9 100644 --- a/hook.c +++ b/hook.c @@ -16,8 +16,7 @@ const char *find_hook(struct repository *r, const char *name) int found_hook; - strbuf_reset(&path); - strbuf_repo_git_path(&path, r, "hooks/%s", name); + repo_git_path_replace(r, &path, "hooks/%s", name); found_hook = access(path.buf, X_OK) >= 0; #ifdef STRIP_EXTENSION if (!found_hook) { @@ -39,7 +38,7 @@ const char *find_hook(struct repository *r, const char *name) advise(_("The '%s' hook was ignored because " "it's not set as executable.\n" "You can disable this warning with " - "`git config advice.ignoredHook false`."), + "`git config set advice.ignoredHook false`."), path.buf); } } diff --git a/http-backend.c b/http-backend.c index 73eec4ea3d8443..50b2858fad634a 100644 --- a/http-backend.c +++ b/http-backend.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -182,7 +183,7 @@ static void send_strbuf(struct strbuf *hdr, static void send_local_file(struct strbuf *hdr, const char *the_type, const char *name) { - char *p = git_pathdup("%s", name); + char *p = repo_git_path(the_repository, "%s", name); size_t buf_alloc = 8192; char *buf = xmalloc(buf_alloc); int fd; diff --git a/http-fetch.c b/http-fetch.c index d460bb1837d06f..02ab80533f0e34 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -106,6 +106,7 @@ int cmd_main(int argc, const char **argv) int nongit; struct object_id packfile_hash; struct strvec index_pack_args = STRVEC_INIT; + int ret; setup_git_directory_gently(&nongit); @@ -157,8 +158,8 @@ int cmd_main(int argc, const char **argv) fetch_single_packfile(&packfile_hash, argv[arg], index_pack_args.v); - - return 0; + ret = 0; + goto out; } if (index_pack_args.nr) @@ -170,7 +171,12 @@ int cmd_main(int argc, const char **argv) commit_id = (char **) &argv[arg++]; commits = 1; } - return fetch_using_walker(argv[arg], get_verbosely, get_recover, - commits, commit_id, write_ref, - commits_on_stdin); + + ret = fetch_using_walker(argv[arg], get_verbosely, get_recover, + commits, commit_id, write_ref, + commits_on_stdin); + +out: + strvec_clear(&index_pack_args); + return ret; } diff --git a/http-push.c b/http-push.c index 7315a694aa4b8a..1b030d96f48002 100644 --- a/http-push.c +++ b/http-push.c @@ -275,7 +275,7 @@ static void start_fetch_loose(struct transfer_request *request) if (!start_active_slot(slot)) { fprintf(stderr, "Unable to start GET request\n"); repo->can_update_info_refs = 0; - release_http_object_request(obj_req); + release_http_object_request(&obj_req); release_request(request); } } @@ -309,7 +309,7 @@ static void start_fetch_packed(struct transfer_request *request) struct transfer_request *check_request = request_queue_head; struct http_pack_request *preq; - target = find_sha1_pack(request->obj->oid.hash, repo->packs); + target = find_oid_pack(&request->obj->oid, repo->packs); if (!target) { fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", oid_to_hex(&request->obj->oid)); repo->can_update_info_refs = 0; @@ -375,7 +375,7 @@ static void start_put(struct transfer_request *request) /* Set it up */ git_deflate_init(&stream, zlib_compression_level); size = git_deflate_bound(&stream, len + hdrlen); - strbuf_init(&request->buffer.buf, size); + strbuf_grow(&request->buffer.buf, size); request->buffer.posn = 0; /* Compress it */ @@ -437,9 +437,11 @@ static void start_move(struct transfer_request *request) if (start_active_slot(slot)) { request->slot = slot; request->state = RUN_MOVE; + request->headers = dav_headers; } else { request->state = ABORTED; FREE_AND_NULL(request->url); + curl_slist_free_all(dav_headers); } } @@ -512,6 +514,8 @@ static void release_request(struct transfer_request *request) } free(request->url); + free(request->dest); + strbuf_release(&request->buffer.buf); free(request); } @@ -578,9 +582,10 @@ static void finish_request(struct transfer_request *request) if (obj_req->rename == 0) request->obj->flags |= (LOCAL | REMOTE); + release_http_object_request(&obj_req); + /* Try fetching packed if necessary */ if (request->obj->flags & LOCAL) { - release_http_object_request(obj_req); release_request(request); } else start_fetch_packed(request); @@ -649,12 +654,10 @@ static void add_fetch_request(struct object *obj) return; obj->flags |= FETCHING; - request = xmalloc(sizeof(*request)); + CALLOC_ARRAY(request, 1); request->obj = obj; - request->url = NULL; - request->lock = NULL; - request->headers = NULL; request->state = NEED_FETCH; + strbuf_init(&request->buffer.buf, 0); request->next = request_queue_head; request_queue_head = request; @@ -678,19 +681,18 @@ static int add_send_request(struct object *obj, struct remote_lock *lock) get_remote_object_list(obj->oid.hash[0]); if (obj->flags & (REMOTE | PUSHING)) return 0; - target = find_sha1_pack(obj->oid.hash, repo->packs); + target = find_oid_pack(&obj->oid, repo->packs); if (target) { obj->flags |= REMOTE; return 0; } obj->flags |= PUSHING; - request = xmalloc(sizeof(*request)); + CALLOC_ARRAY(request, 1); request->obj = obj; - request->url = NULL; request->lock = lock; - request->headers = NULL; request->state = NEED_PUSH; + strbuf_init(&request->buffer.buf, 0); request->next = request_queue_head; request_queue_head = request; @@ -758,7 +760,7 @@ static void handle_lockprop_ctx(struct xml_ctx *ctx, int tag_closed) static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed) { struct remote_lock *lock = (struct remote_lock *)ctx->userData; - git_hash_ctx hash_ctx; + struct git_hash_ctx hash_ctx; unsigned char lock_token_hash[GIT_MAX_RAWSZ]; if (tag_closed && ctx->cdata) { @@ -772,8 +774,8 @@ static void handle_new_lock_ctx(struct xml_ctx *ctx, int tag_closed) lock->token = xstrdup(ctx->cdata); the_hash_algo->init_fn(&hash_ctx); - the_hash_algo->update_fn(&hash_ctx, lock->token, strlen(lock->token)); - the_hash_algo->final_fn(lock_token_hash, &hash_ctx); + git_hash_update(&hash_ctx, lock->token, strlen(lock->token)); + git_hash_final(lock_token_hash, &hash_ctx); lock->tmpfile_suffix[0] = '_'; memcpy(lock->tmpfile_suffix + 1, hash_to_hex(lock_token_hash), the_hash_algo->hexsz); @@ -912,6 +914,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout) result = XML_Parse(parser, in_buffer.buf, in_buffer.len, 1); free(ctx.name); + free(ctx.cdata); if (result != XML_STATUS_OK) { fprintf(stderr, "XML error: %s\n", XML_ErrorString( @@ -1169,6 +1172,7 @@ static void remote_ls(const char *path, int flags, result = XML_Parse(parser, in_buffer.buf, in_buffer.len, 1); free(ctx.name); + free(ctx.cdata); if (result != XML_STATUS_OK) { fprintf(stderr, "XML error: %s\n", @@ -1182,6 +1186,7 @@ static void remote_ls(const char *path, int flags, } free(ls.path); + free(ls.dentry_name); free(url); strbuf_release(&out_buffer.buf); strbuf_release(&in_buffer); @@ -1333,7 +1338,6 @@ static struct object_list **process_tree(struct tree *tree, static int get_delta(struct rev_info *revs, struct remote_lock *lock) { - int i; struct commit *commit; struct object_list **p = &objects; int count = 0; @@ -1346,7 +1350,7 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock) count += add_send_request(&commit->object, lock); } - for (i = 0; i < revs->pending.nr; i++) { + for (size_t i = 0; i < revs->pending.nr; i++) { struct object_array_entry *entry = revs->pending.objects + i; struct object *obj = entry->item; const char *name = entry->name; @@ -1370,9 +1374,13 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock) } while (objects) { + struct object_list *next = objects->next; + if (!(objects->item->flags & UNINTERESTING)) count += add_send_request(objects->item, lock); - objects = objects->next; + + free(objects); + objects = next; } return count; @@ -1398,6 +1406,7 @@ static int update_remote(const struct object_id *oid, struct remote_lock *lock) if (start_active_slot(slot)) { run_active_slot(slot); strbuf_release(&out_buffer.buf); + curl_slist_free_all(dav_headers); if (results.curl_result != CURLE_OK) { fprintf(stderr, "PUT error: curl result=%d, HTTP code=%ld\n", @@ -1407,6 +1416,7 @@ static int update_remote(const struct object_id *oid, struct remote_lock *lock) } } else { strbuf_release(&out_buffer.buf); + curl_slist_free_all(dav_headers); fprintf(stderr, "Unable to start PUT request\n"); return 0; } @@ -1516,6 +1526,7 @@ static void update_remote_info_refs(struct remote_lock *lock) results.curl_result, results.http_code); } } + curl_slist_free_all(dav_headers); } strbuf_release(&buffer.buf); } @@ -1707,7 +1718,7 @@ int cmd_main(int argc, const char **argv) int rc = 0; int i; int new_refs; - struct ref *ref, *local_refs; + struct ref *ref, *local_refs = NULL; CALLOC_ARRAY(repo, 1); @@ -1972,6 +1983,7 @@ int cmd_main(int argc, const char **argv) cleanup: if (info_ref_lock) unlock_remote(info_ref_lock); + free(repo->url); free(repo); http_cleanup(); @@ -1983,5 +1995,8 @@ int cmd_main(int argc, const char **argv) request = next_request; } + refspec_clear(&rs); + free_refs(local_refs); + return rc; } diff --git a/http-walker.c b/http-walker.c index e417a7f51ce3c3..7918ddc0968dd3 100644 --- a/http-walker.c +++ b/http-walker.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "repository.h" @@ -74,7 +75,7 @@ static void start_object_request(struct object_request *obj_req) obj_req->state = ACTIVE; if (!start_active_slot(slot)) { obj_req->state = ABORTED; - release_http_object_request(req); + release_http_object_request(&req); return; } } @@ -110,7 +111,7 @@ static void process_object_response(void *callback_data) if (obj_req->repo->next) { obj_req->repo = obj_req->repo->next; - release_http_object_request(obj_req->req); + release_http_object_request(&obj_req->req); start_object_request(obj_req); return; } @@ -147,14 +148,14 @@ static int fill_active_slot(void *data UNUSED) return 0; } -static void prefetch(struct walker *walker, unsigned char *sha1) +static void prefetch(struct walker *walker, const struct object_id *oid) { struct object_request *newreq; struct walker_data *data = walker->data; newreq = xmalloc(sizeof(*newreq)); newreq->walker = walker; - oidread(&newreq->oid, sha1, the_repository->hash_algo); + oidcpy(&newreq->oid, oid); newreq->repo = data->alt; newreq->state = WAITING; newreq->req = NULL; @@ -422,7 +423,8 @@ static int fetch_indices(struct walker *walker, struct alt_base *repo) return ret; } -static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigned char *sha1) +static int http_fetch_pack(struct walker *walker, struct alt_base *repo, + const struct object_id *oid) { struct packed_git *target; int ret; @@ -431,7 +433,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne if (fetch_indices(walker, repo)) return -1; - target = find_sha1_pack(sha1, repo->packs); + target = find_oid_pack(oid, repo->packs); if (!target) return -1; close_pack_index(target); @@ -440,7 +442,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo, unsigne fprintf(stderr, "Getting pack %s\n", hash_to_hex(target->hash)); fprintf(stderr, " which contains %s\n", - hash_to_hex(sha1)); + oid_to_hex(oid)); } preq = new_http_pack_request(target->hash, repo->base); @@ -477,9 +479,9 @@ static void abort_object_request(struct object_request *obj_req) release_object_request(obj_req); } -static int fetch_object(struct walker *walker, unsigned char *hash) +static int fetch_object(struct walker *walker, const struct object_id *oid) { - char *hex = hash_to_hex(hash); + char *hex = oid_to_hex(oid); int ret = 0; struct object_request *obj_req = NULL; struct http_object_request *req; @@ -487,7 +489,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash) list_for_each(pos, head) { obj_req = list_entry(pos, struct object_request, node); - if (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo)) + if (oideq(&obj_req->oid, oid)) break; } if (!obj_req) @@ -495,7 +497,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash) if (repo_has_object_file(the_repository, &obj_req->oid)) { if (obj_req->req) - abort_http_object_request(obj_req->req); + abort_http_object_request(&obj_req->req); abort_object_request(obj_req); return 0; } @@ -543,25 +545,25 @@ static int fetch_object(struct walker *walker, unsigned char *hash) strbuf_release(&buf); } - release_http_object_request(req); + release_http_object_request(&obj_req->req); release_object_request(obj_req); return ret; } -static int fetch(struct walker *walker, unsigned char *hash) +static int fetch(struct walker *walker, const struct object_id *oid) { struct walker_data *data = walker->data; struct alt_base *altbase = data->alt; - if (!fetch_object(walker, hash)) + if (!fetch_object(walker, oid)) return 0; while (altbase) { - if (!http_fetch_pack(walker, altbase, hash)) + if (!http_fetch_pack(walker, altbase, oid)) return 0; fetch_alternates(walker, data->alt->base); altbase = altbase->next; } - return error("Unable to find %s under %s", hash_to_hex(hash), + return error("Unable to find %s under %s", oid_to_hex(oid), data->alt->base); } @@ -579,8 +581,18 @@ static void cleanup(struct walker *walker) if (data) { alt = data->alt; while (alt) { + struct packed_git *pack; + alt_next = alt->next; + pack = alt->packs; + while (pack) { + struct packed_git *pack_next = pack->next; + close_pack(pack); + free(pack); + pack = pack_next; + } + free(alt->base); free(alt); diff --git a/http.c b/http.c index 376af88c5dc0ed..0c9a872809f872 100644 --- a/http.c +++ b/http.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "git-curl-compat.h" @@ -19,6 +20,7 @@ #include "string-list.h" #include "object-file.h" #include "object-store-ll.h" +#include "tempfile.h" static struct trace_key trace_curl = TRACE_KEY_INIT(CURL); static int trace_curl_data = 1; @@ -52,22 +54,16 @@ static struct { { "sslv2", CURL_SSLVERSION_SSLv2 }, { "sslv3", CURL_SSLVERSION_SSLv3 }, { "tlsv1", CURL_SSLVERSION_TLSv1 }, -#ifdef GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_0 { "tlsv1.0", CURL_SSLVERSION_TLSv1_0 }, { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 }, { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 }, -#endif -#ifdef GIT_CURL_HAVE_CURL_SSLVERSION_TLSv1_3 { "tlsv1.3", CURL_SSLVERSION_TLSv1_3 }, -#endif }; static char *ssl_key; static char *ssl_key_type; static char *ssl_capath; static char *curl_no_proxy; -#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY static char *ssl_pinnedkey; -#endif static char *ssl_cainfo; static long curl_low_speed_limit = -1; static long curl_low_speed_time = -1; @@ -511,12 +507,7 @@ static int http_options(const char *var, const char *value, } if (!strcmp("http.pinnedpubkey", var)) { -#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY return git_config_pathname(&ssl_pinnedkey, var, value); -#else - warning(_("Public key pinning not supported with cURL < 7.39.0")); - return 0; -#endif } if (!strcmp("http.extraheader", var)) { @@ -607,8 +598,7 @@ static void init_curl_http_auth(CURL *result) { if ((!http_auth.username || !*http_auth.username) && (!http_auth.credential || !*http_auth.credential)) { - int empty_auth = curl_empty_auth_enabled(); - if ((empty_auth != -1 && !always_auth_proactively()) || empty_auth == 1) { + if (!always_auth_proactively() && curl_empty_auth_enabled()) { curl_easy_setopt(result, CURLOPT_USERPWD, ":"); return; } else if (!always_auth_proactively()) { @@ -618,7 +608,7 @@ static void init_curl_http_auth(CURL *result) } } - credential_fill(&http_auth, 1); + credential_fill(the_repository, &http_auth, 1); if (http_auth.password) { if (always_auth_proactively()) { @@ -661,7 +651,7 @@ static void init_curl_proxy_auth(CURL *result) { if (proxy_auth.username) { if (!proxy_auth.password && !proxy_auth.credential) - credential_fill(&proxy_auth, 1); + credential_fill(the_repository, &proxy_auth, 1); set_proxyauth_name_password(result); } @@ -695,12 +685,11 @@ static int has_cert_password(void) cert_auth.host = xstrdup(""); cert_auth.username = xstrdup(""); cert_auth.path = xstrdup(ssl_cert); - credential_fill(&cert_auth, 0); + credential_fill(the_repository, &cert_auth, 0); } return 1; } -#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD static int has_proxy_cert_password(void) { if (http_proxy_ssl_cert == NULL || proxy_ssl_cert_password_required != 1) @@ -710,41 +699,16 @@ static int has_proxy_cert_password(void) proxy_cert_auth.host = xstrdup(""); proxy_cert_auth.username = xstrdup(""); proxy_cert_auth.path = xstrdup(http_proxy_ssl_cert); - credential_fill(&proxy_cert_auth, 0); + credential_fill(the_repository, &proxy_cert_auth, 0); } return 1; } -#endif -#ifdef GITCURL_HAVE_CURLOPT_TCP_KEEPALIVE static void set_curl_keepalive(CURL *c) { curl_easy_setopt(c, CURLOPT_TCP_KEEPALIVE, 1); } -#else -static int sockopt_callback(void *client, curl_socket_t fd, curlsocktype type) -{ - int ka = 1; - int rc; - socklen_t len = (socklen_t)sizeof(ka); - - if (type != CURLSOCKTYPE_IPCXN) - return 0; - - rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&ka, len); - if (rc < 0) - warning_errno("unable to set SO_KEEPALIVE on socket"); - - return CURL_SOCKOPT_OK; -} - -static void set_curl_keepalive(CURL *c) -{ - curl_easy_setopt(c, CURLOPT_SOCKOPTFUNCTION, sockopt_callback); -} -#endif - /* Return 1 if redactions have been made, 0 otherwise. */ static int redact_sensitive_header(struct strbuf *header, size_t offset) { @@ -800,6 +764,7 @@ static int redact_sensitive_header(struct strbuf *header, size_t offset) strbuf_setlen(header, sensitive_header - header->buf); strbuf_addbuf(header, &redacted_header); + strbuf_release(&redacted_header); ret = 1; } return ret; @@ -1012,7 +977,6 @@ static long get_curl_allowed_protocols(int from_user, struct strbuf *list) return bits; } -#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2 static int get_curl_http_version_opt(const char *version_string, long *opt) { int i; @@ -1035,8 +999,6 @@ static int get_curl_http_version_opt(const char *version_string, long *opt) return -1; /* not found */ } -#endif - static CURL *get_curl_handle(void) { CURL *result = curl_easy_init(); @@ -1054,7 +1016,6 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_SSL_VERIFYHOST, 2); } -#ifdef GIT_CURL_HAVE_CURL_HTTP_VERSION_2 if (curl_http_version) { long opt; if (!get_curl_http_version_opt(curl_http_version, &opt)) { @@ -1062,7 +1023,6 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_HTTP_VERSION, opt); } } -#endif curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY); @@ -1085,11 +1045,7 @@ static CURL *get_curl_handle(void) if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) && !http_schannel_check_revoke) { -#ifdef GIT_CURL_HAVE_CURLSSLOPT_NO_REVOKE curl_easy_setopt(result, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE); -#else - warning(_("CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0")); -#endif } if (http_proactive_auth != PROACTIVE_AUTH_NONE) @@ -1129,23 +1085,17 @@ static CURL *get_curl_handle(void) curl_easy_setopt(result, CURLOPT_SSLKEYTYPE, ssl_key_type); if (ssl_capath) curl_easy_setopt(result, CURLOPT_CAPATH, ssl_capath); -#ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY if (ssl_pinnedkey) curl_easy_setopt(result, CURLOPT_PINNEDPUBLICKEY, ssl_pinnedkey); -#endif if (http_ssl_backend && !strcmp("schannel", http_ssl_backend) && !http_schannel_use_ssl_cainfo) { curl_easy_setopt(result, CURLOPT_CAINFO, NULL); -#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, NULL); -#endif } else if (ssl_cainfo != NULL || http_proxy_ssl_ca_info != NULL) { if (ssl_cainfo) curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo); -#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_CAINFO if (http_proxy_ssl_ca_info) curl_easy_setopt(result, CURLOPT_PROXY_CAINFO, http_proxy_ssl_ca_info); -#endif } if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) { @@ -1241,7 +1191,6 @@ static CURL *get_curl_handle(void) else if (starts_with(curl_http_proxy, "socks")) curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); -#ifdef GIT_CURL_HAVE_CURLOPT_PROXY_KEYPASSWD else if (starts_with(curl_http_proxy, "https")) { curl_easy_setopt(result, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); @@ -1254,7 +1203,6 @@ static CURL *get_curl_handle(void) if (has_proxy_cert_password()) curl_easy_setopt(result, CURLOPT_PROXY_KEYPASSWD, proxy_cert_auth.password); } -#endif if (strstr(curl_http_proxy, "://")) credential_from_url(&proxy_auth, curl_http_proxy); else { @@ -1328,7 +1276,6 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) free(normalized_url); string_list_clear(&config.vars, 1); -#ifdef GIT_CURL_HAVE_CURLSSLSET_NO_BACKENDS if (http_ssl_backend) { const curl_ssl_backend **backends; struct strbuf buf = STRBUF_INIT; @@ -1353,7 +1300,6 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) break; /* Okay! */ } } -#endif if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) die("curl_global_init failed"); @@ -1837,9 +1783,9 @@ static int handle_curl_result(struct slot_results *results) curl_errorstr, sizeof(curl_errorstr)); if (results->curl_result == CURLE_OK) { - credential_approve(&http_auth); - credential_approve(&proxy_auth); - credential_approve(&cert_auth); + credential_approve(the_repository, &http_auth); + credential_approve(the_repository, &proxy_auth); + credential_approve(the_repository, &cert_auth); return HTTP_OK; } else if (results->curl_result == CURLE_SSL_CERTPROBLEM) { /* @@ -1848,12 +1794,10 @@ static int handle_curl_result(struct slot_results *results) * with the certificate. So we reject the credential to * avoid caching or saving a bad password. */ - credential_reject(&cert_auth); + credential_reject(the_repository, &cert_auth); return HTTP_NOAUTH; -#ifdef GIT_CURL_HAVE_CURLE_SSL_PINNEDPUBKEYNOTMATCH } else if (results->curl_result == CURLE_SSL_PINNEDPUBKEYNOTMATCH) { return HTTP_NOMATCHPUBLICKEY; -#endif } else if (missing_target(results)) return HTTP_MISSING_TARGET; else if (results->http_code == 401) { @@ -1863,7 +1807,7 @@ static int handle_curl_result(struct slot_results *results) credential_clear_secrets(&http_auth); return HTTP_REAUTH; } - credential_reject(&http_auth); + credential_reject(the_repository, &http_auth); if (always_auth_proactively()) http_proactive_auth = PROACTIVE_AUTH_NONE; return HTTP_NOAUTH; @@ -1877,7 +1821,7 @@ static int handle_curl_result(struct slot_results *results) } } else { if (results->http_connectcode == 407) - credential_reject(&proxy_auth); + credential_reject(the_repository, &proxy_auth); if (!curl_errorstr[0]) strlcpy(curl_errorstr, curl_easy_strerror(results->curl_result), @@ -2265,7 +2209,7 @@ static int http_request_reauth(const char *url, int ret; if (always_auth_proactively()) - credential_fill(&http_auth, 1); + credential_fill(the_repository, &http_auth, 1); ret = http_request(url, result, target, options); @@ -2289,22 +2233,24 @@ static int http_request_reauth(const char *url, case HTTP_REQUEST_STRBUF: strbuf_reset(result); break; - case HTTP_REQUEST_FILE: - if (fflush(result)) { + case HTTP_REQUEST_FILE: { + FILE *f = result; + if (fflush(f)) { error_errno("unable to flush a file"); return HTTP_START_FAILED; } - rewind(result); - if (ftruncate(fileno(result), 0) < 0) { + rewind(f); + if (ftruncate(fileno(f), 0) < 0) { error_errno("unable to truncate a file"); return HTTP_START_FAILED; } break; + } default: BUG("Unknown http_request target"); } - credential_fill(&http_auth, 1); + credential_fill(the_repository, &http_auth, 1); ret = http_request(url, result, target, options); } @@ -2387,8 +2333,24 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url) strbuf_addf(&buf, "objects/pack/pack-%s.idx", hash_to_hex(hash)); url = strbuf_detach(&buf, NULL); - strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(hash)); - tmp = strbuf_detach(&buf, NULL); + /* + * Don't put this into packs/, since it's just temporary and we don't + * want to confuse it with our local .idx files. We'll generate our + * own index if we choose to download the matching packfile. + * + * It's tempting to use xmks_tempfile() here, but it's important that + * the file not exist, otherwise http_get_file() complains. So we + * create a filename that should be unique, and then just register it + * as a tempfile so that it will get cleaned up on exit. + * + * In theory we could hold on to the tempfile and delete these as soon + * as we download the matching pack, but it would take a bit of + * refactoring. Leaving them until the process ends is probably OK. + */ + tmp = xstrfmt("%s/tmp_pack_%s.idx", + repo_get_object_directory(the_repository), + hash_to_hex(hash)); + register_tempfile(tmp); if (http_get_file(url, tmp, NULL) != HTTP_OK) { error("Unable to get pack index %s", url); @@ -2402,22 +2364,24 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url) static int fetch_and_setup_pack_index(struct packed_git **packs_head, unsigned char *sha1, const char *base_url) { - struct packed_git *new_pack; + struct packed_git *new_pack, *p; char *tmp_idx = NULL; int ret; - if (has_pack_index(sha1)) { - new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1)); - if (!new_pack) - return -1; /* parse_pack_index() already issued error message */ - goto add_pack; + /* + * If we already have the pack locally, no need to fetch its index or + * even add it to list; we already have all of its objects. + */ + for (p = get_all_packs(the_repository); p; p = p->next) { + if (hasheq(p->hash, sha1, the_repository->hash_algo)) + return 0; } tmp_idx = fetch_pack_index(sha1, base_url); if (!tmp_idx) return -1; - new_pack = parse_pack_index(sha1, tmp_idx); + new_pack = parse_pack_index(the_repository, sha1, tmp_idx); if (!new_pack) { unlink(tmp_idx); free(tmp_idx); @@ -2426,15 +2390,12 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head, } ret = verify_pack_index(new_pack); - if (!ret) { + if (!ret) close_pack_index(new_pack); - ret = finalize_object_file(tmp_idx, sha1_pack_index_name(sha1)); - } free(tmp_idx); if (ret) return -1; -add_pack: new_pack->next = *packs_head; *packs_head = new_pack; return 0; @@ -2474,6 +2435,7 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head) cleanup: free(url); + strbuf_release(&buf); return ret; } @@ -2561,7 +2523,8 @@ struct http_pack_request *new_direct_http_pack_request( preq->url = url; - strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(packed_git_hash)); + odb_pack_name(the_repository, &preq->tmpfile, packed_git_hash, "pack"); + strbuf_addstr(&preq->tmpfile, ".temp"); preq->packfile = fopen(preq->tmpfile.buf, "a"); if (!preq->packfile) { error("Unable to open local file %s for pack", @@ -2633,8 +2596,8 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb, freq->stream.next_out = expn; freq->stream.avail_out = sizeof(expn); freq->zret = git_inflate(&freq->stream, Z_SYNC_FLUSH); - the_hash_algo->update_fn(&freq->c, expn, - sizeof(expn) - freq->stream.avail_out); + git_hash_update(&freq->c, expn, + sizeof(expn) - freq->stream.avail_out); } while (freq->stream.avail_in && freq->zret == Z_OK); return nmemb; } @@ -2725,6 +2688,7 @@ struct http_object_request *new_http_object_request(const char *base_url, * file; also rewind to the beginning of the local file. */ if (prev_read == -1) { + git_inflate_end(&freq->stream); memset(&freq->stream, 0, sizeof(freq->stream)); git_inflate_init(&freq->stream); the_hash_algo->init_fn(&freq->c); @@ -2798,8 +2762,7 @@ int finish_http_object_request(struct http_object_request *freq) return -1; } - git_inflate_end(&freq->stream); - the_hash_algo->final_oid_fn(&freq->real_oid, &freq->c); + git_hash_final_oid(&freq->real_oid, &freq->c); if (freq->zret != Z_STREAM_END) { unlink_or_warn(freq->tmpfile.buf); return -1; @@ -2815,15 +2778,17 @@ int finish_http_object_request(struct http_object_request *freq) return freq->rename; } -void abort_http_object_request(struct http_object_request *freq) +void abort_http_object_request(struct http_object_request **freq_p) { + struct http_object_request *freq = *freq_p; unlink_or_warn(freq->tmpfile.buf); - release_http_object_request(freq); + release_http_object_request(freq_p); } -void release_http_object_request(struct http_object_request *freq) +void release_http_object_request(struct http_object_request **freq_p) { + struct http_object_request *freq = *freq_p; if (freq->localfile != -1) { close(freq->localfile); freq->localfile = -1; @@ -2837,4 +2802,8 @@ void release_http_object_request(struct http_object_request *freq) } curl_slist_free_all(freq->headers); strbuf_release(&freq->tmpfile); + git_inflate_end(&freq->stream); + + free(freq); + *freq_p = NULL; } diff --git a/http.h b/http.h index a516ca4a9a2db1..36202139f451ff 100644 --- a/http.h +++ b/http.h @@ -228,7 +228,7 @@ struct http_object_request { long http_code; struct object_id oid; struct object_id real_oid; - git_hash_ctx c; + struct git_hash_ctx c; git_zstream stream; int zret; int rename; @@ -240,8 +240,8 @@ struct http_object_request *new_http_object_request( const char *base_url, const struct object_id *oid); void process_http_object_request(struct http_object_request *freq); int finish_http_object_request(struct http_object_request *freq); -void abort_http_object_request(struct http_object_request *freq); -void release_http_object_request(struct http_object_request *freq); +void abort_http_object_request(struct http_object_request **freq); +void release_http_object_request(struct http_object_request **freq); /* * Instead of using environment variables to determine if curl tracing happens, diff --git a/ident.c b/ident.c index caf41fb2a98f56..967895d885033d 100644 --- a/ident.c +++ b/ident.c @@ -59,7 +59,7 @@ static struct passwd *xgetpwuid_self(int *is_bogus) static void copy_gecos(const struct passwd *w, struct strbuf *name) { - char *src; + const char *src; /* Traditionally GECOS field had office phone numbers etc, separated * with commas. Also & stands for capitalized form of the login name. diff --git a/imap-send.c b/imap-send.c index ec68a066877765..6c8f84e836bb40 100644 --- a/imap-send.c +++ b/imap-send.c @@ -22,6 +22,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -668,12 +669,12 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb, return RESP_BAD; } if (!strcmp("UIDVALIDITY", arg)) { - if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg))) { + if (!(arg = next_arg(&s)) || strtol_i(arg, 10, &ctx->uidvalidity) || !ctx->uidvalidity) { fprintf(stderr, "IMAP error: malformed UIDVALIDITY status\n"); return RESP_BAD; } } else if (!strcmp("UIDNEXT", arg)) { - if (!(arg = next_arg(&s)) || !(imap->uidnext = atoi(arg))) { + if (!(arg = next_arg(&s)) || strtol_i(arg, 10, &imap->uidnext) || !imap->uidnext) { fprintf(stderr, "IMAP error: malformed NEXTUID status\n"); return RESP_BAD; } @@ -686,8 +687,8 @@ static int parse_response_code(struct imap_store *ctx, struct imap_cmd_cb *cb, for (; isspace((unsigned char)*p); p++); fprintf(stderr, "*** IMAP ALERT *** %s\n", p); } else if (cb && cb->ctx && !strcmp("APPENDUID", arg)) { - if (!(arg = next_arg(&s)) || !(ctx->uidvalidity = atoi(arg)) || - !(arg = next_arg(&s)) || !(*(int *)cb->ctx = atoi(arg))) { + if (!(arg = next_arg(&s)) || strtol_i(arg, 10, &ctx->uidvalidity) || !ctx->uidvalidity || + !(arg = next_arg(&s)) || strtol_i(arg, 10, (int *)cb->ctx) || !cb->ctx) { fprintf(stderr, "IMAP error: malformed APPENDUID status\n"); return RESP_BAD; } @@ -773,7 +774,10 @@ static int get_cmd_result(struct imap_store *ctx, struct imap_cmd *tcmd) if (!tcmd) return DRV_OK; } else { - tag = atoi(arg); + if (strtol_i(arg, 10, &tag)) { + fprintf(stderr, "IMAP error: malformed tag %s\n", arg); + return RESP_BAD; + } for (pcmdp = &imap->in_progress; (cmdp = *pcmdp); pcmdp = &cmdp->next) if (cmdp->tag == tag) goto gottag; @@ -918,7 +922,7 @@ static void server_fill_credential(struct imap_server_conf *srvc, struct credent cred->username = xstrdup_or_null(srvc->user); cred->password = xstrdup_or_null(srvc->pass); - credential_fill(cred, 1); + credential_fill(the_repository, cred, 1); if (!srvc->user) srvc->user = xstrdup(cred->username); @@ -1119,7 +1123,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c } /* !preauth */ if (cred.username) - credential_approve(&cred); + credential_approve(the_repository, &cred); credential_clear(&cred); /* check the target mailbox exists */ @@ -1146,7 +1150,7 @@ static struct imap_store *imap_open_store(struct imap_server_conf *srvc, const c bail: if (cred.username) - credential_reject(&cred); + credential_reject(the_repository, &cred); credential_clear(&cred); out: @@ -1417,15 +1421,11 @@ static CURL *setup_curl(struct imap_server_conf *srvc, struct credential *cred) curl_easy_setopt(curl, CURLOPT_PORT, srvc->port); if (srvc->auth_method) { -#ifndef GIT_CURL_HAVE_CURLOPT_LOGIN_OPTIONS - warning("No LOGIN_OPTIONS support in this cURL version"); -#else struct strbuf auth = STRBUF_INIT; strbuf_addstr(&auth, "AUTH="); strbuf_addstr(&auth, srvc->auth_method); curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, auth.buf); strbuf_release(&auth); -#endif } if (!srvc->use_ssl) @@ -1492,9 +1492,9 @@ static int curl_append_msgs_to_imap(struct imap_server_conf *server, if (cred.username) { if (res == CURLE_OK) - credential_approve(&cred); + credential_approve(the_repository, &cred); else if (res == CURLE_LOGIN_DENIED) - credential_reject(&cred); + credential_reject(the_repository, &cred); } credential_clear(&cred); diff --git a/json-writer.c b/json-writer.c index 25b9201f9c0bce..8c5187e9fdda81 100644 --- a/json-writer.c +++ b/json-writer.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "json-writer.h" diff --git a/kwset.c b/kwset.c index 695e47b7ccfaf1..1714eada608b86 100644 --- a/kwset.c +++ b/kwset.c @@ -32,6 +32,8 @@ String Matching: An Aid to Bibliographic Search," CACM June 1975, Vol. 18, No. 6, which describes the failure function used below. */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "kwset.h" diff --git a/line-log.c b/line-log.c index 67c80b39a0df2e..628e3fe3ae18dc 100644 --- a/line-log.c +++ b/line-log.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "diffcore.h" #include "line-range.h" @@ -248,8 +250,10 @@ static void line_log_data_init(struct line_log_data *r) static void line_log_data_clear(struct line_log_data *r) { range_set_release(&r->ranges); + free(r->path); if (r->pair) diff_free_filepair(r->pair); + diff_ranges_release(&r->diff); } static void free_line_log_data(struct line_log_data *r) @@ -571,7 +575,8 @@ parse_lines(struct repository *r, struct commit *commit, struct line_log_data *p; for_each_string_list_item(item, args) { - const char *name_part, *range_part; + const char *name_part; + char *range_part; char *full_name; struct diff_filespec *spec; long begin = 0, end = 0; @@ -615,6 +620,7 @@ parse_lines(struct repository *r, struct commit *commit, free_filespec(spec); FREE_AND_NULL(ends); + free(range_part); } for (p = ranges; p; p = p->next) @@ -760,15 +766,13 @@ static void parse_pathspec_from_ranges(struct pathspec *pathspec, { struct line_log_data *r; struct strvec array = STRVEC_INIT; - const char **paths; for (r = range; r; r = r->next) strvec_push(&array, r->path); - paths = strvec_detach(&array); - parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", paths); - /* strings are now owned by pathspec */ - free(paths); + parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", array.v); + + strvec_clear(&array); } void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args) @@ -781,21 +785,22 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list add_line_range(rev, commit, range); parse_pathspec_from_ranges(&rev->diffopt.pathspec, range); + + free_line_log_data(range); } static void move_diff_queue(struct diff_queue_struct *dst, struct diff_queue_struct *src) { assert(src != dst); - memcpy(dst, src, sizeof(struct diff_queue_struct)); - DIFF_QUEUE_CLEAR(src); + memcpy(dst, src, sizeof(*dst)); + diff_queue_init(src); } static void filter_diffs_for_paths(struct line_log_data *range, int keep_deletions) { int i; - struct diff_queue_struct outq; - DIFF_QUEUE_CLEAR(&outq); + struct diff_queue_struct outq = DIFF_QUEUE_INIT; for (i = 0; i < diff_queued_diff.nr; i++) { struct diff_filepair *p = diff_queued_diff.queue[i]; @@ -850,12 +855,12 @@ static void queue_diffs(struct line_log_data *range, clear_pathspec(&opt->pathspec); parse_pathspec_from_ranges(&opt->pathspec, range); } - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_clear(&diff_queued_diff); diff_tree_oid(parent_tree_oid, tree_oid, "", opt); if (opt->detect_rename && diff_might_be_rename()) { /* must look at the full tree diff to detect renames */ clear_pathspec(&opt->pathspec); - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_clear(&diff_queued_diff); diff_tree_oid(parent_tree_oid, tree_oid, "", opt); @@ -897,16 +902,6 @@ static void print_line(const char *prefix, char first, fputs("\\ No newline at end of file\n", file); } -static char *output_prefix(struct diff_options *opt) -{ - if (opt->output_prefix) { - struct strbuf *sb = opt->output_prefix(opt, opt->output_prefix_data); - return sb->buf; - } else { - return xstrdup(""); - } -} - static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *range) { unsigned int i, j = 0; @@ -916,7 +911,7 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang struct diff_ranges *diff = &range->diff; struct diff_options *opt = &rev->diffopt; - char *prefix = output_prefix(opt); + const char *prefix = diff_line_prefix(opt); const char *c_reset = diff_get_color(opt->use_color, DIFF_RESET); const char *c_frag = diff_get_color(opt->use_color, DIFF_FRAGINFO); const char *c_meta = diff_get_color(opt->use_color, DIFF_METAINFO); @@ -1003,7 +998,6 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang out: free(p_ends); free(t_ends); - free(prefix); } /* @@ -1012,10 +1006,9 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang */ static void dump_diff_hacky(struct rev_info *rev, struct line_log_data *range) { - char *prefix = output_prefix(&rev->diffopt); + const char *prefix = diff_line_prefix(&rev->diffopt); fprintf(rev->diffopt.file, "%s\n", prefix); - free(prefix); while (range) { dump_diff_hacky_one(rev, range); @@ -1097,7 +1090,7 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair) static void free_diffqueues(int n, struct diff_queue_struct *dq) { for (int i = 0; i < n; i++) - diff_free_queue(&dq[i]); + diff_queue_clear(&dq[i]); free(dq); } @@ -1132,10 +1125,18 @@ static int process_all_files(struct line_log_data **range_out, while (rg && strcmp(rg->path, pair->two->path)) rg = rg->next; assert(rg); + if (rg->pair) + diff_free_filepair(rg->pair); rg->pair = diff_filepair_dup(queue->queue[i]); + diff_ranges_release(&rg->diff); memcpy(&rg->diff, pairdiff, sizeof(struct diff_ranges)); + FREE_AND_NULL(pairdiff); + } + + if (pairdiff) { + diff_ranges_release(pairdiff); + free(pairdiff); } - free(pairdiff); } return changed; @@ -1200,7 +1201,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c if (parent) add_line_range(rev, parent, parent_range); free_line_log_data(parent_range); - diff_free_queue(&queue); + diff_queue_clear(&queue); return changed; } @@ -1213,12 +1214,13 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm struct commit_list *p; int i; int nparents = commit_list_count(commit->parents); + int ret; if (nparents > 1 && rev->first_parent_only) nparents = 1; ALLOC_ARRAY(diffqueues, nparents); - ALLOC_ARRAY(cand, nparents); + CALLOC_ARRAY(cand, nparents); ALLOC_ARRAY(parents, nparents); p = commit->parents; @@ -1230,7 +1232,6 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm for (i = 0; i < nparents; i++) { int changed; - cand[i] = NULL; changed = process_all_files(&cand[i], rev, &diffqueues[i], range); if (!changed) { /* @@ -1238,13 +1239,11 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm * don't follow any other path in history */ add_line_range(rev, parents[i], cand[i]); - clear_commit_line_range(rev, commit); + free_commit_list(commit->parents); commit_list_append(parents[i], &commit->parents); - free(parents); - free(cand); - free_diffqueues(nparents, diffqueues); - /* NEEDSWORK leaking like a sieve */ - return 0; + + ret = 0; + goto out; } } @@ -1252,18 +1251,25 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm * No single parent took the blame. We add the candidates * from the above loop to the parents. */ - for (i = 0; i < nparents; i++) { + for (i = 0; i < nparents; i++) add_line_range(rev, parents[i], cand[i]); - } + ret = 1; + +out: clear_commit_line_range(rev, commit); free(parents); + for (i = 0; i < nparents; i++) { + if (!cand[i]) + continue; + line_log_data_clear(cand[i]); + free(cand[i]); + } free(cand); free_diffqueues(nparents, diffqueues); - return 1; + return ret; /* NEEDSWORK evil merge detection stuff */ - /* NEEDSWORK leaking like a sieve */ } int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit *commit) diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 00611107d20293..948376d42d06af 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -252,16 +252,14 @@ void parse_list_objects_filter( const char *arg) { struct strbuf errbuf = STRBUF_INIT; - int parse_error; if (!filter_options->filter_spec.buf) BUG("filter_options not properly initialized"); if (!filter_options->choice) { + if (gently_parse_list_objects_filter(filter_options, arg, &errbuf)) + die("%s", errbuf.buf); strbuf_addstr(&filter_options->filter_spec, arg); - - parse_error = gently_parse_list_objects_filter( - filter_options, arg, &errbuf); } else { struct list_objects_filter_options *sub; @@ -271,18 +269,17 @@ void parse_list_objects_filter( */ transform_to_combine_type(filter_options); - strbuf_addch(&filter_options->filter_spec, '+'); - filter_spec_append_urlencode(filter_options, arg); ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1, filter_options->sub_alloc); sub = &filter_options->sub[filter_options->sub_nr - 1]; list_objects_filter_init(sub); - parse_error = gently_parse_list_objects_filter(sub, arg, - &errbuf); + if (gently_parse_list_objects_filter(sub, arg, &errbuf)) + die("%s", errbuf.buf); + + strbuf_addch(&filter_options->filter_spec, '+'); + filter_spec_append_urlencode(filter_options, arg); } - if (parse_error) - die("%s", errbuf.buf); } int opt_parse_list_objects_filter(const struct option *opt, @@ -397,8 +394,6 @@ void list_objects_filter_copy( struct list_objects_filter_options *dest, const struct list_objects_filter_options *src) { - int i; - /* Copy everything. We will overwrite the pointers shortly. */ memcpy(dest, src, sizeof(struct list_objects_filter_options)); @@ -407,7 +402,7 @@ void list_objects_filter_copy( dest->sparse_oid_name = xstrdup_or_null(src->sparse_oid_name); ALLOC_ARRAY(dest->sub, dest->sub_alloc); - for (i = 0; i < src->sub_nr; i++) + for (size_t i = 0; i < src->sub_nr; i++) list_objects_filter_copy(&dest->sub[i], &src->sub[i]); } diff --git a/list-objects-filter-options.h b/list-objects-filter-options.h index 55fab8563d20a5..7b2108b98662c9 100644 --- a/list-objects-filter-options.h +++ b/list-objects-filter-options.h @@ -82,7 +82,7 @@ void list_objects_filter_init(struct list_objects_filter_options *filter_options * "filter" SP <arg> * * The filter keyword will be used by many commands. - * See Documentation/rev-list-options.txt for allowed values for <arg>. + * See Documentation/rev-list-options.adoc for allowed values for <arg>. * * Capture the given arg as the "filter_spec". This can be forwarded to * subordinate commands when necessary (although it's better to pass it through diff --git a/list-objects.c b/list-objects.c index 985d008799d0bb..943e62e868ffe7 100644 --- a/list-objects.c +++ b/list-objects.c @@ -41,7 +41,8 @@ static void show_object(struct traversal_context *ctx, { if (!ctx->show_object) return; - if (ctx->revs->unpacked && has_object_pack(&object->oid)) + if (ctx->revs->unpacked && has_object_pack(ctx->revs->repo, + &object->oid)) return; ctx->show_object(object, name, ctx->show_data); @@ -74,7 +75,7 @@ static void process_blob(struct traversal_context *ctx, */ if (ctx->revs->exclude_promisor_objects && !repo_has_object_file(the_repository, &obj->oid) && - is_promisor_object(&obj->oid)) + is_promisor_object(ctx->revs->repo, &obj->oid)) return; pathlen = path->len; @@ -179,7 +180,7 @@ static void process_tree(struct traversal_context *ctx, * an incomplete list of missing objects. */ if (revs->exclude_promisor_objects && - is_promisor_object(&obj->oid)) + is_promisor_object(revs->repo, &obj->oid)) return; if (!revs->do_not_die_on_missing_objects) @@ -283,7 +284,6 @@ void mark_edges_uninteresting(struct rev_info *revs, int sparse) { struct commit_list *list; - int i; if (sparse) { struct oidset set; @@ -320,7 +320,7 @@ void mark_edges_uninteresting(struct rev_info *revs, } if (revs->edge_hint_aggressive) { - for (i = 0; i < revs->cmdline.nr; i++) { + for (size_t i = 0; i < revs->cmdline.nr; i++) { struct object *obj = revs->cmdline.rev[i].item; struct commit *commit = (struct commit *)obj; if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING)) @@ -343,11 +343,9 @@ static void add_pending_tree(struct rev_info *revs, struct tree *tree) static void traverse_non_commits(struct traversal_context *ctx, struct strbuf *base) { - int i; - assert(base->len == 0); - for (i = 0; i < ctx->revs->pending.nr; i++) { + for (size_t i = 0; i < ctx->revs->pending.nr; i++) { struct object_array_entry *pending = ctx->revs->pending.objects + i; struct object *obj = pending->item; const char *name = pending->name; diff --git a/log-tree.c b/log-tree.c index 3758e0d3b8e415..8b184d6776344b 100644 --- a/log-tree.c +++ b/log-tree.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "commit-reach.h" @@ -232,6 +233,11 @@ void load_ref_decorations(struct decoration_filter *filter, int flags) for_each_string_list_item(item, filter->exclude_ref_config_pattern) { normalize_glob_ref(item, NULL, item->string); } + + /* normalize_glob_ref duplicates the strings */ + filter->exclude_ref_pattern->strdup_strings = 1; + filter->include_ref_pattern->strdup_strings = 1; + filter->exclude_ref_config_pattern->strdup_strings = 1; } decoration_loaded = 1; decoration_flags = flags; @@ -243,6 +249,27 @@ void load_ref_decorations(struct decoration_filter *filter, int flags) } } +void load_branch_decorations(void) +{ + if (!decoration_loaded) { + struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP; + struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP; + struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP; + struct decoration_filter decoration_filter = { + .include_ref_pattern = &decorate_refs_include, + .exclude_ref_pattern = &decorate_refs_exclude, + .exclude_ref_config_pattern = &decorate_refs_exclude_config, + }; + + string_list_append(&decorate_refs_include, "refs/heads/"); + load_ref_decorations(&decoration_filter, 0); + + string_list_clear(&decorate_refs_exclude, 0); + string_list_clear(&decorate_refs_exclude_config, 0); + string_list_clear(&decorate_refs_include, 0); + } +} + static void show_parents(struct commit *commit, int abbrev, FILE *file) { struct commit_list *p; @@ -675,7 +702,7 @@ static void show_diff_of_diff(struct rev_info *opt) struct diff_queue_struct dq; memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff)); - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_init(&diff_queued_diff); fprintf_ln(opt->diffopt.file, "\n%s", opt->idiff_title); show_interdiff(opt->idiff_oid1, opt->idiff_oid2, 2, @@ -694,7 +721,7 @@ static void show_diff_of_diff(struct rev_info *opt) }; memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff)); - DIFF_QUEUE_CLEAR(&diff_queued_diff); + diff_queue_init(&diff_queued_diff); fprintf_ln(opt->diffopt.file, "\n%s", opt->rdiff_title); /* @@ -922,12 +949,7 @@ int log_tree_diff_flush(struct rev_info *opt) * diff/diffstat output for readability. */ int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH; - if (opt->diffopt.output_prefix) { - struct strbuf *msg = NULL; - msg = opt->diffopt.output_prefix(&opt->diffopt, - opt->diffopt.output_prefix_data); - fwrite(msg->buf, msg->len, 1, opt->diffopt.file); - } + fputs(diff_line_prefix(&opt->diffopt), opt->diffopt.file); /* * We may have shown three-dashes line early @@ -1020,7 +1042,7 @@ static int do_remerge_diff(struct rev_info *opt, * into the alternative object store list as the primary. */ if (opt->remerge_diff && !opt->remerge_objdir) { - opt->remerge_objdir = tmp_objdir_create("remerge-diff"); + opt->remerge_objdir = tmp_objdir_create(the_repository, "remerge-diff"); if (!opt->remerge_objdir) return error(_("unable to create temporary object directory")); tmp_objdir_replace_primary_odb(opt->remerge_objdir, 1); diff --git a/log-tree.h b/log-tree.h index 94978e2c838ce9..ebe491c543cfab 100644 --- a/log-tree.h +++ b/log-tree.h @@ -33,6 +33,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit, int *need_8bit_cte_p, int maybe_multipart); void load_ref_decorations(struct decoration_filter *filter, int flags); +void load_branch_decorations(void); void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *); void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *); diff --git a/loose.c b/loose.c index 6d6a41b7e55a95..bb602aaa366bf7 100644 --- a/loose.c +++ b/loose.c @@ -1,10 +1,9 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "hash.h" #include "path.h" #include "object-store.h" #include "hex.h" +#include "repository.h" #include "wrapper.h" #include "gettext.h" #include "loose.h" @@ -76,7 +75,7 @@ static int load_one_loose_object_map(struct repository *repo, struct object_dire insert_loose_map(dir, repo->hash_algo->empty_blob, repo->compat_hash_algo->empty_blob); insert_loose_map(dir, repo->hash_algo->null_oid, repo->compat_hash_algo->null_oid); - strbuf_git_common_path(&path, repo, "objects/loose-object-idx"); + repo_common_path_replace(repo, &path, "objects/loose-object-idx"); fp = fopen(path.buf, "rb"); if (!fp) { strbuf_release(&path); @@ -134,7 +133,7 @@ int repo_write_loose_object_map(struct repository *repo) if (!should_use_loose_object_map(repo)) return 0; - strbuf_git_common_path(&path, repo, "objects/loose-object-idx"); + repo_common_path_replace(repo, &path, "objects/loose-object-idx"); fd = hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1); iter = kh_begin(map); if (write_in_full(fd, loose_object_header, strlen(loose_object_header)) < 0) @@ -142,8 +141,8 @@ int repo_write_loose_object_map(struct repository *repo) for (; iter != kh_end(map); iter++) { if (kh_exist(map, iter)) { - if (oideq(&kh_key(map, iter), the_hash_algo->empty_tree) || - oideq(&kh_key(map, iter), the_hash_algo->empty_blob)) + if (oideq(&kh_key(map, iter), repo->hash_algo->empty_tree) || + oideq(&kh_key(map, iter), repo->hash_algo->empty_blob)) continue; strbuf_addf(&buf, "%s %s\n", oid_to_hex(&kh_key(map, iter)), oid_to_hex(kh_value(map, iter))); if (write_in_full(fd, buf.buf, buf.len) < 0) @@ -175,7 +174,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid struct stat st; struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT; - strbuf_git_common_path(&path, repo, "objects/loose-object-idx"); + repo_common_path_replace(repo, &path, "objects/loose-object-idx"); hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1); fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666); @@ -191,7 +190,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid goto errout; if (close(fd)) goto errout; - adjust_shared_perm(path.buf); + adjust_shared_perm(repo, path.buf); rollback_lock_file(&lock); strbuf_release(&buf); strbuf_release(&path); diff --git a/ls-refs.c b/ls-refs.c index c824aea7146a3e..e28c841375861d 100644 --- a/ls-refs.c +++ b/ls-refs.c @@ -53,12 +53,10 @@ static enum { */ static int ref_match(const struct strvec *prefixes, const char *refname) { - int i; - if (!prefixes->nr) return 1; /* no restriction */ - for (i = 0; i < prefixes->nr; i++) { + for (size_t i = 0; i < prefixes->nr; i++) { const char *prefix = prefixes->v[i]; if (starts_with(refname, prefix)) diff --git a/mailinfo.c b/mailinfo.c index d1f42bd7e3e692..7b001fa5dbd685 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -1268,7 +1268,7 @@ static int git_mailinfo_config(const char *var, const char *value, return 0; } -void setup_mailinfo(struct mailinfo *mi) +void setup_mailinfo(struct repository *r, struct mailinfo *mi) { memset(mi, 0, sizeof(*mi)); strbuf_init(&mi->name, 0); @@ -1280,7 +1280,7 @@ void setup_mailinfo(struct mailinfo *mi) mi->header_stage = 1; mi->use_inbody_headers = 1; mi->content_top = mi->content; - git_config(git_mailinfo_config, mi); + repo_config(r, git_mailinfo_config, mi); } void clear_mailinfo(struct mailinfo *mi) diff --git a/mailinfo.h b/mailinfo.h index f2ffd0349e8007..1f2066416578ac 100644 --- a/mailinfo.h +++ b/mailinfo.h @@ -5,6 +5,8 @@ #define MAX_BOUNDARIES 5 +struct repository; + enum quoted_cr_action { quoted_cr_unset = -1, quoted_cr_nowarn, @@ -49,7 +51,7 @@ struct mailinfo { }; int mailinfo_parse_quoted_cr_action(const char *actionstr, int *action); -void setup_mailinfo(struct mailinfo *); +void setup_mailinfo(struct repository *r, struct mailinfo *); int mailinfo(struct mailinfo *, const char *msg, const char *patch); void clear_mailinfo(struct mailinfo *); diff --git a/mailmap.c b/mailmap.c index 9f9fa3199a85f8..f35d20ed7fd1ef 100644 --- a/mailmap.c +++ b/mailmap.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" diff --git a/match-trees.c b/match-trees.c index 147b03abf18f65..ef14ceb594c72a 100644 --- a/match-trees.c +++ b/match-trees.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "hex.h" @@ -7,6 +7,7 @@ #include "tree.h" #include "tree-walk.h" #include "object-store-ll.h" +#include "repository.h" static int score_missing(unsigned mode) { @@ -53,14 +54,15 @@ static int score_matches(unsigned mode1, unsigned mode2) return score; } -static void *fill_tree_desc_strict(struct tree_desc *desc, +static void *fill_tree_desc_strict(struct repository *r, + struct tree_desc *desc, const struct object_id *hash) { void *buffer; enum object_type type; unsigned long size; - buffer = repo_read_object_file(the_repository, hash, &type, &size); + buffer = repo_read_object_file(r, hash, &type, &size); if (!buffer) die("unable to read tree (%s)", oid_to_hex(hash)); if (type != OBJ_TREE) @@ -79,12 +81,13 @@ static int base_name_entries_compare(const struct name_entry *a, /* * Inspect two trees, and give a score that tells how similar they are. */ -static int score_trees(const struct object_id *hash1, const struct object_id *hash2) +static int score_trees(struct repository *r, + const struct object_id *hash1, const struct object_id *hash2) { struct tree_desc one; struct tree_desc two; - void *one_buf = fill_tree_desc_strict(&one, hash1); - void *two_buf = fill_tree_desc_strict(&two, hash2); + void *one_buf = fill_tree_desc_strict(r, &one, hash1); + void *two_buf = fill_tree_desc_strict(r, &two, hash2); int score = 0; for (;;) { @@ -132,7 +135,8 @@ static int score_trees(const struct object_id *hash1, const struct object_id *ha /* * Match one itself and its subtrees with two and pick the best match. */ -static void match_trees(const struct object_id *hash1, +static void match_trees(struct repository *r, + const struct object_id *hash1, const struct object_id *hash2, int *best_score, char **best_match, @@ -140,7 +144,7 @@ static void match_trees(const struct object_id *hash1, int recurse_limit) { struct tree_desc one; - void *one_buf = fill_tree_desc_strict(&one, hash1); + void *one_buf = fill_tree_desc_strict(r, &one, hash1); while (one.size) { const char *path; @@ -151,7 +155,7 @@ static void match_trees(const struct object_id *hash1, elem = tree_entry_extract(&one, &path, &mode); if (!S_ISDIR(mode)) goto next; - score = score_trees(elem, hash2); + score = score_trees(r, elem, hash2); if (*best_score < score) { free(*best_match); *best_match = xstrfmt("%s%s", base, path); @@ -159,7 +163,7 @@ static void match_trees(const struct object_id *hash1, } if (recurse_limit) { char *newbase = xstrfmt("%s%s/", base, path); - match_trees(elem, hash2, best_score, best_match, + match_trees(r, elem, hash2, best_score, best_match, newbase, recurse_limit - 1); free(newbase); } @@ -174,7 +178,8 @@ static void match_trees(const struct object_id *hash1, * A tree "oid1" has a subdirectory at "prefix". Come up with a tree object by * replacing it with another tree "oid2". */ -static int splice_tree(const struct object_id *oid1, const char *prefix, +static int splice_tree(struct repository *r, + const struct object_id *oid1, const char *prefix, const struct object_id *oid2, struct object_id *result) { char *subpath; @@ -193,7 +198,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix, if (*subpath) subpath++; - buf = repo_read_object_file(the_repository, oid1, &type, &sz); + buf = repo_read_object_file(r, oid1, &type, &sz); if (!buf) die("cannot read tree %s", oid_to_hex(oid1)); init_tree_desc(&desc, oid1, buf, sz); @@ -231,15 +236,15 @@ static int splice_tree(const struct object_id *oid1, const char *prefix, oid_to_hex(oid1)); if (*subpath) { struct object_id tree_oid; - oidread(&tree_oid, rewrite_here, the_repository->hash_algo); - status = splice_tree(&tree_oid, subpath, oid2, &subtree); + oidread(&tree_oid, rewrite_here, r->hash_algo); + status = splice_tree(r, &tree_oid, subpath, oid2, &subtree); if (status) return status; rewrite_with = &subtree; } else { rewrite_with = oid2; } - hashcpy(rewrite_here, rewrite_with->hash, the_repository->hash_algo); + hashcpy(rewrite_here, rewrite_with->hash, r->hash_algo); status = write_object_file(buf, sz, OBJ_TREE, result); free(buf); return status; @@ -270,7 +275,7 @@ void shift_tree(struct repository *r, if (!depth_limit) depth_limit = 2; - add_score = del_score = score_trees(hash1, hash2); + add_score = del_score = score_trees(r, hash1, hash2); add_prefix = xcalloc(1, 1); del_prefix = xcalloc(1, 1); @@ -278,13 +283,13 @@ void shift_tree(struct repository *r, * See if one's subtree resembles two; if so we need to prefix * two with a few fake trees to match the prefix. */ - match_trees(hash1, hash2, &add_score, &add_prefix, "", depth_limit); + match_trees(r, hash1, hash2, &add_score, &add_prefix, "", depth_limit); /* * See if two's subtree resembles one; if so we need to * pick only subtree of two. */ - match_trees(hash2, hash1, &del_score, &del_prefix, "", depth_limit); + match_trees(r, hash2, hash1, &del_score, &del_prefix, "", depth_limit); /* Assume we do not have to do any shifting */ oidcpy(shifted, hash2); @@ -305,7 +310,7 @@ void shift_tree(struct repository *r, if (!*add_prefix) goto out; - splice_tree(hash1, add_prefix, hash2, shifted); + splice_tree(r, hash1, add_prefix, hash2, shifted); out: free(add_prefix); @@ -339,16 +344,16 @@ void shift_tree_by(struct repository *r, if (candidate == 3) { /* Both are plausible -- we need to evaluate the score */ - int best_score = score_trees(hash1, hash2); + int best_score = score_trees(r, hash1, hash2); int score; candidate = 0; - score = score_trees(&sub1, hash2); + score = score_trees(r, &sub1, hash2); if (score > best_score) { candidate = 1; best_score = score; } - score = score_trees(&sub2, hash1); + score = score_trees(r, &sub2, hash1); if (score > best_score) candidate = 2; } @@ -364,7 +369,7 @@ void shift_tree_by(struct repository *r, * shift tree2 down by adding shift_prefix above it * to match tree1. */ - splice_tree(hash1, shift_prefix, hash2, shifted); + splice_tree(r, hash1, shift_prefix, hash2, shifted); else /* * shift tree2 up by removing shift_prefix from it diff --git a/mem-pool.c b/mem-pool.c index a3ba38831d94d6..62441dcc71968f 100644 --- a/mem-pool.c +++ b/mem-pool.c @@ -2,6 +2,8 @@ * Memory Pool implementation logic. */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "mem-pool.h" #include "gettext.h" diff --git a/merge-ll.c b/merge-ll.c index 8e63071922b41c..b2dc26da4fe92d 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -5,6 +5,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -15,6 +16,7 @@ #include "merge-ll.h" #include "quote.h" #include "strbuf.h" +#include "gettext.h" struct ll_merge_driver; @@ -427,7 +429,10 @@ enum ll_merge_result ll_merge(mmbuffer_t *result_buf, git_check_attr(istate, path, check); ll_driver_name = check->items[0].value; if (check->items[1].value) { - marker_size = atoi(check->items[1].value); + if (strtol_i(check->items[1].value, 10, &marker_size)) { + marker_size = DEFAULT_CONFLICT_MARKER_SIZE; + warning(_("invalid marker-size '%s', expecting an integer"), check->items[1].value); + } if (marker_size <= 0) marker_size = DEFAULT_CONFLICT_MARKER_SIZE; } @@ -454,7 +459,10 @@ int ll_merge_marker_size(struct index_state *istate, const char *path) check = attr_check_initl("conflict-marker-size", NULL); git_check_attr(istate, path, check); if (check->items[0].value) { - marker_size = atoi(check->items[0].value); + if (strtol_i(check->items[0].value, 10, &marker_size)) { + marker_size = DEFAULT_CONFLICT_MARKER_SIZE; + warning(_("invalid marker-size '%s', expecting an integer"), check->items[0].value); + } if (marker_size <= 0) marker_size = DEFAULT_CONFLICT_MARKER_SIZE; } diff --git a/merge-ort.c b/merge-ort.c index 8b81153e8fe0f5..46e78c3ffa68e6 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -15,6 +15,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "merge-ort.h" @@ -3536,7 +3537,7 @@ static int detect_and_process_renames(struct merge_options *opt) /* Free memory for renames->pairs[] and combined */ for (s = MERGE_SIDE1; s <= MERGE_SIDE2; s++) { free(renames->pairs[s].queue); - DIFF_QUEUE_CLEAR(&renames->pairs[s]); + diff_queue_init(&renames->pairs[s]); } for (i = 0; i < combined.nr; i++) pool_diff_free_filepair(&opt->priv->pool, combined.queue[i]); diff --git a/merge-recursive.c b/merge-recursive.c index ed64a4c537ca89..884ccf99a58d3b 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -5,6 +5,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "merge-recursive.h" @@ -2757,23 +2758,22 @@ static int process_renames(struct merge_options *opt, const struct rename *sre; /* - * FIXME: As string-list.h notes, it's O(n^2) to build a sorted - * string_list one-by-one, but O(n log n) to build it unsorted and - * then sort it. Note that as we build the list, we do not need to - * check if the existing destination path is already in the list, - * because the structure of diffcore_rename guarantees we won't - * have duplicates. + * Note that as we build the list, we do not need to check if the + * existing destination path is already in the list, because the + * structure of diffcore_rename guarantees we won't have duplicates. */ for (i = 0; i < a_renames->nr; i++) { sre = a_renames->items[i].util; - string_list_insert(&a_by_dst, sre->pair->two->path)->util + string_list_append(&a_by_dst, sre->pair->two->path)->util = (void *)sre; } for (i = 0; i < b_renames->nr; i++) { sre = b_renames->items[i].util; - string_list_insert(&b_by_dst, sre->pair->two->path)->util + string_list_append(&b_by_dst, sre->pair->two->path)->util = (void *)sre; } + string_list_sort(&a_by_dst); + string_list_sort(&b_by_dst); for (i = 0, j = 0; i < a_renames->nr || j < b_renames->nr;) { struct string_list *renames1, *renames2Dst; diff --git a/merge.c b/merge.c index fe3efa4b24b7d1..5ecaf508e4cb98 100644 --- a/merge.c +++ b/merge.c @@ -25,11 +25,11 @@ int try_merge_command(struct repository *r, const char *head_arg, struct commit_list *remotes) { struct child_process cmd = CHILD_PROCESS_INIT; - int i, ret; + int ret; struct commit_list *j; strvec_pushf(&cmd.args, "merge-%s", strategy); - for (i = 0; i < xopts_nr; i++) + for (size_t i = 0; i < xopts_nr; i++) strvec_pushf(&cmd.args, "--%s", xopts[i]); for (j = common; j; j = j->next) strvec_push(&cmd.args, merge_argument(j->item)); diff --git a/mergetools/vimdiff b/mergetools/vimdiff index f8ad6b35d4dbde..ffc9be86c83da1 100644 --- a/mergetools/vimdiff +++ b/mergetools/vimdiff @@ -411,7 +411,7 @@ merge_cmd () { -f "$FINAL_CMD" '"$LOCAL"' '"$BASE"' '"$REMOTE"' '"$MERGED"' else # If there is no BASE (example: a merge conflict in a new file - # with the same name created in both braches which didn't exist + # with the same name created in both branches which didn't exist # before), close all BASE windows using vim's "quit" command FINAL_CMD=$(echo "$FINAL_CMD" | \ diff --git a/meson.build b/meson.build new file mode 100644 index 00000000000000..fc0887438dec17 --- /dev/null +++ b/meson.build @@ -0,0 +1,2037 @@ +# Meson build system +# ================== +# +# The Meson build system is an alternative to our Makefile that you can use to +# build, test and install Git. Using Meson results in a couple of benefits: +# +# - Out-of-tree builds. +# - Better integration into IDEs. +# - Easy-to-use autoconfiguration of available features on your system. +# +# To use Meson from the command line you need to have both Meson and Ninja +# installed. Alternatively, if you do not have Python available on your system, +# you can also use Muon instead of Meson and Samurai instead of Ninja, both of +# which are drop-ins replacement that only depend on C. +# +# Basic usage +# =========== +# +# In the most trivial case, you can configure, build and install Git like this: +# +# 1. Set up the build directory. This only needs to happen once per build +# directory you want to have. You can also configure multiple different +# build directories with different configurations. +# +# $ meson setup build/ +# +# The build directory gets ignored by Git automatically as Meson will write +# a ".gitignore" file into it. From hereon, we will assume that you execute +# commands inside this build directory. +# +# 2. Compile Git. You can either use Meson, Ninja or Samurai to do this, so all +# of the following invocations are equivalent: +# +# $ meson compile +# $ ninja +# $ samu +# +# The different invocations should ultimately not make much of a difference. +# Using Meson also works with other generators though, like when the build +# directory has been set up for use with Microsoft Visual Studio. +# +# Ninja and Samurai use multiple jobs by default, scaling with the number of +# processor cores available. You can pass the `-jN` flag to change this. +# +# Meson automatically picks up ccache and sccache when these are installed +# when setting up the build directory. You can override this behaviour when +# setting up the build directory by setting the `CC` environment variable to +# your desired compiler. +# +# 3. Execute tests. Again, you can either use Meson, Ninja or Samurai to do this: +# +# $ meson test +# $ ninja test +# $ samu test +# +# It is recommended to use Meson in this case though as it also provides you +# additional features that the other build systems don't have available. +# You can e.g. pass additional arguments to the test executables or run +# individual tests: +# +# # Execute the t0000-basic integration test and t-reftable-stack unit test. +# $ meson test t0000-basic t-reftable-stack +# +# # Execute all reftable unit tests. +# $ meson test t-reftable-* +# +# # Execute all tests and stop with the first failure. +# $ meson test --maxfail 1 +# +# # Execute single test interactively such that features like `debug ()` work. +# $ meson test -i --test-args='-ix' t1400-update-ref +# +# Test execution is parallelized by default and scales with the number of +# processor cores available. You can change the number of processes by passing +# the `-jN` flag to `meson test`. +# +# 4. Install the Git distribution. Again, this can be done via Meson, Ninja or +# Samurai: +# +# $ meson install +# $ ninja install +# $ samu install +# +# The prefix into which Git shall be installed is defined when setting up +# the build directory. More on that in the "Configuration" section. +# +# Meson supports multiple backends. The default backend generates Ninja build +# instructions, but it also supports the generation of Microsoft Visual +# Studio solutions as well as Xcode projects by passing the `--backend` option +# to `meson setup`. IDEs like Eclipse and Visual Studio Code provide plugins to +# import Meson files directly. +# +# Configuration +# ============= +# +# The exact configuration of Git is determined when setting up the build +# directory via `meson setup`. Unless told otherwise, Meson will automatically +# detect the availability of various bits and pieces. There are two different +# kinds of options that can be used to further tweak the build: +# +# - Built-in options provided by Meson. +# +# - Options defined by the project in the "meson_options.txt" file. +# +# Both kinds of options can be inspected by running `meson configure` in the +# build directory, which will give you a list of the current value for all +# options. +# +# Options can be configured either when setting up the build directory or can +# be changed in preexisting build directories: +# +# # Set up a new build directory with optimized settings that will be +# # installed into an alternative prefix. +# $ meson setup --buildtype release --optimization 3 --strip --prefix=/home/$USER build +# +# # Set up a new build directory with a higher warning level. Level 2 is +# # mostly equivalent to setting DEVELOPER=1, level 3 and "everything" +# # will enable even more warnings. +# $ meson setup -Dwarning_level=2 build +# +# # Set up a new build directory with 'address' and 'undefined' sanitizers +# # using Clang. +# $ CC=clang meson setup -Db_sanitize=address,undefined build +# +# # Disable tests in a preexisting build directory. +# $ meson configure -Dtests=false +# +# # Disable features based on Python +# $ meson configure -Dpython=disabled +# +# Options have a type like booleans, choices, strings or features. Features are +# somewhat special as they can have one of three values: enabled, disabled or +# auto. While the first two values are self-explanatory, "auto" will enable or +# disable the feature based on the availability of prerequisites to support it. +# Python-based features for example will be enabled automatically when a Python +# interpreter could be found. The default value of such features can be changed +# via `meson setup --auto-features={enabled,disabled,auto}`, which will set the +# value of all features with a value of "auto" to the provided one by default. +# +# It is also possible to store a set of configuration options in machine files. +# This can be useful in case you regularly want to reuse the same set of options: +# +# [binaries] +# c = ['clang'] +# ar = ['ar'] +# +# [project options] +# gettext = 'disabled' +# default_editor = 'vim' +# +# [built-in options] +# b_lto = true +# b_sanitize = 'address,undefined' +# +# These machine files can be passed to `meson setup` via the `--native-file` +# option. +# +# Subproject wrappers +# =================== +# +# Subproject wrappers are a feature provided by Meson that allows the automatic +# fallback to a "wrapped" dependency in case the dependency is not provided by +# the system. For example if the system is lacking curl, then Meson will use +# "subprojects/curl.wrap" to set up curl as a subproject and compile and link +# the dependency into Git itself. This is especially helpful on systems like +# Windows, where you typically don't have such dependencies installed. +# +# The use of subproject wrappers can be disabled by executing `meson setup` +# with the `--wrap-mode nofallback` option. + +project('git', 'c', + meson_version: '>=0.61.0', + # The version is only of cosmetic nature, so if we cannot find a shell yet we + # simply don't set up a version at all. This may be the case for example on + # Windows systems, where we first have to bootstrap the host environment. + version: find_program('sh', required: false).found() ? run_command( + 'GIT-VERSION-GEN', meson.current_source_dir(), '--format=@GIT_VERSION@', + capture: true, + check: true, + ).stdout().strip() : 'unknown', + default_options: [ + # Git requires C99 with GNU extensions, which of course isn't supported by + # MSVC. Funny enough, C99 doesn't work with MSVC either, as it has only + # learned to define __STDC_VERSION__ with C11 and later. We thus require + # GNU C99 and fall back to C11. Meson only learned to handle the fallback + # with version 1.3.0, so on older versions we use GNU C99 unconditionally. + 'c_std=' + (meson.version().version_compare('>=1.3.0') ? 'gnu99,c11' : 'gnu99'), + ], +) + +fs = import('fs') + +program_path = [] +if get_option('sane_tool_path').length() != 0 + program_path = get_option('sane_tool_path') +elif host_machine.system() == 'windows' + # Git for Windows provides all the tools we need to build Git. + program_path = [ 'C:/Program Files/Git/bin', 'C:/Program Files/Git/usr/bin' ] +endif + +cygpath = find_program('cygpath', dirs: program_path, required: false) +diff = find_program('diff', dirs: program_path) +git = find_program('git', dirs: program_path, required: false) +sed = find_program('sed', dirs: program_path) +shell = find_program('sh', dirs: program_path) +tar = find_program('tar', dirs: program_path) + +# Sanity-check that programs required for the build exist. +foreach tool : ['cat', 'cut', 'grep', 'sort', 'tr', 'uname'] + find_program(tool, dirs: program_path) +endforeach + +script_environment = environment() +foreach path : program_path + script_environment.prepend('PATH', path) +endforeach + +# The environment used by GIT-VERSION-GEN. Note that we explicitly override +# environment variables that might be set by the user. This is by design so +# that we always use whatever Meson has configured instead of what is present +# in the environment. +version_gen_environment = script_environment +version_gen_environment.set('GIT_BUILT_FROM_COMMIT', get_option('built_from_commit')) +version_gen_environment.set('GIT_DATE', get_option('build_date')) +version_gen_environment.set('GIT_USER_AGENT', get_option('user_agent')) +version_gen_environment.set('GIT_VERSION', get_option('version')) + +compiler = meson.get_compiler('c') + +libgit_sources = [ + 'abspath.c', + 'add-interactive.c', + 'add-patch.c', + 'advice.c', + 'alias.c', + 'alloc.c', + 'apply.c', + 'archive-tar.c', + 'archive-zip.c', + 'archive.c', + 'attr.c', + 'base85.c', + 'bisect.c', + 'blame.c', + 'blob.c', + 'bloom.c', + 'branch.c', + 'bulk-checkin.c', + 'bundle-uri.c', + 'bundle.c', + 'cache-tree.c', + 'cbtree.c', + 'chdir-notify.c', + 'checkout.c', + 'chunk-format.c', + 'color.c', + 'column.c', + 'combine-diff.c', + 'commit-graph.c', + 'commit-reach.c', + 'commit.c', + 'common-exit.c', + 'common-init.c', + 'compat/nonblock.c', + 'compat/obstack.c', + 'compat/terminal.c', + 'config.c', + 'connect.c', + 'connected.c', + 'convert.c', + 'copy.c', + 'credential.c', + 'csum-file.c', + 'ctype.c', + 'date.c', + 'decorate.c', + 'delta-islands.c', + 'diagnose.c', + 'diff-delta.c', + 'diff-merges.c', + 'diff-lib.c', + 'diff-no-index.c', + 'diff.c', + 'diffcore-break.c', + 'diffcore-delta.c', + 'diffcore-order.c', + 'diffcore-pickaxe.c', + 'diffcore-rename.c', + 'diffcore-rotate.c', + 'dir-iterator.c', + 'dir.c', + 'editor.c', + 'entry.c', + 'environment.c', + 'ewah/bitmap.c', + 'ewah/ewah_bitmap.c', + 'ewah/ewah_io.c', + 'ewah/ewah_rlw.c', + 'exec-cmd.c', + 'fetch-negotiator.c', + 'fetch-pack.c', + 'fmt-merge-msg.c', + 'fsck.c', + 'fsmonitor.c', + 'fsmonitor-ipc.c', + 'fsmonitor-settings.c', + 'gettext.c', + 'git-zlib.c', + 'gpg-interface.c', + 'graph.c', + 'grep.c', + 'hash-lookup.c', + 'hashmap.c', + 'help.c', + 'hex.c', + 'hex-ll.c', + 'hook.c', + 'ident.c', + 'json-writer.c', + 'kwset.c', + 'levenshtein.c', + 'line-log.c', + 'line-range.c', + 'linear-assignment.c', + 'list-objects-filter-options.c', + 'list-objects-filter.c', + 'list-objects.c', + 'lockfile.c', + 'log-tree.c', + 'loose.c', + 'ls-refs.c', + 'mailinfo.c', + 'mailmap.c', + 'match-trees.c', + 'mem-pool.c', + 'merge-blobs.c', + 'merge-ll.c', + 'merge-ort.c', + 'merge-ort-wrappers.c', + 'merge-recursive.c', + 'merge.c', + 'midx.c', + 'midx-write.c', + 'name-hash.c', + 'negotiator/default.c', + 'negotiator/noop.c', + 'negotiator/skipping.c', + 'notes-cache.c', + 'notes-merge.c', + 'notes-utils.c', + 'notes.c', + 'object-file-convert.c', + 'object-file.c', + 'object-name.c', + 'object.c', + 'oid-array.c', + 'oidmap.c', + 'oidset.c', + 'oidtree.c', + 'pack-bitmap-write.c', + 'pack-bitmap.c', + 'pack-check.c', + 'pack-mtimes.c', + 'pack-objects.c', + 'pack-revindex.c', + 'pack-write.c', + 'packfile.c', + 'pager.c', + 'parallel-checkout.c', + 'parse.c', + 'parse-options-cb.c', + 'parse-options.c', + 'patch-delta.c', + 'patch-ids.c', + 'path.c', + 'path-walk.c', + 'pathspec.c', + 'pkt-line.c', + 'preload-index.c', + 'pretty.c', + 'prio-queue.c', + 'progress.c', + 'promisor-remote.c', + 'prompt.c', + 'protocol.c', + 'protocol-caps.c', + 'prune-packed.c', + 'pseudo-merge.c', + 'quote.c', + 'range-diff.c', + 'reachable.c', + 'read-cache.c', + 'rebase-interactive.c', + 'rebase.c', + 'ref-filter.c', + 'reflog-walk.c', + 'reflog.c', + 'refs.c', + 'refs/debug.c', + 'refs/files-backend.c', + 'refs/reftable-backend.c', + 'refs/iterator.c', + 'refs/packed-backend.c', + 'refs/ref-cache.c', + 'refspec.c', + 'reftable/basics.c', + 'reftable/error.c', + 'reftable/block.c', + 'reftable/blocksource.c', + 'reftable/iter.c', + 'reftable/merged.c', + 'reftable/pq.c', + 'reftable/reader.c', + 'reftable/record.c', + 'reftable/stack.c', + 'reftable/system.c', + 'reftable/tree.c', + 'reftable/writer.c', + 'remote.c', + 'replace-object.c', + 'repo-settings.c', + 'repository.c', + 'rerere.c', + 'reset.c', + 'resolve-undo.c', + 'revision.c', + 'run-command.c', + 'send-pack.c', + 'sequencer.c', + 'serve.c', + 'server-info.c', + 'setup.c', + 'shallow.c', + 'sideband.c', + 'sigchain.c', + 'sparse-index.c', + 'split-index.c', + 'stable-qsort.c', + 'statinfo.c', + 'strbuf.c', + 'streaming.c', + 'string-list.c', + 'strmap.c', + 'strvec.c', + 'sub-process.c', + 'submodule-config.c', + 'submodule.c', + 'symlinks.c', + 'tag.c', + 'tempfile.c', + 'thread-utils.c', + 'tmp-objdir.c', + 'trace.c', + 'trace2.c', + 'trace2/tr2_cfg.c', + 'trace2/tr2_cmd_name.c', + 'trace2/tr2_ctr.c', + 'trace2/tr2_dst.c', + 'trace2/tr2_sid.c', + 'trace2/tr2_sysenv.c', + 'trace2/tr2_tbuf.c', + 'trace2/tr2_tgt_event.c', + 'trace2/tr2_tgt_normal.c', + 'trace2/tr2_tgt_perf.c', + 'trace2/tr2_tls.c', + 'trace2/tr2_tmr.c', + 'trailer.c', + 'transport-helper.c', + 'transport.c', + 'tree-diff.c', + 'tree-walk.c', + 'tree.c', + 'unpack-trees.c', + 'upload-pack.c', + 'url.c', + 'urlmatch.c', + 'usage.c', + 'userdiff.c', + 'utf8.c', + 'varint.c', + 'version.c', + 'versioncmp.c', + 'walker.c', + 'wildmatch.c', + 'worktree.c', + 'wrapper.c', + 'write-or-die.c', + 'ws.c', + 'wt-status.c', + 'xdiff-interface.c', + 'xdiff/xdiffi.c', + 'xdiff/xemit.c', + 'xdiff/xhistogram.c', + 'xdiff/xmerge.c', + 'xdiff/xpatience.c', + 'xdiff/xprepare.c', + 'xdiff/xutils.c', +] + +libgit_sources += custom_target( + input: 'command-list.txt', + output: 'command-list.h', + command: [shell, meson.current_source_dir() + '/generate-cmdlist.sh', meson.current_source_dir(), '@OUTPUT@'], + env: script_environment, +) + +builtin_sources = [ + 'builtin/add.c', + 'builtin/am.c', + 'builtin/annotate.c', + 'builtin/apply.c', + 'builtin/archive.c', + 'builtin/backfill.c', + 'builtin/bisect.c', + 'builtin/blame.c', + 'builtin/branch.c', + 'builtin/bugreport.c', + 'builtin/bundle.c', + 'builtin/cat-file.c', + 'builtin/check-attr.c', + 'builtin/check-ignore.c', + 'builtin/check-mailmap.c', + 'builtin/check-ref-format.c', + 'builtin/checkout--worker.c', + 'builtin/checkout-index.c', + 'builtin/checkout.c', + 'builtin/clean.c', + 'builtin/clone.c', + 'builtin/column.c', + 'builtin/commit-graph.c', + 'builtin/commit-tree.c', + 'builtin/commit.c', + 'builtin/config.c', + 'builtin/count-objects.c', + 'builtin/credential-cache--daemon.c', + 'builtin/credential-cache.c', + 'builtin/credential-store.c', + 'builtin/credential.c', + 'builtin/describe.c', + 'builtin/diagnose.c', + 'builtin/diff-files.c', + 'builtin/diff-index.c', + 'builtin/diff-tree.c', + 'builtin/diff.c', + 'builtin/difftool.c', + 'builtin/fast-export.c', + 'builtin/fast-import.c', + 'builtin/fetch-pack.c', + 'builtin/fetch.c', + 'builtin/fmt-merge-msg.c', + 'builtin/for-each-ref.c', + 'builtin/for-each-repo.c', + 'builtin/fsck.c', + 'builtin/fsmonitor--daemon.c', + 'builtin/gc.c', + 'builtin/get-tar-commit-id.c', + 'builtin/grep.c', + 'builtin/hash-object.c', + 'builtin/help.c', + 'builtin/hook.c', + 'builtin/index-pack.c', + 'builtin/init-db.c', + 'builtin/interpret-trailers.c', + 'builtin/log.c', + 'builtin/ls-files.c', + 'builtin/ls-remote.c', + 'builtin/ls-tree.c', + 'builtin/mailinfo.c', + 'builtin/mailsplit.c', + 'builtin/merge-base.c', + 'builtin/merge-file.c', + 'builtin/merge-index.c', + 'builtin/merge-ours.c', + 'builtin/merge-recursive.c', + 'builtin/merge-tree.c', + 'builtin/merge.c', + 'builtin/mktag.c', + 'builtin/mktree.c', + 'builtin/multi-pack-index.c', + 'builtin/mv.c', + 'builtin/name-rev.c', + 'builtin/notes.c', + 'builtin/pack-objects.c', + 'builtin/pack-redundant.c', + 'builtin/pack-refs.c', + 'builtin/patch-id.c', + 'builtin/prune-packed.c', + 'builtin/prune.c', + 'builtin/pull.c', + 'builtin/push.c', + 'builtin/range-diff.c', + 'builtin/read-tree.c', + 'builtin/rebase.c', + 'builtin/receive-pack.c', + 'builtin/reflog.c', + 'builtin/refs.c', + 'builtin/remote-ext.c', + 'builtin/remote-fd.c', + 'builtin/remote.c', + 'builtin/repack.c', + 'builtin/replace.c', + 'builtin/replay.c', + 'builtin/rerere.c', + 'builtin/reset.c', + 'builtin/rev-list.c', + 'builtin/rev-parse.c', + 'builtin/revert.c', + 'builtin/rm.c', + 'builtin/send-pack.c', + 'builtin/shortlog.c', + 'builtin/show-branch.c', + 'builtin/show-index.c', + 'builtin/show-ref.c', + 'builtin/sparse-checkout.c', + 'builtin/stash.c', + 'builtin/stripspace.c', + 'builtin/submodule--helper.c', + 'builtin/survey.c', + 'builtin/symbolic-ref.c', + 'builtin/tag.c', + 'builtin/unpack-file.c', + 'builtin/unpack-objects.c', + 'builtin/update-index.c', + 'builtin/update-ref.c', + 'builtin/update-server-info.c', + 'builtin/upload-archive.c', + 'builtin/upload-pack.c', + 'builtin/var.c', + 'builtin/verify-commit.c', + 'builtin/verify-pack.c', + 'builtin/verify-tag.c', + 'builtin/worktree.c', + 'builtin/write-tree.c', +] + +builtin_sources += custom_target( + output: 'config-list.h', + command: [ + shell, + meson.current_source_dir() + '/generate-configlist.sh', + meson.current_source_dir(), + '@OUTPUT@', + ], + env: script_environment, +) + +builtin_sources += custom_target( + input: 'Documentation/githooks.adoc', + output: 'hook-list.h', + command: [ + shell, + meson.current_source_dir() + '/generate-hooklist.sh', + meson.current_source_dir(), + '@OUTPUT@', + ], + env: script_environment, +) + +# This contains the variables for GIT-BUILD-OPTIONS, which we use to propagate +# build options to our tests. +build_options_config = configuration_data() +build_options_config.set('GIT_INTEROP_MAKE_OPTS', '') +build_options_config.set('GIT_PERF_LARGE_REPO', '') +build_options_config.set('GIT_PERF_MAKE_COMMAND', '') +build_options_config.set('GIT_PERF_MAKE_OPTS', '') +build_options_config.set('GIT_PERF_REPEAT_COUNT', '') +build_options_config.set('GIT_PERF_REPO', '') +build_options_config.set('GIT_TEST_CMP_USE_COPIED_CONTEXT', '') +build_options_config.set('GIT_TEST_INDEX_VERSION', '') +build_options_config.set('GIT_TEST_OPTS', '') +build_options_config.set('GIT_TEST_PERL_FATAL_WARNINGS', '') +build_options_config.set_quoted('GIT_TEST_UTF8_LOCALE', get_option('test_utf8_locale')) +build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) +build_options_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb')) + +if get_option('breaking_changes') + build_options_config.set('WITH_BREAKING_CHANGES', 'YesPlease') +else + build_options_config.set('WITH_BREAKING_CHANGES', '') +endif + +if get_option('sane_tool_path').length() != 0 + sane_tool_path = (host_machine.system() == 'windows' ? ';' : ':').join(get_option('sane_tool_path')) + build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + sane_tool_path + '"|') +else + build_options_config.set_quoted('BROKEN_PATH_FIX', '/^\# @BROKEN_PATH_FIX@$/d') +endif + +test_output_directory = get_option('test_output_directory') +if test_output_directory == '' + test_output_directory = meson.project_build_root() / 'test-output' +endif + +# These variables are used for building libgit.a. +libgit_c_args = [ + '-DBINDIR="' + get_option('bindir') + '"', + '-DDEFAULT_EDITOR="' + get_option('default_editor') + '"', + '-DDEFAULT_GIT_TEMPLATE_DIR="' + get_option('datadir') / 'git-core/templates' + '"', + '-DDEFAULT_HELP_FORMAT="' + get_option('default_help_format') + '"', + '-DDEFAULT_PAGER="' + get_option('default_pager') + '"', + '-DETC_GITATTRIBUTES="' + get_option('gitattributes') + '"', + '-DETC_GITCONFIG="' + get_option('gitconfig') + '"', + '-DFALLBACK_RUNTIME_PREFIX="' + get_option('prefix') + '"', + '-DGIT_HOST_CPU="' + host_machine.cpu_family() + '"', + '-DGIT_HTML_PATH="' + get_option('datadir') / 'doc/git-doc"', + '-DGIT_INFO_PATH="' + get_option('infodir') + '"', + '-DGIT_LOCALE_PATH="' + get_option('localedir') + '"', + '-DGIT_MAN_PATH="' + get_option('mandir') + '"', + '-DPAGER_ENV="' + get_option('pager_environment') + '"', + '-DSHELL_PATH="' + fs.as_posix(shell.full_path()) + '"', +] +libgit_include_directories = [ '.' ] +libgit_dependencies = [ ] + +# Treat any warning level above 1 the same as we treat DEVELOPER=1 in our +# Makefile. +if get_option('warning_level') in ['2','3', 'everything'] and compiler.get_argument_syntax() == 'gcc' + foreach cflag : [ + '-Wdeclaration-after-statement', + '-Wformat-security', + '-Wold-style-definition', + '-Woverflow', + '-Wpointer-arith', + '-Wstrict-prototypes', + '-Wunused', + '-Wvla', + '-Wwrite-strings', + '-fno-common', + '-Wtautological-constant-out-of-range-compare', + # If a function is public, there should be a prototype and the right + # header file should be included. If not, it should be static. + '-Wmissing-prototypes', + # These are disabled because we have these all over the place. + '-Wno-empty-body', + '-Wno-missing-field-initializers', + ] + if compiler.has_argument(cflag) + libgit_c_args += cflag + endif + endforeach +endif + +if get_option('b_sanitize').contains('address') + build_options_config.set('SANITIZE_ADDRESS', 'YesCompiledWithIt') +else + build_options_config.set('SANITIZE_ADDRESS', '') +endif +if get_option('b_sanitize').contains('leak') + build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt') +else + build_options_config.set('SANITIZE_LEAK', '') +endif +if get_option('b_sanitize').contains('undefined') + libgit_c_args += '-DSHA1DC_FORCE_ALIGNED_ACCESS' +endif + +executable_suffix = '' +if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' + executable_suffix = '.exe' + libgit_c_args += '-DSTRIP_EXTENSION="' + executable_suffix + '"' +endif +build_options_config.set_quoted('X', executable_suffix) + +python = import('python').find_installation('python3', required: get_option('python')) +if python.found() + build_options_config.set('NO_PYTHON', '') +else + libgit_c_args += '-DNO_PYTHON' + build_options_config.set('NO_PYTHON', '1') +endif + +# Perl is used for two different things: our test harness and to provide some +# features. It is optional if you want to neither execute tests nor use any of +# these optional features. +perl_required = get_option('perl') +if get_option('tests') or get_option('gitweb').enabled() or 'netrc' in get_option('credential_helpers') + perl_required = true +endif + +# Note that we only set NO_PERL if the Perl features were disabled by the user. +# It may not be set when we have found Perl, but only use it to run tests. +# +# At the time of writing, executing `perl --version` results in a string +# similar to the following output: +# +# This is perl 5, version 40, subversion 0 (v5.40.0) built for x86_64-linux-thread-multi +# +# Meson picks up the "40" as version number instead of using "v5.40.0" +# due to the regular expression it uses. This got fixed in Meson 1.7.0, +# but meanwhile we have to either use `-V:version` instead of `--version`, +# which we can do starting with Meson 1.5.0 and newer, or we have to +# match against the minor version. +if meson.version().version_compare('>=1.5.0') + perl = find_program('perl', dirs: program_path, required: perl_required, version: '>=5.26.0', version_argument: '-V:version') +else + perl = find_program('perl', dirs: program_path, required: perl_required, version: '>=26') +endif +perl_features_enabled = perl.found() and get_option('perl').allowed() +if perl_features_enabled + build_options_config.set('NO_PERL', '') + + if get_option('runtime_prefix') + build_options_config.set('PERL_LOCALEDIR', '') + else + build_options_config.set_quoted('PERL_LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) + endif + + if get_option('perl_cpan_fallback') + build_options_config.set('NO_PERL_CPAN_FALLBACKS', '') + else + build_options_config.set_quoted('NO_PERL_CPAN_FALLBACKS', 'YesPlease') + endif +else + libgit_c_args += '-DNO_PERL' + build_options_config.set('NO_PERL', '1') + build_options_config.set('PERL_LOCALEDIR', '') + build_options_config.set('NO_PERL_CPAN_FALLBACKS', '') +endif + +zlib_backend = get_option('zlib_backend') +if zlib_backend in ['auto', 'zlib-ng'] + zlib_ng = dependency('zlib-ng', required: zlib_backend == 'zlib-ng') + if zlib_ng.found() + zlib_backend = 'zlib-ng' + libgit_c_args += '-DHAVE_ZLIB_NG' + libgit_dependencies += zlib_ng + endif +endif +if zlib_backend in ['auto', 'zlib'] + zlib = dependency('zlib', default_options: ['default_library=static', 'tests=disabled']) + if zlib.version().version_compare('<1.2.0') + libgit_c_args += '-DNO_DEFLATE_BOUND' + endif + zlib_backend = 'zlib' + libgit_dependencies += zlib +endif + +threads = dependency('threads', required: false) +if threads.found() + libgit_dependencies += threads + build_options_config.set('NO_PTHREADS', '') +else + libgit_c_args += '-DNO_PTHREADS' + build_options_config.set('NO_PTHREADS', '1') +endif + +msgfmt = find_program('msgfmt', dirs: program_path, required: false) +gettext_option = get_option('gettext').disable_auto_if(not msgfmt.found()) +if not msgfmt.found() and gettext_option.enabled() + error('Internationalization via libintl requires msgfmt') +endif + +if gettext_option.allowed() and host_machine.system() == 'darwin' and get_option('macos_use_homebrew_gettext') + if host_machine.cpu_family() == 'x86_64' + libintl_prefix = '/usr/local' + elif host_machine.cpu_family() == 'aarch64' + libintl_prefix = '/opt/homebrew' + else + error('Homebrew workaround not supported on current architecture') + endif + + intl = compiler.find_library('intl', dirs: libintl_prefix / 'lib', required: gettext_option) + if intl.found() + intl = declare_dependency( + dependencies: intl, + include_directories: libintl_prefix / 'include', + ) + endif +else + intl = dependency('intl', required: gettext_option) +endif +if intl.found() + libgit_dependencies += intl + build_options_config.set('NO_GETTEXT', '') + build_options_config.set('USE_GETTEXT_SCHEME', '') + + # POSIX nowadays requires `nl_langinfo()`, but some systems still don't have + # the function available. On such systems we instead fall back to libcharset. + # On native Windows systems we use our own emulation. + if host_machine.system() != 'windows' and not compiler.has_function('nl_langinfo') + libcharset = compiler.find_library('charset', required: true) + libgit_dependencies += libcharset + libgit_c_args += '-DHAVE_LIBCHARSET_H' + endif +else + libgit_c_args += '-DNO_GETTEXT' + build_options_config.set('NO_GETTEXT', '1') + build_options_config.set('USE_GETTEXT_SCHEME', 'fallthrough') +endif + +iconv = dependency('iconv', required: get_option('iconv')) +if iconv.found() + libgit_dependencies += iconv + build_options_config.set('NO_ICONV', '') + + have_old_iconv = false + if not compiler.compiles(''' + #include <iconv.h> + + extern size_t iconv(iconv_t cd, + char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); + ''', name: 'old iconv interface', dependencies: [iconv]) + libgit_c_args += '-DOLD_ICONV' + have_old_iconv = true + endif + + iconv_omits_bom_source = '''# + #include <iconv.h> + + int main(int argc, const char **argv) + { + ''' + if have_old_iconv + iconv_omits_bom_source += ''' + typedef const char *iconv_ibp; + ''' + else + iconv_omits_bom_source += ''' + typedef char *iconv_ibp; + ''' + endif + iconv_omits_bom_source += ''' + int v; + iconv_t conv; + char in[] = "a"; iconv_ibp pin = in; + char out[20] = ""; char *pout = out; + size_t isz = sizeof in; + size_t osz = sizeof out; + + conv = iconv_open("UTF-16", "UTF-8"); + iconv(conv, &pin, &isz, &pout, &osz); + iconv_close(conv); + v = (unsigned char)(out[0]) + (unsigned char)(out[1]); + return v != 0xfe + 0xff; + } + ''' + + if compiler.run(iconv_omits_bom_source, + dependencies: iconv, + name: 'iconv omits BOM', + ).returncode() != 0 + libgit_c_args += '-DICONV_OMITS_BOM' + endif +else + libgit_c_args += '-DNO_ICONV' + build_options_config.set('NO_ICONV', '1') +endif + +pcre2 = dependency('libpcre2-8', required: get_option('pcre2'), default_options: ['default_library=static', 'test=false']) +if pcre2.found() + libgit_dependencies += pcre2 + libgit_c_args += '-DUSE_LIBPCRE2' + build_options_config.set('USE_LIBPCRE2', '1') +else + build_options_config.set('USE_LIBPCRE2', '') +endif + +curl = dependency('libcurl', version: '>=7.21.3', required: get_option('curl'), default_options: ['default_library=static', 'tests=disabled', 'tool=disabled']) +use_curl_for_imap_send = false +if curl.found() + if curl.version().version_compare('>=7.34.0') + libgit_c_args += '-DUSE_CURL_FOR_IMAP_SEND' + use_curl_for_imap_send = true + endif + + # Most executables don't have to link against libcurl, but we still need its + # include directories so that we can resolve LIBCURL_VERSION in "help.c". + libgit_dependencies += curl.partial_dependency(includes: true) + libgit_c_args += '-DCURL_DISABLE_TYPECHECK' + build_options_config.set('NO_CURL', '') +else + libgit_c_args += '-DNO_CURL' + build_options_config.set('NO_CURL', '1') +endif + +expat = dependency('expat', required: get_option('expat'), default_options: ['default_library=static', 'build_tests=false']) +if expat.found() + libgit_dependencies += expat + + if expat.version().version_compare('<=1.2') + libgit_c_args += '-DEXPAT_NEEDS_XMLPARSE_H' + endif + build_options_config.set('NO_EXPAT', '') +else + libgit_c_args += '-DNO_EXPAT' + build_options_config.set('NO_EXPAT', '1') +endif + +if not compiler.has_header('sys/select.h') + libgit_c_args += '-DNO_SYS_SELECT_H' +endif + +has_poll_h = compiler.has_header('poll.h') +if not has_poll_h + libgit_c_args += '-DNO_POLL_H' +endif + +has_sys_poll_h = compiler.has_header('sys/poll.h') +if not has_sys_poll_h + libgit_c_args += '-DNO_SYS_POLL_H' +endif + +if not has_poll_h and not has_sys_poll_h + libgit_c_args += '-DNO_POLL' + libgit_sources += 'compat/poll/poll.c' + libgit_include_directories += 'compat/poll' +endif + +if not compiler.has_header('inttypes.h') + libgit_c_args += '-DNO_INTTYPES_H' +endif + +if compiler.has_header('alloca.h') + libgit_c_args += '-DHAVE_ALLOCA_H' +endif + +if compiler.has_header('sys/sysinfo.h') + libgit_c_args += '-DHAVE_SYSINFO' +endif + +# Windows has libgen.h and a basename implementation, but we still need our own +# implementation to threat things like drive prefixes specially. +if host_machine.system() == 'windows' or not compiler.has_header('libgen.h') + libgit_c_args += '-DNO_LIBGEN_H' + libgit_sources += 'compat/basename.c' +endif + +if compiler.has_header('paths.h') + libgit_c_args += '-DHAVE_PATHS_H' +endif + +if compiler.has_header('strings.h') + libgit_c_args += '-DHAVE_STRINGS_H' +endif + +networking_dependencies = [ ] +if host_machine.system() == 'windows' + winsock = compiler.find_library('ws2_32', required: false) + if winsock.found() + networking_dependencies += winsock + endif +else + libresolv = compiler.find_library('resolv', required: false) + if libresolv.found() + networking_dependencies += libresolv + endif +endif +libgit_dependencies += networking_dependencies + +foreach symbol : ['inet_ntop', 'inet_pton', 'strerror'] + if not compiler.has_function(symbol, dependencies: networking_dependencies) + libgit_c_args += '-DNO_' + symbol.to_upper() + endif +endforeach + +has_ipv6 = compiler.has_function('getaddrinfo', dependencies: networking_dependencies) +if not has_ipv6 + libgit_c_args += '-DNO_IPV6' +endif + +if not compiler.compiles(''' + #ifdef _WIN32 + # include <winsock2.h> + #else + # include <sys/types.h> + # include <sys/socket.h> + #endif + + void func(void) + { + struct sockaddr_storage x; + } +''', name: 'struct sockaddr_storage') + if has_ipv6 + libgit_c_args += '-Dsockaddr_storage=sockaddr_in6' + else + libgit_c_args += '-Dsockaddr_storage=sockaddr_in' + endif +endif + +if compiler.has_function('socket', dependencies: networking_dependencies) + libgit_sources += [ + 'unix-socket.c', + 'unix-stream-server.c', + ] + build_options_config.set('NO_UNIX_SOCKETS', '') +else + libgit_c_args += '-DNO_UNIX_SOCKETS' + build_options_config.set('NO_UNIX_SOCKETS', '1') +endif + +if not compiler.has_function('pread') + libgit_c_args += '-DNO_PREAD' + libgit_sources += 'compat/pread.c' +endif + +if host_machine.system() == 'darwin' + libgit_sources += 'compat/precompose_utf8.c' + libgit_c_args += '-DPRECOMPOSE_UNICODE' + libgit_c_args += '-DPROTECT_HFS_DEFAULT' +endif + +# Configure general compatibility wrappers. +if host_machine.system() == 'cygwin' + libgit_sources += [ + 'compat/win32/path-utils.c', + ] +elif host_machine.system() == 'windows' + libgit_sources += [ + 'compat/mingw.c', + 'compat/winansi.c', + 'compat/win32/dirent.c', + 'compat/win32/flush.c', + 'compat/win32/path-utils.c', + 'compat/win32/pthread.c', + 'compat/win32/syslog.c', + 'compat/win32mmap.c', + 'compat/nedmalloc/nedmalloc.c', + ] + + libgit_c_args += [ + '-DDETECT_MSYS_TTY', + '-DENSURE_MSYSTEM_IS_SET', + '-DNATIVE_CRLF', + '-DNOGDI', + '-DNO_POSIX_GOODIES', + '-DWIN32', + '-D_CONSOLE', + '-D_CONSOLE_DETECT_MSYS_TTY', + '-D__USE_MINGW_ANSI_STDIO=0', + ] + + libgit_dependencies += compiler.find_library('ntdll') + libgit_include_directories += 'compat/win32' + if compiler.get_id() == 'msvc' + libgit_include_directories += 'compat/vcbuild/include' + endif +endif + +if host_machine.system() == 'linux' + libgit_sources += 'compat/linux/procinfo.c' +elif host_machine.system() == 'windows' + libgit_sources += 'compat/win32/trace2_win32_process_info.c' +else + libgit_sources += 'compat/stub/procinfo.c' +endif + +if host_machine.system() == 'cygwin' or host_machine.system() == 'windows' + libgit_c_args += [ + '-DUNRELIABLE_FSTAT', + '-DMMAP_PREVENTS_DELETE', + '-DOBJECT_CREATION_MODE=1', + ] +endif + +# Configure the simple-ipc subsystem required fro the fsmonitor. +if host_machine.system() == 'windows' + libgit_sources += [ + 'compat/simple-ipc/ipc-shared.c', + 'compat/simple-ipc/ipc-win32.c', + ] + libgit_c_args += '-DSUPPORTS_SIMPLE_IPC' +else + libgit_sources += [ + 'compat/simple-ipc/ipc-shared.c', + 'compat/simple-ipc/ipc-unix-socket.c', + ] + libgit_c_args += '-DSUPPORTS_SIMPLE_IPC' +endif + +fsmonitor_backend = '' +if host_machine.system() == 'windows' + fsmonitor_backend = 'win32' +elif host_machine.system() == 'darwin' + fsmonitor_backend = 'darwin' + libgit_dependencies += dependency('CoreServices') +endif +if fsmonitor_backend != '' + libgit_c_args += '-DHAVE_FSMONITOR_DAEMON_BACKEND' + libgit_c_args += '-DHAVE_FSMONITOR_OS_SETTINGS' + + libgit_sources += [ + 'compat/fsmonitor/fsm-health-' + fsmonitor_backend + '.c', + 'compat/fsmonitor/fsm-ipc-' + fsmonitor_backend + '.c', + 'compat/fsmonitor/fsm-listen-' + fsmonitor_backend + '.c', + 'compat/fsmonitor/fsm-path-utils-' + fsmonitor_backend + '.c', + 'compat/fsmonitor/fsm-settings-' + fsmonitor_backend + '.c', + ] +endif +build_options_config.set_quoted('FSMONITOR_DAEMON_BACKEND', fsmonitor_backend) +build_options_config.set_quoted('FSMONITOR_OS_SETTINGS', fsmonitor_backend) + +if not get_option('b_sanitize').contains('address') and get_option('regex').allowed() and compiler.has_header('regex.h') and compiler.get_define('REG_STARTEND', prefix: '#include <regex.h>') != '' + build_options_config.set('NO_REGEX', '') + + if compiler.get_define('REG_ENHANCED', prefix: '#include <regex.h>') != '' + libgit_c_args += '-DUSE_ENHANCED_BASIC_REGULAR_EXPRESSIONS' + libgit_sources += 'compat/regcomp_enhanced.c' + endif +elif not get_option('regex').enabled() + libgit_c_args += [ + '-DNO_REGEX', + '-DGAWK', + '-DNO_MBSUPPORT', + ] + build_options_config.set('NO_REGEX', '1') + libgit_sources += 'compat/regex/regex.c' + libgit_include_directories += 'compat/regex' +else + error('Native regex support requested but not found') +endif + +# setitimer and friends are provided by compat/mingw.c. +if host_machine.system() != 'windows' + if not compiler.compiles(''' + #include <sys/time.h> + void func(void) + { + struct itimerval value; + } + ''', name: 'struct itimerval') + libgit_c_args += '-DNO_STRUCT_ITIMERVAL' + libgit_c_args += '-DNO_SETITIMER' + elif not compiler.has_function('setitimer') + libgit_c_args += '-DNO_SETITIMER' + endif +endif + +if compiler.has_member('struct stat', 'st_mtimespec.tv_nsec', prefix: '#include <sys/stat.h>') + libgit_c_args += '-DUSE_ST_TIMESPEC' +elif not compiler.has_member('struct stat', 'st_mtim.tv_nsec', prefix: '#include <sys/stat.h>') + libgit_c_args += '-DNO_NSEC' +endif + +if not compiler.has_member('struct stat', 'st_blocks', prefix: '#include <sys/stat.h>') + libgit_c_args += '-DNO_ST_BLOCKS_IN_STRUCT_STAT' +endif + +if not compiler.has_member('struct dirent', 'd_type', prefix: '#include <dirent.h>') + libgit_c_args += '-DNO_D_TYPE_IN_DIRENT' +endif + +if not compiler.has_member('struct passwd', 'pw_gecos', prefix: '#include <pwd.h>') + libgit_c_args += '-DNO_GECOS_IN_PWENT' +endif + +if compiler.has_function('sync_file_range') + libgit_c_args += '-DHAVE_SYNC_FILE_RANGE' +endif + +if not compiler.has_function('strcasestr') + libgit_c_args += '-DNO_STRCASESTR' + libgit_sources += 'compat/strcasestr.c' +endif + +if not compiler.has_function('memmem') + libgit_c_args += '-DNO_MEMMEM' + libgit_sources += 'compat/memmem.c' +endif + +if not compiler.has_function('strlcpy') + libgit_c_args += '-DNO_STRLCPY' + libgit_sources += 'compat/strlcpy.c' +endif + +if not compiler.has_function('strdup') + libgit_c_args += '-DOVERRIDE_STRDUP' + libgit_sources += 'compat/strdup.c' +endif + +if not compiler.has_function('strtoumax') + libgit_c_args += '-DNO_STRTOUMAX' + libgit_sources += [ + 'compat/strtoumax.c', + 'compat/strtoimax.c', + ] +endif + +if not compiler.has_function('strtoull') + libgit_c_args += '-DNO_STRTOULL' +endif + +if not compiler.has_function('setenv') + libgit_c_args += '-DNO_SETENV' + libgit_sources += 'compat/setenv.c' +endif + +if not compiler.has_function('qsort') + libgit_c_args += '-DINTERNAL_QSORT' +endif +libgit_sources += 'compat/qsort_s.c' + +# unsetenv is provided by compat/mingw.c. +if host_machine.system() != 'windows' and not compiler.has_function('unsetenv') + libgit_c_args += '-DNO_UNSETENV' + libgit_sources += 'compat/unsetenv.c' +endif + +if not compiler.has_function('mkdtemp') + libgit_c_args += '-DNO_MKDTEMP' + libgit_sources += 'compat/mkdtemp.c' +endif + +if not compiler.has_function('initgroups') + libgit_c_args += '-DNO_INITGROUPS' +endif + +if compiler.has_function('getdelim') + libgit_c_args += '-DHAVE_GETDELIM' +endif + +if host_machine.system() == 'windows' + libgit_c_args += '-DUSE_WIN32_MMAP' +elif not compiler.has_function('mmap') + libgit_c_args += '-DNO_MMAP' + libgit_sources += 'compat/mmap.c' +endif + +if compiler.has_function('clock_gettime') + libgit_c_args += '-DHAVE_CLOCK_GETTIME' +endif + +if compiler.compiles(''' + #include <time.h> + + void func(void) + { + clockid_t id = CLOCK_MONOTONIC; + } +''', name: 'monotonic clock') + libgit_c_args += '-DHAVE_CLOCK_MONOTONIC' +endif + +if not compiler.compiles(''' + #include <inttypes.h> + + void func(void) + { + uintmax_t x = 0; + } +''', name: 'uintmax_t') + libgit_c_args += '-DNO_UINTMAX_T' +endif + +has_bsd_sysctl = false +if compiler.has_header('sys/sysctl.h') + if compiler.compiles(''' + #include <stddef.h> + #include <sys/sysctl.h> + + void func(void) + { + int val, mib[2] = { 0 }; + size_t len = sizeof(val); + sysctl(mib, 2, &val, &len, NULL, 0); + } + ''', name: 'BSD sysctl') + libgit_c_args += '-DHAVE_BSD_SYSCTL' + has_bsd_sysctl = true + endif +endif + +if not meson.is_cross_build() and compiler.run(''' + #include <stdio.h> + + int main(int argc, const char **argv) + { + FILE *f = fopen(".", "r"); + return f ? 0 : 1; + } +''', name: 'fread reads directories').returncode() == 0 + libgit_c_args += '-DFREAD_READS_DIRECTORIES' + libgit_sources += 'compat/fopen.c' +endif + +if not meson.is_cross_build() and fs.exists('/dev/tty') + libgit_c_args += '-DHAVE_DEV_TTY' +endif + +csprng_backend = get_option('csprng_backend') +https_backend = get_option('https_backend') +sha1_backend = get_option('sha1_backend') +sha1_unsafe_backend = get_option('sha1_unsafe_backend') +sha256_backend = get_option('sha256_backend') + +security_framework = dependency('Security', required: 'CommonCrypto' in [https_backend, sha1_backend, sha1_unsafe_backend]) +core_foundation_framework = dependency('CoreFoundation', required: security_framework.found()) +if https_backend == 'auto' and security_framework.found() + https_backend = 'CommonCrypto' +endif + +openssl_required = 'openssl' in [csprng_backend, https_backend, sha1_backend, sha1_unsafe_backend, sha256_backend] +openssl = dependency('openssl', + required: openssl_required, + allow_fallback: openssl_required or https_backend == 'auto', + default_options: ['default_library=static'], +) +if https_backend == 'auto' and openssl.found() + https_backend = 'openssl' +endif + +if https_backend == 'CommonCrypto' + libgit_dependencies += security_framework + libgit_dependencies += core_foundation_framework + libgit_c_args += '-DAPPLE_COMMON_CRYPTO' +elif https_backend == 'openssl' + libgit_dependencies += openssl +else + # We either couldn't find any dependencies with 'auto' or the user requested + # 'none'. Both cases are benign. + https_backend = 'none' +endif + +if https_backend != 'openssl' + libgit_c_args += '-DNO_OPENSSL' +endif + +if sha1_backend == 'sha1dc' + libgit_c_args += '-DSHA1_DC' + libgit_c_args += '-DSHA1DC_NO_STANDARD_INCLUDES=1' + libgit_c_args += '-DSHA1DC_INIT_SAFE_HASH_DEFAULT=0' + libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_SHA1_C="git-compat-util.h"' + libgit_c_args += '-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="git-compat-util.h"' + + libgit_sources += [ + 'sha1dc_git.c', + 'sha1dc/sha1.c', + 'sha1dc/ubc_check.c', + ] +endif +if sha1_backend == 'CommonCrypto' or sha1_unsafe_backend == 'CommonCrypto' + if sha1_backend == 'CommonCrypto' + libgit_c_args += '-DSHA1_APPLE' + endif + if sha1_unsafe_backend == 'CommonCrypto' + libgit_c_args += '-DSHA1_APPLE_UNSAFE' + endif + + libgit_c_args += '-DCOMMON_DIGEST_FOR_OPENSSL' + # Apple CommonCrypto requires chunking + libgit_c_args += '-DSHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' +endif +if sha1_backend == 'openssl' or sha1_unsafe_backend == 'openssl' + if sha1_backend == 'openssl' + libgit_c_args += '-DSHA1_OPENSSL' + endif + if sha1_unsafe_backend == 'openssl' + libgit_c_args += '-DSHA1_OPENSSL_UNSAFE' + endif + + libgit_dependencies += openssl +endif +if sha1_backend == 'block' or sha1_unsafe_backend == 'block' + if sha1_backend == 'block' + libgit_c_args += '-DSHA1_BLK' + endif + if sha1_unsafe_backend == 'block' + libgit_c_args += '-DSHA1_BLK_UNSAFE' + endif + + libgit_sources += 'block-sha1/sha1.c' +endif + +if sha256_backend == 'openssl' + libgit_c_args += '-DSHA256_OPENSSL' + libgit_dependencies += openssl +elif sha256_backend == 'nettle' + nettle = dependency('nettle') + libgit_dependencies += nettle + libgit_c_args += '-DSHA256_NETTLE' +elif sha256_backend == 'gcrypt' + gcrypt = dependency('gcrypt') + libgit_dependencies += gcrypt + libgit_c_args += '-DSHA256_GCRYPT' +elif sha256_backend == 'block' + libgit_c_args += '-DSHA256_BLK' + libgit_sources += 'sha256/block/sha256.c' +else + error('Unhandled SHA256 backend ' + sha256_backend) +endif + +# Backends are ordered to reflect our preference for more secure and faster +# ones over the ones that are less so. +if csprng_backend in ['auto', 'arc4random'] and compiler.has_header_symbol('stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random') + libgit_c_args += '-DHAVE_ARC4RANDOM' + csprng_backend = 'arc4random' +elif csprng_backend in ['auto', 'arc4random_bsd'] and compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf', required: csprng_backend == 'arc4random_bsd') + libgit_c_args += '-DHAVE_ARC4RANDOM_BSD' + csprng_backend = 'arc4random_bsd' +elif csprng_backend in ['auto', 'getrandom'] and compiler.has_header_symbol('sys/random.h', 'getrandom', required: csprng_backend == 'getrandom') + libgit_c_args += '-DHAVE_GETRANDOM' + csprng_backend = 'getrandom' +elif csprng_backend in ['auto', 'getentropy'] and compiler.has_header_symbol('unistd.h', 'getentropy', required: csprng_backend == 'getentropy') + libgit_c_args += '-DHAVE_GETENTROPY' + csprng_backend = 'getentropy' +elif csprng_backend in ['auto', 'rtlgenrandom'] and compiler.has_header_symbol('ntsecapi.h', 'RtlGenRandom', prefix: '#include <windows.h>', required: csprng_backend == 'rtlgenrandom') + libgit_c_args += '-DHAVE_RTLGENRANDOM' + csprng_backend = 'rtlgenrandom' +elif csprng_backend in ['auto', 'openssl'] and openssl.found() + libgit_c_args += '-DHAVE_OPENSSL_CSPRNG' + csprng_backend = 'openssl' +elif csprng_backend in ['auto', 'urandom'] + csprng_backend = 'urandom' +else + error('Unsupported CSPRNG backend: ' + csprng_backend) +endif + +if get_option('runtime_prefix') + libgit_c_args += '-DRUNTIME_PREFIX' + build_options_config.set('RUNTIME_PREFIX', 'true') + git_exec_path = get_option('libexecdir') / 'git-core' + + if compiler.has_header('mach-o/dyld.h') + libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH' + endif + + if has_bsd_sysctl and compiler.compiles(''' + #include <sys/sysctl.h> + + void func(void) + { + KERN_PROC_PATHNAME; KERN_PROC; + } + ''', name: 'BSD KERN_PROC_PATHNAME') + libgit_c_args += '-DHAVE_NS_GET_EXECUTABLE_PATH' + endif + + if host_machine.system() == 'linux' + libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe' + '"' + elif host_machine.system() == 'openbsd' + libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/file' + '"' + elif host_machine.system() == 'netbsd' + libgit_c_args += '-DPROCFS_EXECUTABLE_PATH="' + '/proc/curproc/exe' + '"' + endif + + if host_machine.system() == 'windows' and compiler.compiles(''' + #include <stdlib.h> + + void func(void) + { + _wpgmptr; + } + ''', name: 'Win32 _wpgmptr') + libgit_c_args += '-DHAVE_WPGMPTR' + endif +else + build_options_config.set('RUNTIME_PREFIX', 'false') + git_exec_path = get_option('prefix') / get_option('libexecdir') / 'git-core' +endif +libgit_c_args += '-DGIT_EXEC_PATH="' + git_exec_path + '"' + +git_version_file = custom_target( + command: [ + shell, + meson.current_source_dir() / 'GIT-VERSION-GEN', + meson.current_source_dir(), + '@INPUT@', + '@OUTPUT@', + ], + input: meson.current_source_dir() / 'GIT-VERSION-FILE.in', + output: 'GIT-VERSION-FILE', + env: version_gen_environment, + build_always_stale: true, +) + +version_def_h = custom_target( + command: [ + shell, + meson.current_source_dir() / 'GIT-VERSION-GEN', + meson.current_source_dir(), + '@INPUT@', + '@OUTPUT@', + ], + input: meson.current_source_dir() / 'version-def.h.in', + output: 'version-def.h', + # Depend on GIT-VERSION-FILE so that we don't always try to rebuild this + # target for the same commit. + depends: [git_version_file], + env: version_gen_environment, +) +libgit_sources += version_def_h + +libgit = declare_dependency( + link_with: static_library('git', + sources: libgit_sources, + c_args: libgit_c_args + [ + '-DGIT_VERSION_H="' + version_def_h.full_path() + '"', + ], + dependencies: libgit_dependencies, + include_directories: libgit_include_directories, + ), + compile_args: libgit_c_args, + dependencies: libgit_dependencies, + include_directories: libgit_include_directories, +) + +common_main_sources = ['common-main.c'] +common_main_link_args = [ ] +if host_machine.system() == 'windows' + git_rc = custom_target( + command: [ + shell, + meson.current_source_dir() / 'GIT-VERSION-GEN', + meson.current_source_dir(), + '@INPUT@', + '@OUTPUT@', + ], + input: meson.current_source_dir() / 'git.rc.in', + output: 'git.rc', + depends: [git_version_file], + env: version_gen_environment, + ) + + common_main_sources += import('windows').compile_resources(git_rc, + include_directories: [meson.current_source_dir()], + ) + if compiler.get_argument_syntax() == 'gcc' + common_main_link_args += [ + '-municode', + '-Wl,-nxcompat', + '-Wl,-dynamicbase', + '-Wl,-pic-executable,-e,mainCRTStartup', + ] + elif compiler.get_argument_syntax() == 'msvc' + common_main_link_args += [ + '/ENTRY:wmainCRTStartup', + 'invalidcontinue.obj', + ] + else + error('Unsupported compiler ' + compiler.get_id()) + endif +endif + +libgit_commonmain = declare_dependency( + link_with: static_library('common-main', + sources: common_main_sources, + dependencies: [ libgit ], + ), + link_args: common_main_link_args, + dependencies: [ libgit ], +) + +bin_wrappers = [ ] +test_dependencies = [ ] + +git_builtin = executable('git', + sources: builtin_sources + 'git.c', + dependencies: [libgit_commonmain], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) +bin_wrappers += git_builtin + +test_dependencies += executable('git-daemon', + sources: 'daemon.c', + dependencies: [libgit_commonmain], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +test_dependencies += executable('git-sh-i18n--envsubst', + sources: 'sh-i18n--envsubst.c', + dependencies: [libgit_commonmain], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +bin_wrappers += executable('git-shell', + sources: 'shell.c', + dependencies: [libgit_commonmain], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +test_dependencies += executable('git-http-backend', + sources: 'http-backend.c', + dependencies: [libgit_commonmain], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +bin_wrappers += executable('scalar', + sources: 'scalar.c', + dependencies: [libgit_commonmain], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('curl').enabled() + libgit_curl = declare_dependency( + sources: [ + 'http.c', + 'http-walker.c', + ], + dependencies: [libgit_commonmain, curl], + ) + + test_dependencies += executable('git-remote-http', + sources: 'remote-curl.c', + dependencies: [libgit_curl], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + + test_dependencies += executable('git-http-fetch', + sources: 'http-fetch.c', + dependencies: [libgit_curl], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + + if expat.found() + test_dependencies += executable('git-http-push', + sources: 'http-push.c', + dependencies: [libgit_curl], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + endif + + foreach alias : [ 'git-remote-https', 'git-remote-ftp', 'git-remote-ftps' ] + test_dependencies += executable(alias, + sources: 'remote-curl.c', + dependencies: [libgit_curl], + ) + + install_symlink(alias + executable_suffix, + install_dir: get_option('libexecdir') / 'git-core', + pointing_to: 'git-remote-http', + ) + endforeach +endif + +test_dependencies += executable('git-imap-send', + sources: 'imap-send.c', + dependencies: [ use_curl_for_imap_send ? libgit_curl : libgit_commonmain ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +foreach alias : [ 'git-receive-pack', 'git-upload-archive', 'git-upload-pack' ] + bin_wrappers += executable(alias, + objects: git_builtin.extract_all_objects(recursive: false), + dependencies: [libgit_commonmain], + ) + + install_symlink(alias + executable_suffix, + install_dir: get_option('libexecdir') / 'git-core', + pointing_to: 'git', + ) +endforeach + +foreach symlink : [ + 'git', + 'git-receive-pack', + 'git-shell', + 'git-upload-archive', + 'git-upload-pack', + 'scalar', +] + if meson.version().version_compare('>=1.3.0') + pointing_to = fs.relative_to(get_option('libexecdir') / 'git-core' / symlink, get_option('bindir')) + else + pointing_to = '../libexec/git-core' / symlink + endif + + install_symlink(symlink, + install_dir: get_option('bindir'), + pointing_to: pointing_to, + ) +endforeach + +scripts_sh = [ + 'git-difftool--helper.sh', + 'git-filter-branch.sh', + 'git-merge-octopus.sh', + 'git-merge-one-file.sh', + 'git-merge-resolve.sh', + 'git-mergetool--lib.sh', + 'git-mergetool.sh', + 'git-quiltimport.sh', + 'git-request-pull.sh', + 'git-sh-i18n.sh', + 'git-sh-setup.sh', + 'git-submodule.sh', + 'git-web--browse.sh', +] +if perl_features_enabled + scripts_sh += 'git-instaweb.sh' +endif + +foreach script : scripts_sh + test_dependencies += custom_target( + input: script, + output: fs.stem(script), + command: [ + shell, + meson.project_source_root() / 'generate-script.sh', + '@INPUT@', + '@OUTPUT@', + meson.project_build_root() / 'GIT-BUILD-OPTIONS', + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) +endforeach + +if perl_features_enabled + scripts_perl = [ + 'git-archimport.perl', + 'git-cvsexportcommit.perl', + 'git-cvsimport.perl', + 'git-cvsserver.perl', + 'git-send-email.perl', + 'git-svn.perl', + ] + + pathsep = ':' + if host_machine.system() == 'windows' + pathsep = ';' + endif + + perl_header_template = 'perl/header_templates/fixed_prefix.template.pl' + if get_option('runtime_prefix') + perl_header_template = 'perl/header_templates/runtime_prefix.template.pl' + endif + + perl_header = configure_file( + input: perl_header_template, + output: 'GIT-PERL-HEADER', + configuration: { + 'GITEXECDIR_REL': get_option('libexecdir') / 'git-core', + 'PERLLIBDIR_REL': get_option('datadir') / 'perl5', + 'LOCALEDIR_REL': get_option('datadir') / 'locale', + 'INSTLIBDIR': get_option('datadir') / 'perl5', + 'PATHSEP': pathsep, + }, + ) + + generate_perl_command = [ + shell, + meson.project_source_root() / 'generate-perl.sh', + meson.project_build_root() / 'GIT-BUILD-OPTIONS', + git_version_file.full_path(), + perl_header, + '@INPUT@', + '@OUTPUT@', + ] + + foreach script : scripts_perl + generated_script = custom_target( + input: script, + output: fs.stem(script), + command: generate_perl_command, + install: true, + install_dir: get_option('libexecdir') / 'git-core', + depends: [git_version_file], + ) + test_dependencies += generated_script + + if script == 'git-cvsserver.perl' + bin_wrappers += generated_script + + if meson.version().version_compare('>=1.3.0') + pointing_to = fs.relative_to(get_option('libexecdir') / 'git-core' / fs.stem(script), get_option('bindir')) + else + pointing_to = '../libexec/git-core' / fs.stem(script) + endif + + install_symlink(fs.stem(script), + install_dir: get_option('bindir'), + pointing_to: pointing_to, + ) + endif + endforeach + + subdir('perl') +endif + +if python.found() + scripts_python = [ + 'git-p4.py' + ] + + foreach script : scripts_python + generated_python = custom_target( + input: script, + output: fs.stem(script), + command: [ + shell, + meson.project_source_root() / 'generate-python.sh', + meson.project_build_root() / 'GIT-BUILD-OPTIONS', + '@INPUT@', + '@OUTPUT@', + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + test_dependencies += generated_python + endforeach +endif + +mergetools = [ + 'mergetools/araxis', + 'mergetools/bc', + 'mergetools/codecompare', + 'mergetools/deltawalker', + 'mergetools/diffmerge', + 'mergetools/diffuse', + 'mergetools/ecmerge', + 'mergetools/emerge', + 'mergetools/examdiff', + 'mergetools/guiffy', + 'mergetools/gvimdiff', + 'mergetools/kdiff3', + 'mergetools/kompare', + 'mergetools/meld', + 'mergetools/nvimdiff', + 'mergetools/opendiff', + 'mergetools/p4merge', + 'mergetools/smerge', + 'mergetools/tkdiff', + 'mergetools/tortoisemerge', + 'mergetools/vimdiff', + 'mergetools/vscode', + 'mergetools/winmerge', + 'mergetools/xxdiff', +] + +foreach mergetool : mergetools + install_data(mergetool, install_dir: get_option('libexecdir') / 'git-core' / 'mergetools') +endforeach + +if intl.found() + subdir('po') +endif + +# Gitweb requires Perl, so we disable the auto-feature if Perl was not found. +# We make sure further up that Perl is required in case the gitweb option is +# enabled. +gitweb_option = get_option('gitweb').disable_auto_if(not perl.found()) +if gitweb_option.allowed() + subdir('gitweb') + build_options_config.set('NO_GITWEB', '') +else + build_options_config.set('NO_GITWEB', '1') +endif + +subdir('templates') + +# Everything but the bin-wrappers need to come before this target such that we +# can properly set up test dependencies. The bin-wrappers themselves are set up +# at configuration time, so these are fine. +if get_option('tests') + subdir('t') +endif + +if get_option('fuzzers') + subdir('oss-fuzz') +endif + +subdir('bin-wrappers') +if get_option('docs') != [] + subdir('Documentation') +endif + +subdir('contrib') + +foreach key, value : { + 'DIFF': diff.full_path(), + 'GIT_SOURCE_DIR': meson.project_source_root(), + 'GIT_TEST_CMP': diff.full_path() + ' -u', + 'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl', + 'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates', + 'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po', + 'PAGER_ENV': get_option('pager_environment'), + 'PERL_PATH': perl.found() ? perl.full_path() : '', + 'PYTHON_PATH': python.found () ? python.full_path() : '', + 'SHELL_PATH': shell.full_path(), + 'TAR': tar.full_path(), + 'TEST_OUTPUT_DIRECTORY': test_output_directory, + 'TEST_SHELL_PATH': shell.full_path(), +} + if value != '' and cygpath.found() + value = run_command(cygpath, value, check: true).stdout().strip() + endif + build_options_config.set_quoted(key, value) +endforeach + +configure_file( + input: 'GIT-BUILD-OPTIONS.in', + output: 'GIT-BUILD-OPTIONS', + configuration: build_options_config, +) + +# Development environments can be used via `meson devenv -C <builddir>`. This +# allows you to execute test scripts directly with the built Git version and +# puts the built version of Git in your PATH. +devenv = environment() +devenv.set('GIT_BUILD_DIR', meson.current_build_dir()) +devenv.prepend('PATH', meson.current_build_dir() / 'bin-wrappers') +meson.add_devenv(devenv) + +# Generate the 'version' file in the distribution tarball. This is used via +# `meson dist -C <builddir>` to populate the source archive with the Git +# version that the archive is being generated from. +meson.add_dist_script( + shell, + '-c', + '"$1" "$2" "$3" --format="@GIT_VERSION@" "$MESON_DIST_ROOT/version"', + 'GIT-VERSION-GEN', + shell, + meson.current_source_dir() / 'GIT-VERSION-GEN', + meson.current_source_dir(), +) + +summary({ + 'curl': curl.found(), + 'expat': expat.found(), + 'gettext': intl.found(), + 'gitweb': gitweb_option.allowed(), + 'https': https_backend, + 'iconv': iconv.found(), + 'pcre2': pcre2.found(), + 'perl': perl_features_enabled, + 'python': python.found(), +}, section: 'Auto-detected features') + +summary({ + 'csprng': csprng_backend, + 'https': https_backend, + 'sha1': sha1_backend, + 'sha1_unsafe': sha1_unsafe_backend, + 'sha256': sha256_backend, + 'zlib': zlib_backend, +}, section: 'Backends') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000000000..78d172a74019a4 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,113 @@ +# Configuration for how Git behaves at runtime. +option('default_pager', type: 'string', value: 'less', + description: 'Fall-back pager.') +option('default_editor', type: 'string', value: 'vi', + description: 'Fall-back editor.') +option('gitconfig', type: 'string', value: '/etc/gitconfig', + description: 'Path to the global git configuration file.') +option('gitattributes', type: 'string', value: '/etc/gitattributes', + description: 'Path to the global git attributes file.') +option('pager_environment', type: 'string', value: 'LESS=FRX LV=-c', + description: 'Environment used when spawning the pager') +option('perl_cpan_fallback', type: 'boolean', value: true, + description: 'Install bundled copies of CPAN modules that serve as a fallback in case the modules are not available on the system.') +option('runtime_prefix', type: 'boolean', value: false, + description: 'Resolve ancillary tooling and support files relative to the location of the runtime binary instead of hard-coding them into the binary.') +option('sane_tool_path', type: 'array', value: [], + description: 'An array of paths to pick up tools from in case the normal tools are broken or lacking.') + +# Build information compiled into Git and other parts like documentation. +option('build_date', type: 'string', value: '', + description: 'Build date reported by our documentation.') +option('built_from_commit', type: 'string', value: '', + description: 'Commit that Git was built from reported by git-version(1).') +option('user_agent', type: 'string', value: '', + description: 'User agent reported to remote servers.') +option('version', type: 'string', value: '', + description: 'Version string reported by git-version(1) and other tools.') + +# Features supported by Git. +option('contrib', type: 'array', value: [ 'completion' ], choices: [ 'completion', 'contacts', 'subtree' ], + description: 'Contributed features to include.') +option('credential_helpers', type: 'array', value: [ ], choices: [ 'libsecret', 'netrc', 'osxkeychain', 'wincred' ], + description: 'Contributed features to include.') +option('curl', type: 'feature', value: 'enabled', + description: 'Build helpers used to access remotes with the HTTP transport.') +option('expat', type: 'feature', value: 'enabled', + description: 'Build helpers used to push to remotes with the HTTP transport.') +option('gettext', type: 'feature', value: 'auto', + description: 'Build translation files.') +option('gitweb', type: 'feature', value: 'auto', + description: 'Build Git web interface. Requires Perl.') +option('iconv', type: 'feature', value: 'auto', + description: 'Support reencoding strings with different encodings.') +option('pcre2', type: 'feature', value: 'enabled', + description: 'Support Perl-compatible regular expressions in e.g. git-grep(1).') +option('perl', type: 'feature', value: 'auto', + description: 'Build tools written in Perl.') +option('python', type: 'feature', value: 'auto', + description: 'Build tools written in Python.') +option('regex', type: 'feature', value: 'auto', + description: 'Use the system-provided regex library instead of the bundled one.') + +# Backends. +option('csprng_backend', type: 'combo', value: 'auto', choices: ['auto', 'arc4random', 'arc4random_bsd', 'getrandom', 'getentropy', 'rtlgenrandom', 'openssl', 'urandom'], + description: 'The backend to use for generating cryptographically-secure pseudo-random numbers.') +option('https_backend', type: 'combo', value: 'auto', choices: ['auto', 'openssl', 'CommonCrypto', 'none'], + description: 'The HTTPS backend to use when connecting to remotes.') +option('sha1_backend', type: 'combo', choices: ['openssl', 'block', 'sha1dc', 'CommonCrypto'], value: 'sha1dc', + description: 'The backend used for hashing objects with the SHA1 object format.') +option('sha1_unsafe_backend', type: 'combo', choices: ['openssl', 'block', 'CommonCrypto', 'none'], value: 'none', + description: 'The backend used for hashing data with the SHA1 object format in case no cryptographic security is needed.') +option('sha256_backend', type: 'combo', choices: ['openssl', 'nettle', 'gcrypt', 'block'], value: 'block', + description: 'The backend used for hashing objects with the SHA256 object format.') +option('zlib_backend', type: 'combo', choices: ['auto', 'zlib', 'zlib-ng'], value: 'auto', + description: 'The backend used for compressing objects and other data.') + +# Build tweaks. +option('breaking_changes', type: 'boolean', value: false, + description: 'Enable upcoming breaking changes.') +option('macos_use_homebrew_gettext', type: 'boolean', value: true, + description: 'Use gettext from Homebrew instead of the slightly-broken system-provided one.') + +# gitweb configuration. +option('gitweb_config', type: 'string', value: 'gitweb_config.perl') +option('gitweb_config_system', type: 'string', value: '/etc/gitweb.conf') +option('gitweb_config_common', type: 'string', value: '/etc/gitweb-common.conf') +option('gitweb_home_link_str', type: 'string', value: 'projects') +option('gitweb_sitename', type: 'string', value: '') +option('gitweb_projectroot', type: 'string', value: '/pub/git') +option('gitweb_project_maxdepth', type: 'string', value: '2007') +option('gitweb_export_ok', type: 'string', value: '') +option('gitweb_strict_export', type: 'string', value: '') +option('gitweb_base_url', type: 'string', value: '') +option('gitweb_list', type: 'string', value: '') +option('gitweb_hometext', type: 'string', value: 'indextext.html') +option('gitweb_css', type: 'string', value: 'static/gitweb.css') +option('gitweb_logo', type: 'string', value: 'static/git-logo.png') +option('gitweb_favicon', type: 'string', value: 'static/git-favicon.png') +option('gitweb_js', type: 'string', value: 'static/gitweb.js') +option('gitweb_site_html_head_string', type: 'string', value: '') +option('gitweb_site_header', type: 'string', value: '') +option('gitweb_site_footer', type: 'string', value: '') +option('highlight_bin', type: 'string', value: 'highlight') + +# Documentation. +option('docs', type: 'array', choices: ['man', 'html'], value: [], + description: 'Which documenattion formats to build and install.') +option('default_help_format', type: 'combo', choices: ['man', 'html'], value: 'man', + description: 'Default format used when executing git-help(1).') +option('docs_backend', type: 'combo', choices: ['asciidoc', 'asciidoctor', 'auto'], value: 'auto', + description: 'Which backend to use to generate documentation.') + +# Testing. +option('coccinelle', type: 'feature', value: 'auto', + description: 'Provide a coccicheck target that generates a Coccinelle patch.') +option('tests', type: 'boolean', value: true, + description: 'Enable building tests. This requires Perl, but is separate from the "perl" option such that you can build tests without Perl features enabled.') +option('test_output_directory', type: 'string', + description: 'Path to the directory used to store test outputs') +option('test_utf8_locale', type: 'string', + description: 'Name of a UTF-8 locale used for testing.') +option('fuzzers', type: 'boolean', value: false, + description: 'Enable building fuzzers.') diff --git a/midx-write.c b/midx-write.c index 1ef62c4f4bebf6..48d6558253ec93 100644 --- a/midx-write.c +++ b/midx-write.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -35,13 +35,13 @@ extern void clear_incremental_midx_files_ext(const char *object_dir, extern int cmp_idx_or_pack_name(const char *idx_or_pack_name, const char *idx_name); -static size_t write_midx_header(struct hashfile *f, - unsigned char num_chunks, +static size_t write_midx_header(const struct git_hash_algo *hash_algo, + struct hashfile *f, unsigned char num_chunks, uint32_t num_packs) { hashwrite_be32(f, MIDX_SIGNATURE); hashwrite_u8(f, MIDX_VERSION); - hashwrite_u8(f, oid_version(the_hash_algo)); + hashwrite_u8(f, oid_version(hash_algo)); hashwrite_u8(f, num_chunks); hashwrite_u8(f, 0); /* unused */ hashwrite_be32(f, num_packs); @@ -110,6 +110,8 @@ struct write_midx_context { uint32_t num_multi_pack_indexes_before; struct string_list *to_include; + + struct repository *repo; }; static int should_include_pack(const struct write_midx_context *ctx, @@ -154,7 +156,7 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len, return; ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc); - p = add_packed_git(full_path, full_path_len, 0); + p = add_packed_git(ctx->repo, full_path, full_path_len, 0); if (!p) { warning(_("failed to add packfile '%s'"), full_path); @@ -480,7 +482,7 @@ static int write_midx_oid_lookup(struct hashfile *f, void *data) { struct write_midx_context *ctx = data; - unsigned char hash_len = the_hash_algo->rawsz; + unsigned char hash_len = ctx->repo->hash_algo->rawsz; struct pack_midx_entry *list = ctx->entries; uint32_t i; @@ -605,7 +607,7 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx) uint32_t *pack_order, base_objects = 0; uint32_t i; - trace2_region_enter("midx", "midx_pack_order", the_repository); + trace2_region_enter("midx", "midx_pack_order", ctx->repo); if (ctx->incremental && ctx->base_midx) base_objects = ctx->base_midx->num_objects + @@ -640,7 +642,7 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx) } free(data); - trace2_region_leave("midx", "midx_pack_order", the_repository); + trace2_region_leave("midx", "midx_pack_order", ctx->repo); return pack_order; } @@ -649,21 +651,23 @@ static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash, struct write_midx_context *ctx) { struct strbuf buf = STRBUF_INIT; - const char *tmp_file; + char *tmp_file; - trace2_region_enter("midx", "write_midx_reverse_index", the_repository); + trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo); - strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex(midx_hash)); + strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex_algop(midx_hash, + ctx->repo->hash_algo)); - tmp_file = write_rev_file_order(NULL, ctx->pack_order, ctx->entries_nr, - midx_hash, WRITE_REV); + tmp_file = write_rev_file_order(ctx->repo->hash_algo, NULL, ctx->pack_order, + ctx->entries_nr, midx_hash, WRITE_REV); if (finalize_object_file(tmp_file, buf.buf)) die(_("cannot store reverse index file")); strbuf_release(&buf); + free(tmp_file); - trace2_region_leave("midx", "write_midx_reverse_index", the_repository); + trace2_region_leave("midx", "write_midx_reverse_index", ctx->repo); } static void prepare_midx_packing_data(struct packing_data *pdata, @@ -671,10 +675,10 @@ static void prepare_midx_packing_data(struct packing_data *pdata, { uint32_t i; - trace2_region_enter("midx", "prepare_midx_packing_data", the_repository); + trace2_region_enter("midx", "prepare_midx_packing_data", ctx->repo); memset(pdata, 0, sizeof(struct packing_data)); - prepare_packing_data(the_repository, pdata); + prepare_packing_data(ctx->repo, pdata); for (i = 0; i < ctx->entries_nr; i++) { uint32_t pos = ctx->pack_order[i]; @@ -685,7 +689,7 @@ static void prepare_midx_packing_data(struct packing_data *pdata, ctx->info[ctx->pack_perm[from->pack_int_id]].p); } - trace2_region_leave("midx", "prepare_midx_packing_data", the_repository); + trace2_region_leave("midx", "prepare_midx_packing_data", ctx->repo); } static int add_ref_to_pending(const char *refname, const char *referent UNUSED, @@ -701,7 +705,7 @@ static int add_ref_to_pending(const char *refname, const char *referent UNUSED, return 0; } - if (!peel_iterated_oid(the_repository, oid, &peeled)) + if (!peel_iterated_oid(revs->repo, oid, &peeled)) oid = &peeled; object = parse_object_or_die(oid, refname); @@ -759,7 +763,7 @@ static int read_refs_snapshot(const char *refs_snapshot, hex = &buf.buf[1]; } - if (parse_oid_hex(hex, &oid, &end) < 0) + if (parse_oid_hex_algop(hex, &oid, &end, revs->repo->hash_algo) < 0) die(_("could not parse line: %s"), buf.buf); if (*end) die(_("malformed line: %s"), buf.buf); @@ -775,6 +779,7 @@ static int read_refs_snapshot(const char *refs_snapshot, strbuf_release(&buf); return 0; } + static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr_p, const char *refs_snapshot, struct write_midx_context *ctx) @@ -782,17 +787,16 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr struct rev_info revs; struct bitmap_commit_cb cb = {0}; - trace2_region_enter("midx", "find_commits_for_midx_bitmap", - the_repository); + trace2_region_enter("midx", "find_commits_for_midx_bitmap", ctx->repo); cb.ctx = ctx; - repo_init_revisions(the_repository, &revs, NULL); + repo_init_revisions(ctx->repo, &revs, NULL); if (refs_snapshot) { read_refs_snapshot(refs_snapshot, &revs); } else { setup_revisions(0, NULL, &revs, NULL); - refs_for_each_ref(get_main_ref_store(the_repository), + refs_for_each_ref(get_main_ref_store(ctx->repo), add_ref_to_pending, &revs); } @@ -820,13 +824,12 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr release_revisions(&revs); - trace2_region_leave("midx", "find_commits_for_midx_bitmap", - the_repository); + trace2_region_leave("midx", "find_commits_for_midx_bitmap", ctx->repo); return cb.commits; } -static int write_midx_bitmap(const char *midx_name, +static int write_midx_bitmap(struct repository *r, const char *midx_name, const unsigned char *midx_hash, struct packing_data *pdata, struct commit **commits, @@ -839,9 +842,9 @@ static int write_midx_bitmap(const char *midx_name, struct bitmap_writer writer; struct pack_idx_entry **index; char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name, - hash_to_hex(midx_hash)); + hash_to_hex_algop(midx_hash, r->hash_algo)); - trace2_region_enter("midx", "write_midx_bitmap", the_repository); + trace2_region_enter("midx", "write_midx_bitmap", r); if (flags & MIDX_WRITE_BITMAP_HASH_CACHE) options |= BITMAP_OPT_HASH_CACHE; @@ -858,7 +861,7 @@ static int write_midx_bitmap(const char *midx_name, for (i = 0; i < pdata->nr_objects; i++) index[i] = &pdata->objects[i].idx; - bitmap_writer_init(&writer, the_repository, pdata); + bitmap_writer_init(&writer, r, pdata); bitmap_writer_show_progress(&writer, flags & MIDX_PROGRESS); bitmap_writer_build_type_index(&writer, index); @@ -891,7 +894,7 @@ static int write_midx_bitmap(const char *midx_name, free(bitmap_name); bitmap_writer_free(&writer); - trace2_region_leave("midx", "write_midx_bitmap", the_repository); + trace2_region_leave("midx", "write_midx_bitmap", r); return ret; } @@ -943,7 +946,7 @@ static int fill_packs_from_midx(struct write_midx_context *ctx, */ if (flags & MIDX_WRITE_REV_INDEX || preferred_pack_name) { - if (prepare_midx_pack(the_repository, m, + if (prepare_midx_pack(ctx->repo, m, m->num_packs_in_base + i)) { error(_("could not load pack")); return 1; @@ -990,9 +993,10 @@ static int link_midx_to_chain(struct multi_pack_index *m) for (i = 0; i < ARRAY_SIZE(midx_exts); i++) { const unsigned char *hash = get_midx_checksum(m); - get_midx_filename_ext(&from, m->object_dir, hash, - midx_exts[i].non_split); - get_split_midx_filename_ext(&to, m->object_dir, hash, + get_midx_filename_ext(m->repo->hash_algo, &from, m->object_dir, + hash, midx_exts[i].non_split); + get_split_midx_filename_ext(m->repo->hash_algo, &to, + m->object_dir, hash, midx_exts[i].split); if (link(from.buf, to.buf) < 0 && errno != ENOENT) { @@ -1011,9 +1015,8 @@ static int link_midx_to_chain(struct multi_pack_index *m) return ret; } -static void clear_midx_files(const char *object_dir, - const char **hashes, - uint32_t hashes_nr, +static void clear_midx_files(struct repository *r, const char *object_dir, + const char **hashes, uint32_t hashes_nr, unsigned incremental) { /* @@ -1038,7 +1041,7 @@ static void clear_midx_files(const char *object_dir, } if (incremental) - get_midx_filename(&buf, object_dir); + get_midx_filename(r->hash_algo, &buf, object_dir); else get_midx_chain_filename(&buf, object_dir); @@ -1048,7 +1051,7 @@ static void clear_midx_files(const char *object_dir, strbuf_release(&buf); } -static int write_midx_internal(const char *object_dir, +static int write_midx_internal(struct repository *r, const char *object_dir, struct string_list *packs_to_include, struct string_list *packs_to_drop, const char *preferred_pack_name, @@ -1069,7 +1072,9 @@ static int write_midx_internal(const char *object_dir, const char **keep_hashes = NULL; struct chunkfile *cf; - trace2_region_enter("midx", "write_midx_internal", the_repository); + trace2_region_enter("midx", "write_midx_internal", r); + + ctx.repo = r; ctx.incremental = !!(flags & MIDX_WRITE_INCREMENTAL); if (ctx.incremental && (flags & MIDX_WRITE_BITMAP)) @@ -1080,14 +1085,13 @@ static int write_midx_internal(const char *object_dir, "%s/pack/multi-pack-index.d/tmp_midx_XXXXXX", object_dir); else - get_midx_filename(&midx_name, object_dir); + get_midx_filename(r->hash_algo, &midx_name, object_dir); if (safe_create_leading_directories(midx_name.buf)) die_errno(_("unable to create leading directories of %s"), midx_name.buf); if (!packs_to_include || ctx.incremental) { - struct multi_pack_index *m = lookup_multi_pack_index(the_repository, - object_dir); + struct multi_pack_index *m = lookup_multi_pack_index(r, object_dir); if (m && !midx_checksum_valid(m)) { warning(_("ignoring existing multi-pack-index; checksum mismatch")); m = NULL; @@ -1127,7 +1131,8 @@ static int write_midx_internal(const char *object_dir, ctx.pack_paths_checked = 0; if (flags & MIDX_PROGRESS) - ctx.progress = start_delayed_progress(_("Adding packfiles to multi-pack-index"), 0); + ctx.progress = start_delayed_progress(r, + _("Adding packfiles to multi-pack-index"), 0); else ctx.progress = NULL; @@ -1331,7 +1336,7 @@ static int write_midx_internal(const char *object_dir, return -1; } - if (adjust_shared_perm(get_tempfile_path(incr))) { + if (adjust_shared_perm(r, get_tempfile_path(incr))) { error(_("unable to adjust shared permissions for '%s'"), get_tempfile_path(incr)); return -1; @@ -1350,7 +1355,7 @@ static int write_midx_internal(const char *object_dir, add_chunk(cf, MIDX_CHUNKID_OIDFANOUT, MIDX_CHUNK_FANOUT_SIZE, write_midx_oid_fanout); add_chunk(cf, MIDX_CHUNKID_OIDLOOKUP, - st_mult(ctx.entries_nr, the_hash_algo->rawsz), + st_mult(ctx.entries_nr, r->hash_algo->rawsz), write_midx_oid_lookup); add_chunk(cf, MIDX_CHUNKID_OBJECTOFFSETS, st_mult(ctx.entries_nr, MIDX_CHUNK_OFFSET_WIDTH), @@ -1372,7 +1377,8 @@ static int write_midx_internal(const char *object_dir, write_midx_bitmapped_packs); } - write_midx_header(f, get_num_chunks(cf), ctx.nr - dropped_packs); + write_midx_header(r->hash_algo, f, get_num_chunks(cf), + ctx.nr - dropped_packs); write_chunkfile(cf, &ctx); finalize_hashfile(f, midx_hash, FSYNC_COMPONENT_PACK_METADATA, @@ -1404,7 +1410,7 @@ static int write_midx_internal(const char *object_dir, FREE_AND_NULL(ctx.entries); ctx.entries_nr = 0; - if (write_midx_bitmap(midx_name.buf, midx_hash, &pdata, + if (write_midx_bitmap(r, midx_name.buf, midx_hash, &pdata, commits, commits_nr, ctx.pack_order, flags) < 0) { error(_("could not write multi-pack bitmap")); @@ -1437,21 +1443,24 @@ static int write_midx_internal(const char *object_dir, if (link_midx_to_chain(ctx.base_midx) < 0) return -1; - get_split_midx_filename_ext(&final_midx_name, object_dir, - midx_hash, MIDX_EXT_MIDX); + get_split_midx_filename_ext(r->hash_algo, &final_midx_name, + object_dir, midx_hash, MIDX_EXT_MIDX); if (rename_tempfile(&incr, final_midx_name.buf) < 0) { error_errno(_("unable to rename new multi-pack-index layer")); return -1; } + strbuf_release(&final_midx_name); + keep_hashes[ctx.num_multi_pack_indexes_before] = - xstrdup(hash_to_hex(midx_hash)); + xstrdup(hash_to_hex_algop(midx_hash, r->hash_algo)); for (i = 0; i < ctx.num_multi_pack_indexes_before; i++) { uint32_t j = ctx.num_multi_pack_indexes_before - i - 1; - keep_hashes[j] = xstrdup(hash_to_hex(get_midx_checksum(m))); + keep_hashes[j] = xstrdup(hash_to_hex_algop(get_midx_checksum(m), + r->hash_algo)); m = m->base_midx; } @@ -1459,16 +1468,16 @@ static int write_midx_internal(const char *object_dir, fprintf(get_lock_file_fp(&lk), "%s\n", keep_hashes[i]); } else { keep_hashes[ctx.num_multi_pack_indexes_before] = - xstrdup(hash_to_hex(midx_hash)); + xstrdup(hash_to_hex_algop(midx_hash, r->hash_algo)); } if (ctx.m || ctx.base_midx) - close_object_store(the_repository->objects); + close_object_store(ctx.repo->objects); if (commit_lock_file(&lk) < 0) die_errno(_("could not write multi-pack-index")); - clear_midx_files(object_dir, keep_hashes, + clear_midx_files(r, object_dir, keep_hashes, ctx.num_multi_pack_indexes_before + 1, ctx.incremental); @@ -1492,27 +1501,26 @@ static int write_midx_internal(const char *object_dir, } strbuf_release(&midx_name); - trace2_region_leave("midx", "write_midx_internal", the_repository); + trace2_region_leave("midx", "write_midx_internal", r); return result; } -int write_midx_file(const char *object_dir, +int write_midx_file(struct repository *r, const char *object_dir, const char *preferred_pack_name, - const char *refs_snapshot, - unsigned flags) + const char *refs_snapshot, unsigned flags) { - return write_midx_internal(object_dir, NULL, NULL, preferred_pack_name, - refs_snapshot, flags); + return write_midx_internal(r, object_dir, NULL, NULL, + preferred_pack_name, refs_snapshot, + flags); } -int write_midx_file_only(const char *object_dir, +int write_midx_file_only(struct repository *r, const char *object_dir, struct string_list *packs_to_include, const char *preferred_pack_name, - const char *refs_snapshot, - unsigned flags) + const char *refs_snapshot, unsigned flags) { - return write_midx_internal(object_dir, packs_to_include, NULL, + return write_midx_internal(r, object_dir, packs_to_include, NULL, preferred_pack_name, refs_snapshot, flags); } @@ -1532,7 +1540,9 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla CALLOC_ARRAY(count, m->num_packs); if (flags & MIDX_PROGRESS) - progress = start_delayed_progress(_("Counting referenced objects"), + progress = start_delayed_progress( + r, + _("Counting referenced objects"), m->num_objects); for (i = 0; i < m->num_objects; i++) { int pack_int_id = nth_midxed_pack_int_id(m, i); @@ -1542,7 +1552,9 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla stop_progress(&progress); if (flags & MIDX_PROGRESS) - progress = start_delayed_progress(_("Finding and deleting unreferenced packfiles"), + progress = start_delayed_progress( + r, + _("Finding and deleting unreferenced packfiles"), m->num_packs); for (i = 0; i < m->num_packs; i++) { char *pack_name; @@ -1569,7 +1581,8 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla free(count); if (packs_to_drop.nr) - result = write_midx_internal(object_dir, NULL, &packs_to_drop, NULL, NULL, flags); + result = write_midx_internal(r, object_dir, NULL, + &packs_to_drop, NULL, NULL, flags); string_list_clear(&packs_to_drop, 0); @@ -1766,7 +1779,8 @@ int midx_repack(struct repository *r, const char *object_dir, size_t batch_size, goto cleanup; } - result = write_midx_internal(object_dir, NULL, NULL, NULL, NULL, flags); + result = write_midx_internal(r, object_dir, NULL, NULL, NULL, NULL, + flags); cleanup: free(include_pack); diff --git a/midx.c b/midx.c index 67e0d64004666d..d91088efb87ca0 100644 --- a/midx.c +++ b/midx.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -25,20 +25,22 @@ int cmp_idx_or_pack_name(const char *idx_or_pack_name, const unsigned char *get_midx_checksum(struct multi_pack_index *m) { - return m->data + m->data_len - the_hash_algo->rawsz; + return m->data + m->data_len - m->repo->hash_algo->rawsz; } -void get_midx_filename(struct strbuf *out, const char *object_dir) +void get_midx_filename(const struct git_hash_algo *hash_algo, + struct strbuf *out, const char *object_dir) { - get_midx_filename_ext(out, object_dir, NULL, NULL); + get_midx_filename_ext(hash_algo, out, object_dir, NULL, NULL); } -void get_midx_filename_ext(struct strbuf *out, const char *object_dir, +void get_midx_filename_ext(const struct git_hash_algo *hash_algo, + struct strbuf *out, const char *object_dir, const unsigned char *hash, const char *ext) { strbuf_addf(out, "%s/pack/multi-pack-index", object_dir); if (ext) - strbuf_addf(out, "-%s.%s", hash_to_hex(hash), ext); + strbuf_addf(out, "-%s.%s", hash_to_hex_algop(hash, hash_algo), ext); } static int midx_read_oid_fanout(const unsigned char *chunk_start, @@ -92,9 +94,8 @@ static int midx_read_object_offsets(const unsigned char *chunk_start, return 0; } -#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + the_hash_algo->rawsz) - -static struct multi_pack_index *load_multi_pack_index_one(const char *object_dir, +static struct multi_pack_index *load_multi_pack_index_one(struct repository *r, + const char *object_dir, const char *midx_name, int local) { @@ -119,7 +120,7 @@ static struct multi_pack_index *load_multi_pack_index_one(const char *object_dir midx_size = xsize_t(st.st_size); - if (midx_size < MIDX_MIN_SIZE) { + if (midx_size < (MIDX_HEADER_SIZE + r->hash_algo->rawsz)) { error(_("multi-pack-index file %s is too small"), midx_name); goto cleanup_fail; } @@ -131,6 +132,7 @@ static struct multi_pack_index *load_multi_pack_index_one(const char *object_dir m->data = midx_map; m->data_len = midx_size; m->local = local; + m->repo = r; m->signature = get_be32(m->data); if (m->signature != MIDX_SIGNATURE) @@ -143,12 +145,12 @@ static struct multi_pack_index *load_multi_pack_index_one(const char *object_dir m->version); hash_version = m->data[MIDX_BYTE_HASH_VERSION]; - if (hash_version != oid_version(the_hash_algo)) { + if (hash_version != oid_version(r->hash_algo)) { error(_("multi-pack-index hash version %u does not match version %u"), - hash_version, oid_version(the_hash_algo)); + hash_version, oid_version(r->hash_algo)); goto cleanup_fail; } - m->hash_len = the_hash_algo->rawsz; + m->hash_len = r->hash_algo->rawsz; m->num_chunks = m->data[MIDX_BYTE_NUM_CHUNKS]; @@ -205,8 +207,8 @@ static struct multi_pack_index *load_multi_pack_index_one(const char *object_dir m->pack_names[i]); } - trace2_data_intmax("midx", the_repository, "load/num_packs", m->num_packs); - trace2_data_intmax("midx", the_repository, "load/num_objects", m->num_objects); + trace2_data_intmax("midx", r, "load/num_packs", m->num_packs); + trace2_data_intmax("midx", r, "load/num_objects", m->num_objects); free_chunkfile(cf); return m; @@ -232,15 +234,18 @@ void get_midx_chain_filename(struct strbuf *buf, const char *object_dir) strbuf_addstr(buf, "/multi-pack-index-chain"); } -void get_split_midx_filename_ext(struct strbuf *buf, const char *object_dir, +void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo, + struct strbuf *buf, const char *object_dir, const unsigned char *hash, const char *ext) { get_midx_chain_dirname(buf, object_dir); - strbuf_addf(buf, "/multi-pack-index-%s.%s", hash_to_hex(hash), ext); + strbuf_addf(buf, "/multi-pack-index-%s.%s", + hash_to_hex_algop(hash, hash_algo), ext); } -static int open_multi_pack_index_chain(const char *chain_file, - int *fd, struct stat *st) +static int open_multi_pack_index_chain(const struct git_hash_algo *hash_algo, + const char *chain_file, int *fd, + struct stat *st) { *fd = git_open(chain_file); if (*fd < 0) @@ -249,7 +254,7 @@ static int open_multi_pack_index_chain(const char *chain_file, close(*fd); return 0; } - if (st->st_size < the_hash_algo->hexsz) { + if (st->st_size < hash_algo->hexsz) { close(*fd); if (!st->st_size) { /* treat empty files the same as missing */ @@ -291,7 +296,8 @@ static int add_midx_to_chain(struct multi_pack_index *midx, return 1; } -static struct multi_pack_index *load_midx_chain_fd_st(const char *object_dir, +static struct multi_pack_index *load_midx_chain_fd_st(struct repository *r, + const char *object_dir, int local, int fd, struct stat *st, int *incomplete_chain) @@ -302,7 +308,7 @@ static struct multi_pack_index *load_midx_chain_fd_st(const char *object_dir, uint32_t i, count; FILE *fp = xfdopen(fd, "r"); - count = st->st_size / (the_hash_algo->hexsz + 1); + count = st->st_size / (r->hash_algo->hexsz + 1); for (i = 0; i < count; i++) { struct multi_pack_index *m; @@ -311,7 +317,7 @@ static struct multi_pack_index *load_midx_chain_fd_st(const char *object_dir, if (strbuf_getline_lf(&buf, fp) == EOF) break; - if (get_oid_hex(buf.buf, &layer)) { + if (get_oid_hex_algop(buf.buf, &layer, r->hash_algo)) { warning(_("invalid multi-pack-index chain: line '%s' " "not a hash"), buf.buf); @@ -322,9 +328,9 @@ static struct multi_pack_index *load_midx_chain_fd_st(const char *object_dir, valid = 0; strbuf_reset(&buf); - get_split_midx_filename_ext(&buf, object_dir, layer.hash, - MIDX_EXT_MIDX); - m = load_multi_pack_index_one(object_dir, buf.buf, local); + get_split_midx_filename_ext(r->hash_algo, &buf, object_dir, + layer.hash, MIDX_EXT_MIDX); + m = load_multi_pack_index_one(r, object_dir, buf.buf, local); if (m) { if (add_midx_to_chain(m, midx_chain)) { @@ -347,7 +353,8 @@ static struct multi_pack_index *load_midx_chain_fd_st(const char *object_dir, return midx_chain; } -static struct multi_pack_index *load_multi_pack_index_chain(const char *object_dir, +static struct multi_pack_index *load_multi_pack_index_chain(struct repository *r, + const char *object_dir, int local) { struct strbuf chain_file = STRBUF_INIT; @@ -356,10 +363,10 @@ static struct multi_pack_index *load_multi_pack_index_chain(const char *object_d struct multi_pack_index *m = NULL; get_midx_chain_filename(&chain_file, object_dir); - if (open_multi_pack_index_chain(chain_file.buf, &fd, &st)) { + if (open_multi_pack_index_chain(r->hash_algo, chain_file.buf, &fd, &st)) { int incomplete; /* ownership of fd is taken over by load function */ - m = load_midx_chain_fd_st(object_dir, local, fd, &st, + m = load_midx_chain_fd_st(r, object_dir, local, fd, &st, &incomplete); } @@ -367,17 +374,19 @@ static struct multi_pack_index *load_multi_pack_index_chain(const char *object_d return m; } -struct multi_pack_index *load_multi_pack_index(const char *object_dir, +struct multi_pack_index *load_multi_pack_index(struct repository *r, + const char *object_dir, int local) { struct strbuf midx_name = STRBUF_INIT; struct multi_pack_index *m; - get_midx_filename(&midx_name, object_dir); + get_midx_filename(r->hash_algo, &midx_name, object_dir); - m = load_multi_pack_index_one(object_dir, midx_name.buf, local); + m = load_multi_pack_index_one(r, object_dir, + midx_name.buf, local); if (!m) - m = load_multi_pack_index_chain(object_dir, local); + m = load_multi_pack_index_chain(r, object_dir, local); strbuf_release(&midx_name); @@ -445,6 +454,7 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id) { struct strbuf pack_name = STRBUF_INIT; + struct strbuf key = STRBUF_INIT; struct packed_git *p; pack_int_id = midx_for_pack(&m, pack_int_id); @@ -455,16 +465,29 @@ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir, m->pack_names[pack_int_id]); - p = add_packed_git(pack_name.buf, pack_name.len, m->local); + /* pack_map holds the ".pack" name, but we have the .idx */ + strbuf_addbuf(&key, &pack_name); + strbuf_strip_suffix(&key, ".idx"); + strbuf_addstr(&key, ".pack"); + p = hashmap_get_entry_from_hash(&r->objects->pack_map, + strhash(key.buf), key.buf, + struct packed_git, packmap_ent); + if (!p) { + p = add_packed_git(r, pack_name.buf, pack_name.len, m->local); + if (p) { + install_packed_git(r, p); + list_add_tail(&p->mru, &r->objects->packed_git_mru); + } + } + strbuf_release(&pack_name); + strbuf_release(&key); if (!p) return 1; p->multi_pack_index = 1; m->packs[pack_int_id] = p; - install_packed_git(r, p); - list_add_tail(&p->mru, &r->objects->packed_git_mru); return 0; } @@ -505,7 +528,7 @@ int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m, uint32_t *result) { int ret = bsearch_hash(oid->hash, m->chunk_oid_fanout, - m->chunk_oid_lookup, the_hash_algo->rawsz, + m->chunk_oid_lookup, m->repo->hash_algo->rawsz, result); if (result) *result += m->num_objects_in_base; @@ -536,7 +559,7 @@ struct object_id *nth_midxed_object_oid(struct object_id *oid, n = midx_for_object(&m, n); oidread(oid, m->chunk_oid_lookup + st_mult(m->hash_len, n), - the_repository->hash_algo); + m->repo->hash_algo); return oid; } @@ -707,7 +730,7 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i if (!strcmp(object_dir, m_search->object_dir)) return 1; - m = load_multi_pack_index(object_dir, local); + m = load_multi_pack_index(r, object_dir, local); if (m) { struct multi_pack_index *mp = r->objects->multi_pack_index; @@ -801,7 +824,7 @@ void clear_midx_file(struct repository *r) { struct strbuf midx = STRBUF_INIT; - get_midx_filename(&midx, r->objects->odb->path); + get_midx_filename(r->hash_algo, &midx, r->objects->odb->path); if (r->objects && r->objects->multi_pack_index) { close_midx(r->objects->multi_pack_index); @@ -861,7 +884,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag struct pair_pos_vs_id *pairs = NULL; uint32_t i; struct progress *progress = NULL; - struct multi_pack_index *m = load_multi_pack_index(object_dir, 1); + struct multi_pack_index *m = load_multi_pack_index(r, object_dir, 1); struct multi_pack_index *curr; verify_midx_error = 0; @@ -870,7 +893,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag struct stat sb; struct strbuf filename = STRBUF_INIT; - get_midx_filename(&filename, object_dir); + get_midx_filename(r->hash_algo, &filename, object_dir); if (!stat(filename.buf, &sb)) { error(_("multi-pack-index file exists, but failed to parse")); @@ -884,7 +907,8 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag midx_report(_("incorrect checksum")); if (flags & MIDX_PROGRESS) - progress = start_delayed_progress(_("Looking for referenced packfiles"), + progress = start_delayed_progress(r, + _("Looking for referenced packfiles"), m->num_packs + m->num_packs_in_base); for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) { if (prepare_midx_pack(r, m, i)) @@ -904,7 +928,8 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag } if (flags & MIDX_PROGRESS) - progress = start_sparse_progress(_("Verifying OID order in multi-pack-index"), + progress = start_sparse_progress(r, + _("Verifying OID order in multi-pack-index"), m->num_objects - 1); for (curr = m; curr; curr = curr->base_midx) { @@ -936,14 +961,17 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag } if (flags & MIDX_PROGRESS) - progress = start_sparse_progress(_("Sorting objects by packfile"), + progress = start_sparse_progress(r, + _("Sorting objects by packfile"), m->num_objects); display_progress(progress, 0); /* TODO: Measure QSORT() progress */ QSORT(pairs, m->num_objects, compare_pair_pos_vs_id); stop_progress(&progress); if (flags & MIDX_PROGRESS) - progress = start_sparse_progress(_("Verifying object offsets"), m->num_objects); + progress = start_sparse_progress(r, + _("Verifying object offsets"), + m->num_objects); for (i = 0; i < m->num_objects + m->num_objects_in_base; i++) { struct object_id oid; struct pack_entry e; @@ -973,7 +1001,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag } m_offset = e.offset; - p_offset = find_pack_entry_one(oid.hash, e.p); + p_offset = find_pack_entry_one(&oid, e.p); if (m_offset != p_offset) midx_report(_("incorrect object offset for oid[%d] = %s: %"PRIx64" != %"PRIx64), diff --git a/midx.h b/midx.h index 42d4f8d149e9a2..9d1374cbd58d01 100644 --- a/midx.h +++ b/midx.h @@ -7,6 +7,7 @@ struct object_id; struct pack_entry; struct repository; struct bitmapped_pack; +struct git_hash_algo; #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 @@ -71,6 +72,9 @@ struct multi_pack_index { const char **pack_names; struct packed_git **packs; + + struct repository *repo; + char object_dir[FLEX_ARRAY]; }; @@ -86,15 +90,20 @@ struct multi_pack_index { #define MIDX_EXT_MIDX "midx" const unsigned char *get_midx_checksum(struct multi_pack_index *m); -void get_midx_filename(struct strbuf *out, const char *object_dir); -void get_midx_filename_ext(struct strbuf *out, const char *object_dir, +void get_midx_filename(const struct git_hash_algo *hash_algo, + struct strbuf *out, const char *object_dir); +void get_midx_filename_ext(const struct git_hash_algo *hash_algo, + struct strbuf *out, const char *object_dir, const unsigned char *hash, const char *ext); void get_midx_chain_dirname(struct strbuf *buf, const char *object_dir); void get_midx_chain_filename(struct strbuf *buf, const char *object_dir); -void get_split_midx_filename_ext(struct strbuf *buf, const char *object_dir, +void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo, + struct strbuf *buf, const char *object_dir, const unsigned char *hash, const char *ext); -struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local); +struct multi_pack_index *load_multi_pack_index(struct repository *r, + const char *object_dir, + int local); int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id); struct packed_git *nth_midxed_pack(struct multi_pack_index *m, uint32_t pack_int_id); @@ -120,15 +129,13 @@ int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, i * Variant of write_midx_file which writes a MIDX containing only the packs * specified in packs_to_include. */ -int write_midx_file(const char *object_dir, - const char *preferred_pack_name, - const char *refs_snapshot, +int write_midx_file(struct repository *r, const char *object_dir, + const char *preferred_pack_name, const char *refs_snapshot, unsigned flags); -int write_midx_file_only(const char *object_dir, +int write_midx_file_only(struct repository *r, const char *object_dir, struct string_list *packs_to_include, const char *preferred_pack_name, - const char *refs_snapshot, - unsigned flags); + const char *refs_snapshot, unsigned flags); void clear_midx_file(struct repository *r); int verify_midx_file(struct repository *r, const char *object_dir, unsigned flags); int expire_midx_packs(struct repository *r, const char *object_dir, unsigned flags); diff --git a/name-hash.c b/name-hash.c index 95528e3bcd2a3e..d66de1cdfd5633 100644 --- a/name-hash.c +++ b/name-hash.c @@ -7,6 +7,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" diff --git a/negotiator/skipping.c b/negotiator/skipping.c index abedb70a48b646..616df6bf3af51c 100644 --- a/negotiator/skipping.c +++ b/negotiator/skipping.c @@ -134,7 +134,6 @@ static int push_parent(struct data *data, struct entry *entry, struct entry *parent_entry; if (to_push->object.flags & SEEN) { - int i; if (to_push->object.flags & POPPED) /* * The entry for this commit has already been popped, @@ -145,7 +144,7 @@ static int push_parent(struct data *data, struct entry *entry, /* * Find the existing entry and use it. */ - for (i = 0; i < data->rev_list.nr; i++) { + for (size_t i = 0; i < data->rev_list.nr; i++) { parent_entry = data->rev_list.array[i].data; if (parent_entry->commit == to_push) goto parent_found; @@ -248,7 +247,7 @@ static int ack(struct fetch_negotiator *n, struct commit *c) static void release(struct fetch_negotiator *n) { struct data *data = n->data; - for (int i = 0; i < data->rev_list.nr; i++) + for (size_t i = 0; i < data->rev_list.nr; i++) free(data->rev_list.array[i].data); clear_prio_queue(&data->rev_list); FREE_AND_NULL(data); diff --git a/notes-merge.c b/notes-merge.c index dadbbabf86da6a..67a472020dedd9 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "advice.h" @@ -274,41 +275,45 @@ static void diff_tree_local(struct notes_merge_options *o, static void check_notes_merge_worktree(struct notes_merge_options *o) { + struct strbuf buf = STRBUF_INIT; + if (!o->has_worktree) { /* * Must establish NOTES_MERGE_WORKTREE. * Abort if NOTES_MERGE_WORKTREE already exists */ - if (file_exists(git_path(NOTES_MERGE_WORKTREE)) && - !is_empty_dir(git_path(NOTES_MERGE_WORKTREE))) { + if (file_exists(repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE)) && + !is_empty_dir(repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE))) { if (advice_enabled(ADVICE_RESOLVE_CONFLICT)) die(_("You have not concluded your previous " "notes merge (%s exists).\nPlease, use " "'git notes merge --commit' or 'git notes " "merge --abort' to commit/abort the " "previous merge before you start a new " - "notes merge."), git_path("NOTES_MERGE_*")); + "notes merge."), repo_git_path_replace(the_repository, &buf, "NOTES_MERGE_*")); else die(_("You have not concluded your notes merge " - "(%s exists)."), git_path("NOTES_MERGE_*")); + "(%s exists)."), repo_git_path_replace(the_repository, &buf, "NOTES_MERGE_*")); } - if (safe_create_leading_directories_const(git_path( + if (safe_create_leading_directories_const(repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE "/.test"))) die_errno("unable to create directory %s", - git_path(NOTES_MERGE_WORKTREE)); + repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE)); o->has_worktree = 1; - } else if (!file_exists(git_path(NOTES_MERGE_WORKTREE))) + } else if (!file_exists(repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE))) /* NOTES_MERGE_WORKTREE should already be established */ die("missing '%s'. This should not happen", - git_path(NOTES_MERGE_WORKTREE)); + repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE)); + + strbuf_release(&buf); } static void write_buf_to_worktree(const struct object_id *obj, const char *buf, unsigned long size) { int fd; - char *path = git_pathdup(NOTES_MERGE_WORKTREE "/%s", oid_to_hex(obj)); + char *path = repo_git_path(the_repository, NOTES_MERGE_WORKTREE "/%s", oid_to_hex(obj)); if (safe_create_leading_directories_const(path)) die_errno("unable to create directory for '%s'", path); @@ -694,7 +699,7 @@ int notes_merge_commit(struct notes_merge_options *o, const char *msg = strstr(buffer, "\n\n"); int baselen; - git_path_buf(&path, NOTES_MERGE_WORKTREE); + repo_git_path_replace(the_repository, &path, NOTES_MERGE_WORKTREE); if (o->verbosity >= 3) printf("Committing notes in notes merge worktree at %s\n", path.buf); @@ -756,7 +761,7 @@ int notes_merge_abort(struct notes_merge_options *o) struct strbuf buf = STRBUF_INIT; int ret; - git_path_buf(&buf, NOTES_MERGE_WORKTREE); + repo_git_path_replace(the_repository, &buf, NOTES_MERGE_WORKTREE); if (o->verbosity >= 3) printf("Removing notes merge worktree at %s/*\n", buf.buf); ret = remove_dir_recursively(&buf, REMOVE_DIR_KEEP_TOPLEVEL); diff --git a/notes.c b/notes.c index f4f18daf07ec52..f5344230505afb 100644 --- a/notes.c +++ b/notes.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" diff --git a/object-file-convert.c b/object-file-convert.c index 3887d6d57b7965..eba71955cf7b88 100644 --- a/object-file-convert.c +++ b/object-file-convert.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" diff --git a/object-file.c b/object-file.c index 7ac9533ab1ee37..726e41a0475b43 100644 --- a/object-file.c +++ b/object-file.c @@ -8,6 +8,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -44,31 +45,18 @@ /* The maximum size for an object header. */ #define MAX_HEADER_LEN 32 - -#define EMPTY_TREE_SHA1_BIN_LITERAL \ - "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \ - "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04" -#define EMPTY_TREE_SHA256_BIN_LITERAL \ - "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \ - "\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \ - "\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \ - "\x53\x21" - -#define EMPTY_BLOB_SHA1_BIN_LITERAL \ - "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \ - "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91" -#define EMPTY_BLOB_SHA256_BIN_LITERAL \ - "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \ - "\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \ - "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \ - "\x18\x13" - static const struct object_id empty_tree_oid = { - .hash = EMPTY_TREE_SHA1_BIN_LITERAL, + .hash = { + 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 + }, .algo = GIT_HASH_SHA1, }; static const struct object_id empty_blob_oid = { - .hash = EMPTY_BLOB_SHA1_BIN_LITERAL, + .hash = { + 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, + 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 + }, .algo = GIT_HASH_SHA1, }; static const struct object_id null_oid_sha1 = { @@ -76,11 +64,21 @@ static const struct object_id null_oid_sha1 = { .algo = GIT_HASH_SHA1, }; static const struct object_id empty_tree_oid_sha256 = { - .hash = EMPTY_TREE_SHA256_BIN_LITERAL, + .hash = { + 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, + 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, + 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, + 0x53, 0x21 + }, .algo = GIT_HASH_SHA256, }; static const struct object_id empty_blob_oid_sha256 = { - .hash = EMPTY_BLOB_SHA256_BIN_LITERAL, + .hash = { + 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, + 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, + 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, + 0x18, 0x13 + }, .algo = GIT_HASH_SHA256, }; static const struct object_id null_oid_sha256 = { @@ -88,57 +86,90 @@ static const struct object_id null_oid_sha256 = { .algo = GIT_HASH_SHA256, }; -static void git_hash_sha1_init(git_hash_ctx *ctx) +static void git_hash_sha1_init(struct git_hash_ctx *ctx) { - git_SHA1_Init(&ctx->sha1); + ctx->algop = &hash_algos[GIT_HASH_SHA1]; + git_SHA1_Init(&ctx->state.sha1); } -static void git_hash_sha1_clone(git_hash_ctx *dst, const git_hash_ctx *src) +static void git_hash_sha1_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src) { - git_SHA1_Clone(&dst->sha1, &src->sha1); + dst->algop = src->algop; + git_SHA1_Clone(&dst->state.sha1, &src->state.sha1); } -static void git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len) +static void git_hash_sha1_update(struct git_hash_ctx *ctx, const void *data, size_t len) { - git_SHA1_Update(&ctx->sha1, data, len); + git_SHA1_Update(&ctx->state.sha1, data, len); } -static void git_hash_sha1_final(unsigned char *hash, git_hash_ctx *ctx) +static void git_hash_sha1_final(unsigned char *hash, struct git_hash_ctx *ctx) { - git_SHA1_Final(hash, &ctx->sha1); + git_SHA1_Final(hash, &ctx->state.sha1); } -static void git_hash_sha1_final_oid(struct object_id *oid, git_hash_ctx *ctx) +static void git_hash_sha1_final_oid(struct object_id *oid, struct git_hash_ctx *ctx) { - git_SHA1_Final(oid->hash, &ctx->sha1); + git_SHA1_Final(oid->hash, &ctx->state.sha1); memset(oid->hash + GIT_SHA1_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ); oid->algo = GIT_HASH_SHA1; } +static void git_hash_sha1_init_unsafe(struct git_hash_ctx *ctx) +{ + ctx->algop = unsafe_hash_algo(&hash_algos[GIT_HASH_SHA1]); + git_SHA1_Init_unsafe(&ctx->state.sha1_unsafe); +} -static void git_hash_sha256_init(git_hash_ctx *ctx) +static void git_hash_sha1_clone_unsafe(struct git_hash_ctx *dst, const struct git_hash_ctx *src) { - git_SHA256_Init(&ctx->sha256); + dst->algop = src->algop; + git_SHA1_Clone_unsafe(&dst->state.sha1_unsafe, &src->state.sha1_unsafe); } -static void git_hash_sha256_clone(git_hash_ctx *dst, const git_hash_ctx *src) +static void git_hash_sha1_update_unsafe(struct git_hash_ctx *ctx, const void *data, + size_t len) { - git_SHA256_Clone(&dst->sha256, &src->sha256); + git_SHA1_Update_unsafe(&ctx->state.sha1_unsafe, data, len); } -static void git_hash_sha256_update(git_hash_ctx *ctx, const void *data, size_t len) +static void git_hash_sha1_final_unsafe(unsigned char *hash, struct git_hash_ctx *ctx) { - git_SHA256_Update(&ctx->sha256, data, len); + git_SHA1_Final_unsafe(hash, &ctx->state.sha1_unsafe); } -static void git_hash_sha256_final(unsigned char *hash, git_hash_ctx *ctx) +static void git_hash_sha1_final_oid_unsafe(struct object_id *oid, struct git_hash_ctx *ctx) { - git_SHA256_Final(hash, &ctx->sha256); + git_SHA1_Final_unsafe(oid->hash, &ctx->state.sha1_unsafe); + memset(oid->hash + GIT_SHA1_RAWSZ, 0, GIT_MAX_RAWSZ - GIT_SHA1_RAWSZ); + oid->algo = GIT_HASH_SHA1; } -static void git_hash_sha256_final_oid(struct object_id *oid, git_hash_ctx *ctx) +static void git_hash_sha256_init(struct git_hash_ctx *ctx) { - git_SHA256_Final(oid->hash, &ctx->sha256); + ctx->algop = unsafe_hash_algo(&hash_algos[GIT_HASH_SHA256]); + git_SHA256_Init(&ctx->state.sha256); +} + +static void git_hash_sha256_clone(struct git_hash_ctx *dst, const struct git_hash_ctx *src) +{ + dst->algop = src->algop; + git_SHA256_Clone(&dst->state.sha256, &src->state.sha256); +} + +static void git_hash_sha256_update(struct git_hash_ctx *ctx, const void *data, size_t len) +{ + git_SHA256_Update(&ctx->state.sha256, data, len); +} + +static void git_hash_sha256_final(unsigned char *hash, struct git_hash_ctx *ctx) +{ + git_SHA256_Final(hash, &ctx->state.sha256); +} + +static void git_hash_sha256_final_oid(struct object_id *oid, struct git_hash_ctx *ctx) +{ + git_SHA256_Final(oid->hash, &ctx->state.sha256); /* * This currently does nothing, so the compiler should optimize it out, * but keep it in case we extend the hash size again. @@ -147,18 +178,18 @@ static void git_hash_sha256_final_oid(struct object_id *oid, git_hash_ctx *ctx) oid->algo = GIT_HASH_SHA256; } -static void git_hash_unknown_init(git_hash_ctx *ctx UNUSED) +static void git_hash_unknown_init(struct git_hash_ctx *ctx UNUSED) { BUG("trying to init unknown hash"); } -static void git_hash_unknown_clone(git_hash_ctx *dst UNUSED, - const git_hash_ctx *src UNUSED) +static void git_hash_unknown_clone(struct git_hash_ctx *dst UNUSED, + const struct git_hash_ctx *src UNUSED) { BUG("trying to clone unknown hash"); } -static void git_hash_unknown_update(git_hash_ctx *ctx UNUSED, +static void git_hash_unknown_update(struct git_hash_ctx *ctx UNUSED, const void *data UNUSED, size_t len UNUSED) { @@ -166,17 +197,33 @@ static void git_hash_unknown_update(git_hash_ctx *ctx UNUSED, } static void git_hash_unknown_final(unsigned char *hash UNUSED, - git_hash_ctx *ctx UNUSED) + struct git_hash_ctx *ctx UNUSED) { BUG("trying to finalize unknown hash"); } static void git_hash_unknown_final_oid(struct object_id *oid UNUSED, - git_hash_ctx *ctx UNUSED) + struct git_hash_ctx *ctx UNUSED) { BUG("trying to finalize unknown hash"); } +static const struct git_hash_algo sha1_unsafe_algo = { + .name = "sha1", + .format_id = GIT_SHA1_FORMAT_ID, + .rawsz = GIT_SHA1_RAWSZ, + .hexsz = GIT_SHA1_HEXSZ, + .blksz = GIT_SHA1_BLKSZ, + .init_fn = git_hash_sha1_init_unsafe, + .clone_fn = git_hash_sha1_clone_unsafe, + .update_fn = git_hash_sha1_update_unsafe, + .final_fn = git_hash_sha1_final_unsafe, + .final_oid_fn = git_hash_sha1_final_oid_unsafe, + .empty_tree = &empty_tree_oid, + .empty_blob = &empty_blob_oid, + .null_oid = &null_oid_sha1, +}; + const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { { .name = NULL, @@ -204,6 +251,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { .update_fn = git_hash_sha1_update, .final_fn = git_hash_sha1_final, .final_oid_fn = git_hash_sha1_final_oid, + .unsafe = &sha1_unsafe_algo, .empty_tree = &empty_tree_oid, .empty_blob = &empty_blob_oid, .null_oid = &null_oid_sha1, @@ -265,36 +313,43 @@ int hash_algo_by_length(int len) return GIT_HASH_UNKNOWN; } +const struct git_hash_algo *unsafe_hash_algo(const struct git_hash_algo *algop) +{ + /* If we have a faster "unsafe" implementation, use that. */ + if (algop->unsafe) + return algop->unsafe; + /* Otherwise use the default one. */ + return algop; +} + /* * This is meant to hold a *small* number of objects that you would * want repo_read_object_file() to be able to return, but yet you do not want * to write them into the object store (e.g. a browse-only * application). */ -static struct cached_object { +static struct cached_object_entry { struct object_id oid; - enum object_type type; - const void *buf; - unsigned long size; + struct cached_object { + enum object_type type; + const void *buf; + unsigned long size; + } value; } *cached_objects; static int cached_object_nr, cached_object_alloc; -static struct cached_object empty_tree = { - .oid = { - .hash = EMPTY_TREE_SHA1_BIN_LITERAL, - }, - .type = OBJ_TREE, - .buf = "", -}; - -static struct cached_object *find_cached_object(const struct object_id *oid) +static const struct cached_object *find_cached_object(const struct object_id *oid) { + static const struct cached_object empty_tree = { + .type = OBJ_TREE, + .buf = "", + }; int i; - struct cached_object *co = cached_objects; + const struct cached_object_entry *co = cached_objects; for (i = 0; i < cached_object_nr; i++, co++) { if (oideq(&co->oid, oid)) - return co; + return &co->value; } if (oideq(oid, the_hash_algo->empty_tree)) return &empty_tree; @@ -339,7 +394,7 @@ int mkdir_in_gitdir(const char *path) } strbuf_release(&sb); } - return adjust_shared_perm(path); + return adjust_shared_perm(the_repository, path); } static enum scld_error safe_create_leading_directories_1(char *path, int share) @@ -388,7 +443,7 @@ static enum scld_error safe_create_leading_directories_1(char *path, int share) ret = SCLD_VANISHED; else ret = SCLD_FAILED; - } else if (share && adjust_shared_perm(path)) { + } else if (share && adjust_shared_perm(the_repository, path)) { ret = SCLD_PERMS; } *slash = slash_character; @@ -427,14 +482,14 @@ int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) * restrictive except to remove write permission. */ int mode = 0444; - git_path_buf(temp_filename, "objects/%s", pattern); + repo_git_path_replace(the_repository, temp_filename, "objects/%s", pattern); fd = git_mkstemp_mode(temp_filename->buf, mode); if (0 <= fd) return fd; /* slow path */ /* some mkstemp implementations erase temp_filename on failure */ - git_path_buf(temp_filename, "objects/%s", pattern); + repo_git_path_replace(the_repository, temp_filename, "objects/%s", pattern); safe_create_leading_directories(temp_filename->buf); return xmkstemp_mode(temp_filename->buf, mode); } @@ -668,7 +723,7 @@ static void read_info_alternates(struct repository *r, void add_to_alternates_file(const char *reference) { struct lock_file lock = LOCK_INIT; - char *alts = git_pathdup("objects/info/alternates"); + char *alts = repo_git_path(the_repository, "objects/info/alternates"); FILE *in, *out; int found = 0; @@ -1131,7 +1186,7 @@ int stream_object_signature(struct repository *r, const struct object_id *oid) unsigned long size; enum object_type obj_type; struct git_istream *st; - git_hash_ctx c; + struct git_hash_ctx c; char hdr[MAX_HEADER_LEN]; int hdrlen; @@ -1144,7 +1199,7 @@ int stream_object_signature(struct repository *r, const struct object_id *oid) /* Sha1.. */ r->hash_algo->init_fn(&c); - r->hash_algo->update_fn(&c, hdr, hdrlen); + git_hash_update(&c, hdr, hdrlen); for (;;) { char buf[1024 * 16]; ssize_t readlen = read_istream(st, buf, sizeof(buf)); @@ -1155,9 +1210,9 @@ int stream_object_signature(struct repository *r, const struct object_id *oid) } if (!readlen) break; - r->hash_algo->update_fn(&c, buf, readlen); + git_hash_update(&c, buf, readlen); } - r->hash_algo->final_oid_fn(&real_oid, &c); + git_hash_final_oid(&real_oid, &c); close_istream(st); return !oideq(oid, &real_oid) ? -1 : 0; } @@ -1585,7 +1640,7 @@ static int do_oid_object_info_extended(struct repository *r, struct object_info *oi, unsigned flags) { static struct object_info blank_oi = OBJECT_INFO_INIT; - struct cached_object *co; + const struct cached_object *co; struct pack_entry e; int rtype; const struct object_id *real = oid; @@ -1807,7 +1862,7 @@ int oid_object_info(struct repository *r, int pretend_object_file(void *buf, unsigned long len, enum object_type type, struct object_id *oid) { - struct cached_object *co; + struct cached_object_entry *co; char *co_buf; hash_object_file(the_hash_algo, buf, len, type, oid); @@ -1816,11 +1871,11 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type, return 0; ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc); co = &cached_objects[cached_object_nr++]; - co->size = len; - co->type = type; + co->value.size = len; + co->value.type = type; co_buf = xmalloc(len); memcpy(co_buf, buf, len); - co->buf = co_buf; + co->value.buf = co_buf; oidcpy(&co->oid, oid); return 0; } @@ -1896,15 +1951,15 @@ void *read_object_with_reference(struct repository *r, } } -static void hash_object_body(const struct git_hash_algo *algo, git_hash_ctx *c, +static void hash_object_body(const struct git_hash_algo *algo, struct git_hash_ctx *c, const void *buf, unsigned long len, struct object_id *oid, char *hdr, int *hdrlen) { algo->init_fn(c); - algo->update_fn(c, hdr, *hdrlen); - algo->update_fn(c, buf, len); - algo->final_oid_fn(oid, c); + git_hash_update(c, hdr, *hdrlen); + git_hash_update(c, buf, len); + git_hash_final_oid(oid, c); } static void write_object_file_prepare(const struct git_hash_algo *algo, @@ -1912,7 +1967,7 @@ static void write_object_file_prepare(const struct git_hash_algo *algo, enum object_type type, struct object_id *oid, char *hdr, int *hdrlen) { - git_hash_ctx c; + struct git_hash_ctx c; /* Generate the header */ *hdrlen = format_object_header(hdr, *hdrlen, type, len); @@ -1926,23 +1981,91 @@ static void write_object_file_prepare_literally(const struct git_hash_algo *algo const char *type, struct object_id *oid, char *hdr, int *hdrlen) { - git_hash_ctx c; + struct git_hash_ctx c; *hdrlen = format_object_header_literally(hdr, *hdrlen, type, len); hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen); } +#define CHECK_COLLISION_DEST_VANISHED -2 + +static int check_collision(const char *source, const char *dest) +{ + char buf_source[4096], buf_dest[4096]; + int fd_source = -1, fd_dest = -1; + int ret = 0; + + fd_source = open(source, O_RDONLY); + if (fd_source < 0) { + ret = error_errno(_("unable to open %s"), source); + goto out; + } + + fd_dest = open(dest, O_RDONLY); + if (fd_dest < 0) { + if (errno != ENOENT) + ret = error_errno(_("unable to open %s"), dest); + else + ret = CHECK_COLLISION_DEST_VANISHED; + goto out; + } + + while (1) { + ssize_t sz_a, sz_b; + + sz_a = read_in_full(fd_source, buf_source, sizeof(buf_source)); + if (sz_a < 0) { + ret = error_errno(_("unable to read %s"), source); + goto out; + } + + sz_b = read_in_full(fd_dest, buf_dest, sizeof(buf_dest)); + if (sz_b < 0) { + ret = error_errno(_("unable to read %s"), dest); + goto out; + } + + if (sz_a != sz_b || memcmp(buf_source, buf_dest, sz_a)) { + ret = error(_("files '%s' and '%s' differ in contents"), + source, dest); + goto out; + } + + if (sz_a < sizeof(buf_source)) + break; + } + +out: + if (fd_source > -1) + close(fd_source); + if (fd_dest > -1) + close(fd_dest); + return ret; +} + /* * Move the just written object into its final resting place. */ int finalize_object_file(const char *tmpfile, const char *filename) { - int ret = 0; + return finalize_object_file_flags(tmpfile, filename, 0); +} + +int finalize_object_file_flags(const char *tmpfile, const char *filename, + enum finalize_object_file_flags flags) +{ + unsigned retries = 0; + int ret; + +retry: + ret = 0; if (object_creation_mode == OBJECT_CREATION_USES_RENAMES) goto try_rename; else if (link(tmpfile, filename)) ret = errno; + else + unlink_or_warn(tmpfile); /* * Coda hack - coda doesn't like cross-directory links, @@ -1956,21 +2079,39 @@ int finalize_object_file(const char *tmpfile, const char *filename) * left to unlink. */ if (ret && ret != EEXIST) { + struct stat st; + try_rename: - if (!rename(tmpfile, filename)) + if (!stat(filename, &st)) + ret = EEXIST; + else if (!rename(tmpfile, filename)) goto out; - ret = errno; + else + ret = errno; } - unlink_or_warn(tmpfile); if (ret) { if (ret != EEXIST) { + int saved_errno = errno; + unlink_or_warn(tmpfile); + errno = saved_errno; return error_errno(_("unable to write file %s"), filename); } - /* FIXME!!! Collision check here ? */ + if (!(flags & FOF_SKIP_COLLISION_CHECK)) { + ret = check_collision(tmpfile, filename); + if (ret == CHECK_COLLISION_DEST_VANISHED) { + if (retries++ > 5) + return error(_("unable to write repeatedly vanishing file %s"), + filename); + goto retry; + } + else if (ret) + return -1; + } + unlink_or_warn(tmpfile); } out: - if (adjust_shared_perm(filename)) + if (adjust_shared_perm(the_repository, filename)) return error(_("unable to set permission to '%s'"), filename); return 0; } @@ -2046,7 +2187,7 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) strbuf_add(tmp, filename, dirlen - 1); if (mkdir(tmp->buf, 0777) && errno != EEXIST) return -1; - if (adjust_shared_perm(tmp->buf)) + if (adjust_shared_perm(the_repository, tmp->buf)) return -1; /* Try again */ @@ -2071,7 +2212,7 @@ static int start_loose_object_common(struct strbuf *tmp_file, const char *filename, unsigned flags, git_zstream *stream, unsigned char *buf, size_t buflen, - git_hash_ctx *c, git_hash_ctx *compat_c, + struct git_hash_ctx *c, struct git_hash_ctx *compat_c, char *hdr, int hdrlen) { struct repository *repo = the_repository; @@ -2105,9 +2246,9 @@ static int start_loose_object_common(struct strbuf *tmp_file, stream->avail_in = hdrlen; while (git_deflate(stream, 0) == Z_OK) ; /* nothing */ - algo->update_fn(c, hdr, hdrlen); + git_hash_update(c, hdr, hdrlen); if (compat && compat_c) - compat->update_fn(compat_c, hdr, hdrlen); + git_hash_update(compat_c, hdr, hdrlen); return fd; } @@ -2116,21 +2257,20 @@ static int start_loose_object_common(struct strbuf *tmp_file, * Common steps for the inner git_deflate() loop for writing loose * objects. Returns what git_deflate() returns. */ -static int write_loose_object_common(git_hash_ctx *c, git_hash_ctx *compat_c, +static int write_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx *compat_c, git_zstream *stream, const int flush, unsigned char *in0, const int fd, unsigned char *compressed, const size_t compressed_len) { struct repository *repo = the_repository; - const struct git_hash_algo *algo = repo->hash_algo; const struct git_hash_algo *compat = repo->compat_hash_algo; int ret; ret = git_deflate(stream, flush ? Z_FINISH : 0); - algo->update_fn(c, in0, stream->next_in - in0); + git_hash_update(c, in0, stream->next_in - in0); if (compat && compat_c) - compat->update_fn(compat_c, in0, stream->next_in - in0); + git_hash_update(compat_c, in0, stream->next_in - in0); if (write_in_full(fd, compressed, stream->next_out - compressed) < 0) die_errno(_("unable to write loose object file")); stream->next_out = compressed; @@ -2145,21 +2285,20 @@ static int write_loose_object_common(git_hash_ctx *c, git_hash_ctx *compat_c, * - End the compression of zlib stream. * - Get the calculated oid to "oid". */ -static int end_loose_object_common(git_hash_ctx *c, git_hash_ctx *compat_c, +static int end_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx *compat_c, git_zstream *stream, struct object_id *oid, struct object_id *compat_oid) { struct repository *repo = the_repository; - const struct git_hash_algo *algo = repo->hash_algo; const struct git_hash_algo *compat = repo->compat_hash_algo; int ret; ret = git_deflate_end_gently(stream); if (ret != Z_OK) return ret; - algo->final_oid_fn(oid, c); + git_hash_final_oid(oid, c); if (compat && compat_c) - compat->final_oid_fn(compat_oid, compat_c); + git_hash_final_oid(compat_oid, compat_c); return Z_OK; } @@ -2171,7 +2310,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, int fd, ret; unsigned char compressed[4096]; git_zstream stream; - git_hash_ctx c; + struct git_hash_ctx c; struct object_id parano_oid; static struct strbuf tmp_file = STRBUF_INIT; static struct strbuf filename = STRBUF_INIT; @@ -2219,7 +2358,8 @@ static int write_loose_object(const struct object_id *oid, char *hdr, warning_errno(_("failed utime() on %s"), tmp_file.buf); } - return finalize_object_file(tmp_file.buf, filename.buf); + return finalize_object_file_flags(tmp_file.buf, filename.buf, + FOF_SKIP_COLLISION_CHECK); } static int freshen_loose_object(const struct object_id *oid) @@ -2250,7 +2390,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, int fd, ret, err = 0, flush = 0; unsigned char compressed[4096]; git_zstream stream; - git_hash_ctx c, compat_c; + struct git_hash_ctx c, compat_c; struct strbuf tmp_file = STRBUF_INIT; struct strbuf filename = STRBUF_INIT; int dirlen; @@ -2341,7 +2481,8 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, strbuf_release(&dir); } - err = finalize_object_file(tmp_file.buf, filename.buf); + err = finalize_object_file_flags(tmp_file.buf, filename.buf, + FOF_SKIP_COLLISION_CHECK); if (!err && compat) err = repo_add_loose_object_map(the_repository, oid, &compat_oid); cleanup: @@ -2909,14 +3050,14 @@ static int check_stream_oid(git_zstream *stream, const char *path, const struct object_id *expected_oid) { - git_hash_ctx c; + struct git_hash_ctx c; struct object_id real_oid; unsigned char buf[4096]; unsigned long total_read; int status = Z_OK; the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, hdr, stream->total_out); + git_hash_update(&c, hdr, stream->total_out); /* * We already read some bytes into hdr, but the ones up to the NUL @@ -2936,7 +3077,7 @@ static int check_stream_oid(git_zstream *stream, if (size - total_read < stream->avail_out) stream->avail_out = size - total_read; status = git_inflate(stream, Z_FINISH); - the_hash_algo->update_fn(&c, buf, stream->next_out - buf); + git_hash_update(&c, buf, stream->next_out - buf); total_read += stream->next_out - buf; } git_inflate_end(stream); @@ -2951,7 +3092,7 @@ static int check_stream_oid(git_zstream *stream, return -1; } - the_hash_algo->final_oid_fn(&real_oid, &c); + git_hash_final_oid(&real_oid, &c); if (!oideq(expected_oid, &real_oid)) { error(_("hash mismatch for %s (expected %s)"), path, oid_to_hex(expected_oid)); diff --git a/object-file.h b/object-file.h index d6414610f80b73..81b30d269c82e4 100644 --- a/object-file.h +++ b/object-file.h @@ -117,7 +117,13 @@ int check_object_signature(struct repository *r, const struct object_id *oid, */ int stream_object_signature(struct repository *r, const struct object_id *oid); +enum finalize_object_file_flags { + FOF_SKIP_COLLISION_CHECK = 1, +}; + int finalize_object_file(const char *tmpfile, const char *filename); +int finalize_object_file_flags(const char *tmpfile, const char *filename, + enum finalize_object_file_flags flags); /* Helper to check and "touch" a file */ int check_and_freshen_file(const char *fn, int freshen); diff --git a/object-name.c b/object-name.c index c892fbe80aa717..76749fbfe652bf 100644 --- a/object-name.c +++ b/object-name.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "object-name.h" @@ -952,7 +953,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len, "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" - "running \"git config advice.objectNameWarning false\""); + "running \"git config set advice.objectNameWarning false\""); struct object_id tmp_oid; char *real_ref = NULL; int refs_found = 0; @@ -1271,6 +1272,58 @@ static int peel_onion(struct repository *r, const char *name, int len, return 0; } +/* + * Documentation/revisions.adoc says: + * '<describeOutput>', e.g. 'v1.7.4.2-679-g3bee7fb':: + * Output from `git describe`; i.e. a closest tag, optionally + * followed by a dash and a number of commits, followed by a dash, a + * 'g', and an abbreviated object name. + * + * which means that the stuff before '-g${HASH}' needs to be a valid + * refname, a dash, and a non-negative integer. This function verifies + * that. + * + * In particular, we do not want to treat + * branchname:path/to/file/named/i-gaffed + * as a request for commit affed. + * + * More generally, we should probably not treat + * 'refs/heads/./../.../ ~^:/?*[////\\\&}/busted.lock-g050e0ef6ead' + * as a request for object 050e0ef6ead either. + * + * We are called with name[len] == '-' and name[len+1] == 'g', i.e. + * we are verifying ${REFNAME}-{INTEGER} part of the name. + */ +static int ref_and_count_parts_valid(const char *name, int len) +{ + struct strbuf sb; + const char *cp; + int flags = REFNAME_ALLOW_ONELEVEL; + int ret = 1; + + /* Ensure we have at least one digit */ + if (!isxdigit(name[len-1])) + return 0; + + /* Skip over digits backwards until we get to the dash */ + for (cp = name + len - 2; name < cp; cp--) { + if (*cp == '-') + break; + if (!isxdigit(*cp)) + return 0; + } + /* Ensure we found the leading dash */ + if (*cp != '-') + return 0; + + len = cp - name; + strbuf_init(&sb, len); + strbuf_add(&sb, name, len); + ret = !check_refname_format(sb.buf, flags); + strbuf_release(&sb); + return ret; +} + static int get_describe_name(struct repository *r, const char *name, int len, struct object_id *oid) @@ -1284,7 +1337,8 @@ static int get_describe_name(struct repository *r, /* We must be looking at g in "SOMETHING-g" * for it to be describe output. */ - if (ch == 'g' && cp[-1] == '-') { + if (ch == 'g' && cp[-1] == '-' && + ref_and_count_parts_valid(name, cp - 1 - name)) { cp++; len -= cp - name; return get_short_oid(r, @@ -1401,7 +1455,7 @@ static int get_oid_oneline(struct repository *r, const char *prefix, struct object_id *oid, const struct commit_list *list) { - struct commit_list *copy = NULL; + struct commit_list *copy = NULL, **copy_tail = © const struct commit_list *l; int found = 0; int negative = 0; @@ -1423,7 +1477,7 @@ static int get_oid_oneline(struct repository *r, for (l = list; l; l = l->next) { l->item->object.flags |= ONELINE_SEEN; - commit_list_insert(l->item, ©); + copy_tail = &commit_list_insert(l->item, copy_tail)->next; } while (copy) { const char *p, *buf; @@ -1734,42 +1788,6 @@ int repo_interpret_branch_name(struct repository *r, return -1; } -void strbuf_branchname(struct strbuf *sb, const char *name, unsigned allowed) -{ - int len = strlen(name); - struct interpret_branch_name_options options = { - .allowed = allowed - }; - int used = repo_interpret_branch_name(the_repository, name, len, sb, - &options); - - if (used < 0) - used = 0; - strbuf_add(sb, name + used, len - used); -} - -int strbuf_check_branch_ref(struct strbuf *sb, const char *name) -{ - if (startup_info->have_repository) - strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL); - else - strbuf_addstr(sb, name); - - /* - * This splice must be done even if we end up rejecting the - * name; builtin/branch.c::copy_or_rename_branch() still wants - * to see what the name expanded to so that "branch -m" can be - * used as a tool to correct earlier mistakes. - */ - strbuf_splice(sb, 0, 0, "refs/heads/", 11); - - if (*name == '-' || - !strcmp(sb->buf, "refs/heads/HEAD")) - return -1; - - return check_refname_format(sb->buf, 0); -} - void object_context_release(struct object_context *ctx) { free(ctx->path); @@ -2087,12 +2105,14 @@ static enum get_oid_result get_oid_with_context_1(struct repository *repo, return -1; } for (cp = name, bracket_depth = 0; *cp; cp++) { - if (*cp == '{') + if (strchr("@^", *cp) && cp[1] == '{') { + cp++; bracket_depth++; - else if (bracket_depth && *cp == '}') + } else if (bracket_depth && *cp == '}') { bracket_depth--; - else if (!bracket_depth && *cp == ':') + } else if (!bracket_depth && *cp == ':') { break; + } } if (*cp == ':') { struct object_id tree_oid; diff --git a/object-store-ll.h b/object-store-ll.h index 53b8e693b1b74f..cd3bd5bd99f78c 100644 --- a/object-store-ll.h +++ b/object-store-ll.h @@ -10,6 +10,7 @@ struct oidmap; struct oidtree; struct strbuf; +struct repository; struct object_directory { struct object_directory *next; @@ -135,6 +136,10 @@ struct packed_git { */ const uint32_t *mtimes_map; size_t mtimes_size; + + /* repo denotes the repository this packfile belongs to */ + struct repository *repo; + /* something like ".git/objects/pack/xxxxx.pack" */ char pack_name[FLEX_ARRAY]; /* more */ }; @@ -545,7 +550,7 @@ typedef int each_packed_object_fn(const struct object_id *oid, int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn, void *data, enum for_each_object_flags flags); -int for_each_packed_object(each_packed_object_fn, void *, - enum for_each_object_flags flags); +int for_each_packed_object(struct repository *repo, each_packed_object_fn cb, + void *data, enum for_each_object_flags flags); #endif /* OBJECT_STORE_LL_H */ diff --git a/object.c b/object.c index 94ea8fb8d2c4f9..100bf9b8d12beb 100644 --- a/object.c +++ b/object.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" diff --git a/oidtree.c b/oidtree.c index 92d03b52dbe13f..151568f74fbf13 100644 --- a/oidtree.c +++ b/oidtree.c @@ -47,7 +47,7 @@ void oidtree_insert(struct oidtree *ot, const struct object_id *oid) /* * n.b. Current callers won't get us duplicates, here. If a - * future caller causes duplicates, there'll be a a small leak + * future caller causes duplicates, there'll be a small leak * that won't be freed until oidtree_clear. Currently it's not * worth maintaining a free list */ diff --git a/oss-fuzz/.gitignore b/oss-fuzz/.gitignore index a877c11f42b2d2..f2d74de457259d 100644 --- a/oss-fuzz/.gitignore +++ b/oss-fuzz/.gitignore @@ -1,5 +1,8 @@ fuzz-commit-graph fuzz-config +fuzz-credential-from-url-gently fuzz-date fuzz-pack-headers fuzz-pack-idx +fuzz-parse-attr-line +fuzz-url-decode-mem diff --git a/oss-fuzz/fuzz-credential-from-url-gently.c b/oss-fuzz/fuzz-credential-from-url-gently.c new file mode 100644 index 00000000000000..c872f9ad2d123e --- /dev/null +++ b/oss-fuzz/fuzz-credential-from-url-gently.c @@ -0,0 +1,32 @@ +#include "git-compat-util.h" +#include <stddef.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include "credential.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct credential c; + char *buf; + + buf = malloc(size + 1); + if (!buf) + return 0; + + memcpy(buf, data, size); + buf[size] = 0; + + // start fuzzing + credential_init(&c); + credential_from_url_gently(&c, buf, 1); + + // cleanup + credential_clear(&c); + free(buf); + + return 0; +} diff --git a/oss-fuzz/fuzz-parse-attr-line.c b/oss-fuzz/fuzz-parse-attr-line.c new file mode 100644 index 00000000000000..315198505c876b --- /dev/null +++ b/oss-fuzz/fuzz-parse-attr-line.c @@ -0,0 +1,41 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + +#include "git-compat-util.h" +#include <stddef.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include "attr.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct match_attr *res; + char *buf; + + buf = malloc(size + 1); + if (!buf) + return 0; + + memcpy(buf, data, size); + buf[size] = 0; + + res = parse_attr_line(buf, "dummy", 0, 0); + + if (res) { + size_t j; + for (j = 0; j < res->num_attr; j++) { + const char *setto = res->state[j].setto; + if (ATTR_TRUE(setto) || ATTR_FALSE(setto) || + ATTR_UNSET(setto)) + ; + else + free((char *)setto); + } + free(res); + } + free(buf); + + return 0; +} diff --git a/oss-fuzz/fuzz-url-decode-mem.c b/oss-fuzz/fuzz-url-decode-mem.c new file mode 100644 index 00000000000000..2342aa993b8aef --- /dev/null +++ b/oss-fuzz/fuzz-url-decode-mem.c @@ -0,0 +1,43 @@ +#include "git-compat-util.h" +#include <stddef.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include "url.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char *buf; + char *r; + const char *pbuf; + + buf = malloc(size + 1); + if (!buf) + return 0; + + memcpy(buf, data, size); + buf[size] = 0; + + // start fuzzing + r = url_decode(buf); + free(r); + + r = url_percent_decode(buf); + free(r); + + pbuf = (const char*) buf; + r = url_decode_parameter_name(&pbuf); + free(r); + + pbuf = (const char*) buf; + r = url_decode_parameter_value(&pbuf); + free(r); + + // cleanup + free(buf); + + return 0; +} diff --git a/oss-fuzz/meson.build b/oss-fuzz/meson.build new file mode 100644 index 00000000000000..878afd8426fd01 --- /dev/null +++ b/oss-fuzz/meson.build @@ -0,0 +1,20 @@ +fuzz_programs = [ + 'fuzz-commit-graph.c', + 'fuzz-config.c', + 'fuzz-credential-from-url-gently.c', + 'fuzz-date.c', + 'fuzz-pack-headers.c', + 'fuzz-pack-idx.c', + 'fuzz-parse-attr-line.c', + 'fuzz-url-decode-mem.c', +] + +foreach fuzz_program : fuzz_programs + executable(fs.stem(fuzz_program), + sources: [ + 'dummy-cmd-main.c', + fuzz_program, + ], + dependencies: [libgit_commonmain], + ) +endforeach diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index 4dc0fe8e404347..34e86d49947d23 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" @@ -64,6 +65,12 @@ static void free_pseudo_merge_commit_idx(struct pseudo_merge_commit_idx *idx) free(idx); } +static void pseudo_merge_group_release_cb(void *payload, const char *name UNUSED) +{ + pseudo_merge_group_release(payload); + free(payload); +} + void bitmap_writer_free(struct bitmap_writer *writer) { uint32_t i; @@ -82,6 +89,8 @@ void bitmap_writer_free(struct bitmap_writer *writer) kh_foreach_value(writer->pseudo_merge_commits, idx, free_pseudo_merge_commit_idx(idx)); kh_destroy_oid_map(writer->pseudo_merge_commits); + string_list_clear_func(&writer->pseudo_merge_groups, + pseudo_merge_group_release_cb); for (i = 0; i < writer->selected_nr; i++) { struct bitmapped_commit *bc = &writer->selected[i]; @@ -581,7 +590,8 @@ int bitmap_writer_build(struct bitmap_writer *writer) int closed = 1; /* until proven otherwise */ if (writer->show_progress) - writer->progress = start_progress("Building bitmaps", + writer->progress = start_progress(the_repository, + "Building bitmaps", writer->selected_nr); trace2_region_enter("pack-bitmap-write", "building_bitmaps_total", the_repository); @@ -701,7 +711,8 @@ void bitmap_writer_select_commits(struct bitmap_writer *writer, } if (writer->show_progress) - writer->progress = start_progress("Selecting bitmap commits", 0); + writer->progress = start_progress(the_repository, + "Selecting bitmap commits", 0); for (;;) { struct commit *chosen = NULL; @@ -905,6 +916,7 @@ static void write_pseudo_merges(struct bitmap_writer *writer, for (i = 0; i < writer->pseudo_merges_nr; i++) bitmap_free(commits_bitmap[i]); + oid_array_clear(&commits); free(pseudo_merge_ofs); free(commits_bitmap); } @@ -1060,7 +1072,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer, finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA, CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE); - if (adjust_shared_perm(tmp_file.buf)) + if (adjust_shared_perm(the_repository, tmp_file.buf)) die_errno("unable to make temporary bitmap file readable"); if (rename(tmp_file.buf, filename)) diff --git a/pack-bitmap.c b/pack-bitmap.c index 9d9b8c4bfbcc86..6406953d322371 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "commit.h" @@ -177,12 +177,21 @@ static uint32_t bitmap_num_objects(struct bitmap_index *index) return index->pack->num_objects; } +static struct repository *bitmap_repo(struct bitmap_index *bitmap_git) +{ + if (bitmap_is_midx(bitmap_git)) + return bitmap_git->midx->repo; + return bitmap_git->pack->repo; +} + static int load_bitmap_header(struct bitmap_index *index) { struct bitmap_disk_header *header = (void *)index->map; - size_t header_size = sizeof(*header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz; + const struct git_hash_algo *hash_algo = bitmap_repo(index)->hash_algo; + + size_t header_size = sizeof(*header) - GIT_MAX_RAWSZ + hash_algo->rawsz; - if (index->map_size < header_size + the_hash_algo->rawsz) + if (index->map_size < header_size + hash_algo->rawsz) return error(_("corrupted bitmap index (too small)")); if (memcmp(header->magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)) != 0) @@ -196,7 +205,7 @@ static int load_bitmap_header(struct bitmap_index *index) { uint32_t flags = ntohs(header->options); size_t cache_size = st_mult(bitmap_num_objects(index), sizeof(uint32_t)); - unsigned char *index_end = index->map + index->map_size - the_hash_algo->rawsz; + unsigned char *index_end = index->map + index->map_size - hash_algo->rawsz; if ((flags & BITMAP_OPT_FULL_DAG) == 0) BUG("unsupported options for bitmap index file " @@ -368,8 +377,8 @@ static int load_bitmap_entries_v1(struct bitmap_index *index) char *midx_bitmap_filename(struct multi_pack_index *midx) { struct strbuf buf = STRBUF_INIT; - get_midx_filename_ext(&buf, midx->object_dir, get_midx_checksum(midx), - MIDX_EXT_BITMAP); + get_midx_filename_ext(midx->repo->hash_algo, &buf, midx->object_dir, + get_midx_checksum(midx), MIDX_EXT_BITMAP); return strbuf_detach(&buf, NULL); } @@ -389,8 +398,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, preferred_pack; - struct packed_git *preferred; + uint32_t i; if (fd < 0) { if (errno != ENOENT) @@ -408,8 +416,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, if (bitmap_git->pack || bitmap_git->midx) { struct strbuf buf = STRBUF_INIT; - get_midx_filename(&buf, midx->object_dir); - trace2_data_string("bitmap", the_repository, + get_midx_filename(midx->repo->hash_algo, &buf, midx->object_dir); + trace2_data_string("bitmap", bitmap_repo(bitmap_git), "ignoring extra midx bitmap file", buf.buf); close(fd); strbuf_release(&buf); @@ -427,7 +435,7 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, goto cleanup; if (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum, - the_repository->hash_algo)) { + bitmap_repo(bitmap_git)->hash_algo)) { error(_("checksum doesn't match in MIDX and bitmap")); goto cleanup; } @@ -438,25 +446,15 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, } for (i = 0; i < bitmap_git->midx->num_packs; i++) { - if (prepare_midx_pack(the_repository, bitmap_git->midx, i)) { + if (prepare_midx_pack(bitmap_repo(bitmap_git), + bitmap_git->midx, + i)) { warning(_("could not open pack %s"), bitmap_git->midx->pack_names[i]); goto cleanup; } } - 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); - goto cleanup; - } - return 0; cleanup: @@ -492,8 +490,9 @@ static int open_pack_bitmap_1(struct bitmap_index *bitmap_git, struct packed_git } if (bitmap_git->pack || bitmap_git->midx) { - trace2_data_string("bitmap", the_repository, - "ignoring extra bitmap file", packfile->pack_name); + trace2_data_string("bitmap", bitmap_repo(bitmap_git), + "ignoring extra bitmap file", + packfile->pack_name); close(fd); return -1; } @@ -518,8 +517,8 @@ static int open_pack_bitmap_1(struct bitmap_index *bitmap_git, struct packed_git return -1; } - trace2_data_string("bitmap", the_repository, "opened bitmap file", - packfile->pack_name); + trace2_data_string("bitmap", bitmap_repo(bitmap_git), + "opened bitmap file", packfile->pack_name); return 0; } @@ -649,7 +648,7 @@ struct bitmap_index *prepare_bitmap_git(struct repository *r) struct bitmap_index *prepare_midx_bitmap_git(struct multi_pack_index *midx) { - struct repository *r = the_repository; + struct repository *r = midx->repo; struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git)); if (!open_midx_bitmap_1(bitmap_git, midx) && !load_bitmap(r, bitmap_git)) @@ -935,7 +934,7 @@ static inline int bitmap_position_packfile(struct bitmap_index *bitmap_git, const struct object_id *oid) { uint32_t pos; - off_t offset = find_pack_entry_one(oid->hash, bitmap_git->pack); + off_t offset = find_pack_entry_one(oid, bitmap_git->pack); if (!offset) return -1; @@ -1213,6 +1212,7 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git, { struct bitmap_boundary_cb cb; struct object_list *root; + struct repository *repo; unsigned int i; unsigned int tmp_blobs, tmp_trees, tmp_tags; int any_missing = 0; @@ -1222,6 +1222,8 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git, cb.base = bitmap_new(); object_array_init(&cb.boundary); + repo = bitmap_repo(bitmap_git); + revs->ignore_missing_links = 1; if (bitmap_git->pseudo_merges.nr) { @@ -1270,7 +1272,7 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git, tmp_blobs = revs->blob_objects; tmp_trees = revs->tree_objects; - tmp_tags = revs->blob_objects; + tmp_tags = revs->tag_objects; revs->blob_objects = 0; revs->tree_objects = 0; revs->tag_objects = 0; @@ -1280,19 +1282,19 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git, * revision walk to (a) OR in any bitmaps that are UNINTERESTING * between the tips and boundary, and (b) record the boundary. */ - trace2_region_enter("pack-bitmap", "boundary-prepare", the_repository); + trace2_region_enter("pack-bitmap", "boundary-prepare", repo); if (prepare_revision_walk(revs)) die("revision walk setup failed"); - trace2_region_leave("pack-bitmap", "boundary-prepare", the_repository); + trace2_region_leave("pack-bitmap", "boundary-prepare", repo); - trace2_region_enter("pack-bitmap", "boundary-traverse", the_repository); + trace2_region_enter("pack-bitmap", "boundary-traverse", repo); revs->boundary = 1; traverse_commit_list_filtered(revs, show_boundary_commit, show_boundary_object, &cb, NULL); revs->boundary = 0; - trace2_region_leave("pack-bitmap", "boundary-traverse", the_repository); + trace2_region_leave("pack-bitmap", "boundary-traverse", repo); revs->blob_objects = tmp_blobs; revs->tree_objects = tmp_trees; @@ -1304,7 +1306,7 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git, /* * Then add the boundary commit(s) as fill-in traversal tips. */ - trace2_region_enter("pack-bitmap", "boundary-fill-in", the_repository); + trace2_region_enter("pack-bitmap", "boundary-fill-in", repo); for (i = 0; i < cb.boundary.nr; i++) { struct object *obj = cb.boundary.objects[i].item; if (bitmap_walk_contains(bitmap_git, cb.base, &obj->oid)) @@ -1314,7 +1316,7 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git, } if (revs->pending.nr) cb.base = fill_in_bitmap(bitmap_git, revs, cb.base, NULL); - trace2_region_leave("pack-bitmap", "boundary-fill-in", the_repository); + trace2_region_leave("pack-bitmap", "boundary-fill-in", repo); cleanup: object_array_clear(&cb.boundary); @@ -1390,8 +1392,8 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git, } base = bitmap_new(); - if (!cascade_pseudo_merges_1(bitmap_git, base, roots_bitmap)) - bitmap_free(roots_bitmap); + cascade_pseudo_merges_1(bitmap_git, base, roots_bitmap); + bitmap_free(roots_bitmap); } /* @@ -1609,7 +1611,7 @@ static int in_bitmapped_pack(struct bitmap_index *bitmap_git, if (bsearch_midx(&object->oid, bitmap_git->midx, NULL)) return 1; } else { - if (find_pack_entry_one(object->oid.hash, bitmap_git->pack) > 0) + if (find_pack_entry_one(&object->oid, bitmap_git->pack) > 0) return 1; } } @@ -1718,7 +1720,8 @@ static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git, ofs = pack_pos_to_offset(pack, pos); } - if (packed_object_info(the_repository, pack, ofs, &oi) < 0) { + if (packed_object_info(bitmap_repo(bitmap_git), pack, ofs, + &oi) < 0) { struct object_id oid; nth_bitmap_object_oid(bitmap_git, &oid, pack_pos_to_index(pack, pos)); @@ -1727,7 +1730,8 @@ static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git, } else { struct eindex *eindex = &bitmap_git->ext_index; struct object *obj = eindex->objects[pos - bitmap_num_objects(bitmap_git)]; - if (oid_object_info_extended(the_repository, &obj->oid, &oi, 0) < 0) + if (oid_object_info_extended(bitmap_repo(bitmap_git), &obj->oid, + &oi, 0) < 0) die(_("unable to get size of %s"), oid_to_hex(&obj->oid)); } @@ -1889,7 +1893,8 @@ static void filter_packed_objects_from_bitmap(struct bitmap_index *bitmap_git, bitmap_unset(result, i); for (i = 0; i < eindex->count; ++i) { - if (has_object_pack(&eindex->objects[i]->oid)) + if (has_object_pack(bitmap_repo(bitmap_git), + &eindex->objects[i]->oid)) bitmap_unset(result, objects_nr + i); } } @@ -1907,6 +1912,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs, struct bitmap *haves_bitmap = NULL; struct bitmap_index *bitmap_git; + struct repository *repo; /* * We can't do pathspec limiting with bitmaps, because we don't know @@ -1980,18 +1986,20 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs, if (!use_boundary_traversal) object_array_clear(&revs->pending); + repo = bitmap_repo(bitmap_git); + if (haves) { if (use_boundary_traversal) { - trace2_region_enter("pack-bitmap", "haves/boundary", the_repository); + trace2_region_enter("pack-bitmap", "haves/boundary", repo); haves_bitmap = find_boundary_objects(bitmap_git, revs, haves); - trace2_region_leave("pack-bitmap", "haves/boundary", the_repository); + trace2_region_leave("pack-bitmap", "haves/boundary", repo); } else { - trace2_region_enter("pack-bitmap", "haves/classic", the_repository); + trace2_region_enter("pack-bitmap", "haves/classic", repo); revs->ignore_missing_links = 1; haves_bitmap = find_objects(bitmap_git, revs, haves, NULL); reset_revision_walk(); revs->ignore_missing_links = 0; - trace2_region_leave("pack-bitmap", "haves/classic", the_repository); + trace2_region_leave("pack-bitmap", "haves/classic", repo); } if (!haves_bitmap) @@ -2025,17 +2033,17 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs, object_list_free(&wants); object_list_free(&haves); - trace2_data_intmax("bitmap", the_repository, "pseudo_merges_satisfied", + trace2_data_intmax("bitmap", repo, "pseudo_merges_satisfied", pseudo_merges_satisfied_nr); - trace2_data_intmax("bitmap", the_repository, "pseudo_merges_cascades", + trace2_data_intmax("bitmap", repo, "pseudo_merges_cascades", pseudo_merges_cascades_nr); - trace2_data_intmax("bitmap", the_repository, "bitmap/hits", + trace2_data_intmax("bitmap", repo, "bitmap/hits", existing_bitmaps_hits_nr); - trace2_data_intmax("bitmap", the_repository, "bitmap/misses", + trace2_data_intmax("bitmap", repo, "bitmap/misses", existing_bitmaps_misses_nr); - trace2_data_intmax("bitmap", the_repository, "bitmap/roots_with_bitmap", + trace2_data_intmax("bitmap", repo, "bitmap/roots_with_bitmap", roots_with_bitmaps_nr); - trace2_data_intmax("bitmap", the_repository, "bitmap/roots_without_bitmap", + trace2_data_intmax("bitmap", repo, "bitmap/roots_without_bitmap", roots_without_bitmaps_nr); return bitmap_git; @@ -2256,7 +2264,7 @@ void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, struct bitmap **reuse_out, int multi_pack_reuse) { - struct repository *r = the_repository; + struct repository *r = bitmap_repo(bitmap_git); struct bitmapped_pack *packs = NULL; struct bitmap *result = bitmap_git->result; struct bitmap *reuse; @@ -2285,8 +2293,10 @@ void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, if (!pack.bitmap_nr) continue; - ALLOC_GROW(packs, packs_nr + 1, packs_alloc); - memcpy(&packs[packs_nr++], &pack, sizeof(pack)); + if (is_pack_valid(pack.p)) { + ALLOC_GROW(packs, packs_nr + 1, packs_alloc); + memcpy(&packs[packs_nr++], &pack, sizeof(pack)); + } objects_nr += pack.p->num_objects; } @@ -2320,16 +2330,22 @@ void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git, pack_int_id = -1; } - ALLOC_GROW(packs, packs_nr + 1, packs_alloc); - packs[packs_nr].p = pack; - packs[packs_nr].pack_int_id = pack_int_id; - packs[packs_nr].bitmap_nr = pack->num_objects; - packs[packs_nr].bitmap_pos = 0; - packs[packs_nr].from_midx = bitmap_git->midx; + if (is_pack_valid(pack)) { + ALLOC_GROW(packs, packs_nr + 1, packs_alloc); + packs[packs_nr].p = pack; + packs[packs_nr].pack_int_id = pack_int_id; + packs[packs_nr].bitmap_nr = pack->num_objects; + packs[packs_nr].bitmap_pos = 0; + packs[packs_nr].from_midx = bitmap_git->midx; + packs_nr++; + } - objects_nr = packs[packs_nr++].bitmap_nr; + objects_nr = pack->num_objects; } + if (!packs_nr) + return; + word_alloc = objects_nr / BITS_IN_EWORD; if (objects_nr % BITS_IN_EWORD) word_alloc++; @@ -2557,7 +2573,9 @@ void test_bitmap_walk(struct rev_info *revs) tdata.trees = ewah_to_bitmap(bitmap_git->trees); tdata.blobs = ewah_to_bitmap(bitmap_git->blobs); tdata.tags = ewah_to_bitmap(bitmap_git->tags); - tdata.prg = start_progress("Verifying bitmap entries", result_popcnt); + tdata.prg = start_progress(revs->repo, + "Verifying bitmap entries", + result_popcnt); tdata.seen = 0; traverse_commit_list(revs, &test_show_commit, &test_show_object, &tdata); @@ -2792,7 +2810,7 @@ int rebuild_bitmap(const uint32_t *reposition, uint32_t *create_bitmap_mapping(struct bitmap_index *bitmap_git, struct packing_data *mapping) { - struct repository *r = the_repository; + struct repository *r = bitmap_repo(bitmap_git); uint32_t i, num_objects; uint32_t *reposition; @@ -2948,7 +2966,8 @@ static off_t get_disk_usage_for_extended(struct bitmap_index *bitmap_git) st_add(bitmap_num_objects(bitmap_git), i))) continue; - if (oid_object_info_extended(the_repository, &obj->oid, &oi, 0) < 0) + if (oid_object_info_extended(bitmap_repo(bitmap_git), &obj->oid, + &oi, 0) < 0) die(_("unable to get disk usage of '%s'"), oid_to_hex(&obj->oid)); diff --git a/pack-check.c b/pack-check.c index e883dae3f24bb4..d0aeb5ec41259b 100644 --- a/pack-check.c +++ b/pack-check.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" @@ -57,7 +58,7 @@ static int verify_packfile(struct repository *r, { off_t index_size = p->index_size; const unsigned char *index_base = p->index_data; - git_hash_ctx ctx; + struct git_hash_ctx ctx; unsigned char hash[GIT_MAX_RAWSZ], *pack_sig; off_t offset = 0, pack_sig_ofs = 0; uint32_t nr_objects, i; @@ -76,9 +77,9 @@ static int verify_packfile(struct repository *r, pack_sig_ofs = p->pack_size - r->hash_algo->rawsz; if (offset > pack_sig_ofs) remaining -= (unsigned int)(offset - pack_sig_ofs); - r->hash_algo->update_fn(&ctx, in, remaining); + git_hash_update(&ctx, in, remaining); } while (offset < pack_sig_ofs); - r->hash_algo->final_fn(hash, &ctx); + git_hash_final(hash, &ctx); pack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL); if (!hasheq(hash, pack_sig, the_repository->hash_algo)) err = error("%s pack checksum mismatch", diff --git a/pack-objects.h b/pack-objects.h index b9898a4e64b8b4..d73e3843c92e9c 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -7,7 +7,8 @@ struct repository; -#define DEFAULT_DELTA_CACHE_SIZE (256 * 1024 * 1024) +#define DEFAULT_DELTA_CACHE_SIZE (256 * 1024 * 1024) +#define DEFAULT_DELTA_BASE_CACHE_LIMIT (96 * 1024 * 1024) #define OE_DFS_STATE_BITS 2 #define OE_DEPTH_BITS 12 @@ -207,6 +208,34 @@ static inline uint32_t pack_name_hash(const char *name) return hash; } +static inline uint32_t pack_name_hash_v2(const unsigned char *name) +{ + uint32_t hash = 0, base = 0, c; + + if (!name) + return 0; + + while ((c = *name++)) { + if (isspace(c)) + continue; + if (c == '/') { + base = (base >> 6) ^ hash; + hash = 0; + } else { + /* + * 'c' is only a single byte. Reverse it and move + * it to the top of the hash, moving the rest to + * less-significant bits. + */ + c = (c & 0xF0) >> 4 | (c & 0x0F) << 4; + c = (c & 0xCC) >> 2 | (c & 0x33) << 2; + c = (c & 0xAA) >> 1 | (c & 0x55) << 1; + hash = (hash >> 2) + (c << 24); + } + } + return (base >> 6) ^ hash; +} + static inline enum object_type oe_type(const struct object_entry *e) { return e->type_valid ? e->type_ : OBJ_BAD; diff --git a/pack-revindex.c b/pack-revindex.c index 22d3c2346488de..d3832478d99edf 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -383,7 +383,7 @@ int load_midx_revindex(struct multi_pack_index *m) trace2_data_string("load_midx_revindex", the_repository, "source", "rev"); - get_midx_filename_ext(&revindex_name, m->object_dir, + get_midx_filename_ext(m->repo->hash_algo, &revindex_name, m->object_dir, get_midx_checksum(m), MIDX_EXT_REV); ret = load_revindex_from_disk(revindex_name.buf, diff --git a/pack-write.c b/pack-write.c index 27965672f17822..823e40b42f2097 100644 --- a/pack-write.c +++ b/pack-write.c @@ -8,6 +8,7 @@ #include "csum-file.h" #include "remote.h" #include "chunk-format.h" +#include "object-file.h" #include "pack-mtimes.h" #include "pack-objects.h" #include "pack-revindex.h" @@ -20,6 +21,7 @@ void reset_pack_idx_option(struct pack_idx_option *opts) memset(opts, 0, sizeof(*opts)); opts->version = 2; opts->off32_limit = 0x7fffffff; + opts->delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT; } static int sha1_compare(const void *_a, const void *_b) @@ -54,7 +56,8 @@ static int need_large_offset(off_t offset, const struct pack_idx_option *opts) * The *sha1 contains the pack content SHA1 hash. * The objects array passed in will be sorted by SHA1 on exit. */ -const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, +const char *write_idx_file(const struct git_hash_algo *hash_algo, + const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *opts, const unsigned char *sha1) { @@ -128,7 +131,7 @@ const char *write_idx_file(const char *index_name, struct pack_idx_entry **objec struct pack_idx_entry *obj = *list++; if (index_version < 2) hashwrite_be32(f, obj->offset); - hashwrite(f, obj->oid.hash, the_hash_algo->rawsz); + hashwrite(f, obj->oid.hash, hash_algo->rawsz); if ((opts->flags & WRITE_IDX_STRICT) && (i && oideq(&list[-2]->oid, &obj->oid))) die("The same object %s appears twice in the pack", @@ -170,7 +173,7 @@ const char *write_idx_file(const char *index_name, struct pack_idx_entry **objec } } - hashwrite(f, sha1, the_hash_algo->rawsz); + hashwrite(f, sha1, hash_algo->rawsz); finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA, CSUM_HASH_IN_STREAM | CSUM_CLOSE | ((opts->flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC)); @@ -191,11 +194,12 @@ static int pack_order_cmp(const void *va, const void *vb, void *ctx) return 0; } -static void write_rev_header(struct hashfile *f) +static void write_rev_header(const struct git_hash_algo *hash_algo, + struct hashfile *f) { hashwrite_be32(f, RIDX_SIGNATURE); hashwrite_be32(f, RIDX_VERSION); - hashwrite_be32(f, oid_version(the_hash_algo)); + hashwrite_be32(f, oid_version(hash_algo)); } static void write_rev_index_positions(struct hashfile *f, @@ -207,20 +211,22 @@ static void write_rev_index_positions(struct hashfile *f, hashwrite_be32(f, pack_order[i]); } -static void write_rev_trailer(struct hashfile *f, const unsigned char *hash) +static void write_rev_trailer(const struct git_hash_algo *hash_algo, + struct hashfile *f, const unsigned char *hash) { - hashwrite(f, hash, the_hash_algo->rawsz); + hashwrite(f, hash, hash_algo->rawsz); } -const char *write_rev_file(const char *rev_name, - struct pack_idx_entry **objects, - uint32_t nr_objects, - const unsigned char *hash, - unsigned flags) +char *write_rev_file(const struct git_hash_algo *hash_algo, + const char *rev_name, + struct pack_idx_entry **objects, + uint32_t nr_objects, + const unsigned char *hash, + unsigned flags) { uint32_t *pack_order; uint32_t i; - const char *ret; + char *ret; if (!(flags & WRITE_REV) && !(flags & WRITE_REV_VERIFY)) return NULL; @@ -230,21 +236,23 @@ const char *write_rev_file(const char *rev_name, pack_order[i] = i; QSORT_S(pack_order, nr_objects, pack_order_cmp, objects); - ret = write_rev_file_order(rev_name, pack_order, nr_objects, hash, - flags); + ret = write_rev_file_order(hash_algo, rev_name, pack_order, nr_objects, + hash, flags); free(pack_order); return ret; } -const char *write_rev_file_order(const char *rev_name, - uint32_t *pack_order, - uint32_t nr_objects, - const unsigned char *hash, - unsigned flags) +char *write_rev_file_order(const struct git_hash_algo *hash_algo, + const char *rev_name, + uint32_t *pack_order, + uint32_t nr_objects, + const unsigned char *hash, + unsigned flags) { struct hashfile *f; + char *path; int fd; if ((flags & WRITE_REV) && (flags & WRITE_REV_VERIFY)) @@ -254,12 +262,13 @@ const char *write_rev_file_order(const char *rev_name, if (!rev_name) { struct strbuf tmp_file = STRBUF_INIT; fd = odb_mkstemp(&tmp_file, "pack/tmp_rev_XXXXXX"); - rev_name = strbuf_detach(&tmp_file, NULL); + path = strbuf_detach(&tmp_file, NULL); } else { unlink(rev_name); fd = xopen(rev_name, O_CREAT|O_EXCL|O_WRONLY, 0600); + path = xstrdup(rev_name); } - f = hashfd(fd, rev_name); + f = hashfd(fd, path); } else if (flags & WRITE_REV_VERIFY) { struct stat statbuf; if (stat(rev_name, &statbuf)) { @@ -270,29 +279,32 @@ const char *write_rev_file_order(const char *rev_name, die_errno(_("could not stat: %s"), rev_name); } f = hashfd_check(rev_name); - } else + path = xstrdup(rev_name); + } else { return NULL; + } - write_rev_header(f); + write_rev_header(hash_algo, f); write_rev_index_positions(f, pack_order, nr_objects); - write_rev_trailer(f, hash); + write_rev_trailer(hash_algo, f, hash); - if (rev_name && adjust_shared_perm(rev_name) < 0) - die(_("failed to make %s readable"), rev_name); + if (adjust_shared_perm(the_repository, path) < 0) + die(_("failed to make %s readable"), path); finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA, CSUM_HASH_IN_STREAM | CSUM_CLOSE | ((flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC)); - return rev_name; + return path; } -static void write_mtimes_header(struct hashfile *f) +static void write_mtimes_header(const struct git_hash_algo *hash_algo, + struct hashfile *f) { hashwrite_be32(f, MTIMES_SIGNATURE); hashwrite_be32(f, MTIMES_VERSION); - hashwrite_be32(f, oid_version(the_hash_algo)); + hashwrite_be32(f, oid_version(hash_algo)); } /* @@ -312,12 +324,14 @@ static void write_mtimes_objects(struct hashfile *f, } } -static void write_mtimes_trailer(struct hashfile *f, const unsigned char *hash) +static void write_mtimes_trailer(const struct git_hash_algo *hash_algo, + struct hashfile *f, const unsigned char *hash) { - hashwrite(f, hash, the_hash_algo->rawsz); + hashwrite(f, hash, hash_algo->rawsz); } -static char *write_mtimes_file(struct packing_data *to_pack, +static char *write_mtimes_file(const struct git_hash_algo *hash_algo, + struct packing_data *to_pack, struct pack_idx_entry **objects, uint32_t nr_objects, const unsigned char *hash) @@ -334,11 +348,11 @@ static char *write_mtimes_file(struct packing_data *to_pack, mtimes_name = strbuf_detach(&tmp_file, NULL); f = hashfd(fd, mtimes_name); - write_mtimes_header(f); + write_mtimes_header(hash_algo, f); write_mtimes_objects(f, to_pack, objects, nr_objects); - write_mtimes_trailer(f, hash); + write_mtimes_trailer(hash_algo, f, hash); - if (adjust_shared_perm(mtimes_name) < 0) + if (adjust_shared_perm(the_repository, mtimes_name) < 0) die(_("failed to make %s readable"), mtimes_name); finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA, @@ -374,7 +388,8 @@ off_t write_pack_header(struct hashfile *f, uint32_t nr_entries) * partial_pack_sha1 can refer to the same buffer if the caller is not * interested in the resulting SHA1 of pack data above partial_pack_offset. */ -void fixup_pack_header_footer(int pack_fd, +void fixup_pack_header_footer(const struct git_hash_algo *hash_algo, + int pack_fd, unsigned char *new_pack_hash, const char *pack_name, uint32_t object_count, @@ -382,13 +397,13 @@ void fixup_pack_header_footer(int pack_fd, off_t partial_pack_offset) { int aligned_sz, buf_sz = 8 * 1024; - git_hash_ctx old_hash_ctx, new_hash_ctx; + struct git_hash_ctx old_hash_ctx, new_hash_ctx; struct pack_header hdr; char *buf; ssize_t read_result; - the_hash_algo->init_fn(&old_hash_ctx); - the_hash_algo->init_fn(&new_hash_ctx); + hash_algo->init_fn(&old_hash_ctx); + hash_algo->init_fn(&new_hash_ctx); if (lseek(pack_fd, 0, SEEK_SET) != 0) die_errno("Failed seeking to start of '%s'", pack_name); @@ -400,9 +415,9 @@ void fixup_pack_header_footer(int pack_fd, pack_name); if (lseek(pack_fd, 0, SEEK_SET) != 0) die_errno("Failed seeking to start of '%s'", pack_name); - the_hash_algo->update_fn(&old_hash_ctx, &hdr, sizeof(hdr)); + git_hash_update(&old_hash_ctx, &hdr, sizeof(hdr)); hdr.hdr_entries = htonl(object_count); - the_hash_algo->update_fn(&new_hash_ctx, &hdr, sizeof(hdr)); + git_hash_update(&new_hash_ctx, &hdr, sizeof(hdr)); write_or_die(pack_fd, &hdr, sizeof(hdr)); partial_pack_offset -= sizeof(hdr); @@ -417,7 +432,7 @@ void fixup_pack_header_footer(int pack_fd, break; if (n < 0) die_errno("Failed to checksum '%s'", pack_name); - the_hash_algo->update_fn(&new_hash_ctx, buf, n); + git_hash_update(&new_hash_ctx, buf, n); aligned_sz -= n; if (!aligned_sz) @@ -426,13 +441,13 @@ void fixup_pack_header_footer(int pack_fd, if (!partial_pack_hash) continue; - the_hash_algo->update_fn(&old_hash_ctx, buf, n); + git_hash_update(&old_hash_ctx, buf, n); partial_pack_offset -= n; if (partial_pack_offset == 0) { unsigned char hash[GIT_MAX_RAWSZ]; - the_hash_algo->final_fn(hash, &old_hash_ctx); + git_hash_final(hash, &old_hash_ctx); if (!hasheq(hash, partial_pack_hash, - the_repository->hash_algo)) + hash_algo)) die("Unexpected checksum for %s " "(disk corruption?)", pack_name); /* @@ -440,7 +455,7 @@ void fixup_pack_header_footer(int pack_fd, * pack, which also means making partial_pack_offset * big enough not to matter anymore. */ - the_hash_algo->init_fn(&old_hash_ctx); + hash_algo->init_fn(&old_hash_ctx); partial_pack_offset = ~partial_pack_offset; partial_pack_offset -= MSB(partial_pack_offset, 1); } @@ -448,16 +463,16 @@ void fixup_pack_header_footer(int pack_fd, free(buf); if (partial_pack_hash) - the_hash_algo->final_fn(partial_pack_hash, &old_hash_ctx); - the_hash_algo->final_fn(new_pack_hash, &new_hash_ctx); - write_or_die(pack_fd, new_pack_hash, the_hash_algo->rawsz); + git_hash_final(partial_pack_hash, &old_hash_ctx); + git_hash_final(new_pack_hash, &new_hash_ctx); + write_or_die(pack_fd, new_pack_hash, hash_algo->rawsz); fsync_component_or_die(FSYNC_COMPONENT_PACK, pack_fd, pack_name); } -char *index_pack_lockfile(int ip_out, int *is_well_formed) +char *index_pack_lockfile(struct repository *r, int ip_out, int *is_well_formed) { char packname[GIT_MAX_HEXSZ + 6]; - const int len = the_hash_algo->hexsz + 6; + const int len = r->hash_algo->hexsz + 6; /* * The first thing we expect from index-pack's output @@ -474,7 +489,7 @@ char *index_pack_lockfile(int ip_out, int *is_well_formed) packname[len-1] = 0; if (skip_prefix(packname, "keep\t", &name)) return xstrfmt("%s/pack/pack-%s.keep", - repo_get_object_directory(the_repository), name); + repo_get_object_directory(r), name); return NULL; } if (is_well_formed) @@ -528,9 +543,9 @@ static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source, size_t name_prefix_len = name_prefix->len; strbuf_addstr(name_prefix, ext); - if (rename(source, name_prefix->buf)) - die_errno("unable to rename temporary file to '%s'", - name_prefix->buf); + if (finalize_object_file(source, name_prefix->buf)) + die("unable to rename temporary file to '%s'", + name_prefix->buf); strbuf_setlen(name_prefix, name_prefix_len); } @@ -540,7 +555,8 @@ void rename_tmp_packfile_idx(struct strbuf *name_buffer, rename_tmp_packfile(name_buffer, *idx_tmp_name, "idx"); } -void stage_tmp_packfiles(struct strbuf *name_buffer, +void stage_tmp_packfiles(const struct git_hash_algo *hash_algo, + struct strbuf *name_buffer, const char *pack_tmp_name, struct pack_idx_entry **written_list, uint32_t nr_written, @@ -549,23 +565,23 @@ void stage_tmp_packfiles(struct strbuf *name_buffer, unsigned char hash[], char **idx_tmp_name) { - const char *rev_tmp_name = NULL; + char *rev_tmp_name = NULL; char *mtimes_tmp_name = NULL; - if (adjust_shared_perm(pack_tmp_name)) + if (adjust_shared_perm(the_repository, pack_tmp_name)) die_errno("unable to make temporary pack file readable"); - *idx_tmp_name = (char *)write_idx_file(NULL, written_list, nr_written, - pack_idx_opts, hash); - if (adjust_shared_perm(*idx_tmp_name)) + *idx_tmp_name = (char *)write_idx_file(hash_algo, NULL, written_list, + nr_written, pack_idx_opts, hash); + if (adjust_shared_perm(the_repository, *idx_tmp_name)) die_errno("unable to make temporary index file readable"); - rev_tmp_name = write_rev_file(NULL, written_list, nr_written, hash, - pack_idx_opts->flags); + rev_tmp_name = write_rev_file(hash_algo, NULL, written_list, nr_written, + hash, pack_idx_opts->flags); if (pack_idx_opts->flags & WRITE_MTIMES) { - mtimes_tmp_name = write_mtimes_file(to_pack, written_list, - nr_written, + mtimes_tmp_name = write_mtimes_file(hash_algo, to_pack, + written_list, nr_written, hash); } @@ -575,7 +591,7 @@ void stage_tmp_packfiles(struct strbuf *name_buffer, if (mtimes_tmp_name) rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes"); - free((char *)rev_tmp_name); + free(rev_tmp_name); free(mtimes_tmp_name); } diff --git a/pack.h b/pack.h index 3ab9e3f60c0b03..9f1194ac13de17 100644 --- a/pack.h +++ b/pack.h @@ -13,7 +13,8 @@ struct repository; */ #define PACK_SIGNATURE 0x5041434b /* "PACK" */ #define PACK_VERSION 2 -#define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3)) +#define pack_version_ok(v) pack_version_ok_native(ntohl(v)) +#define pack_version_ok_native(v) ((v) == 2 || (v) == 3) struct pack_header { uint32_t hdr_signature; uint32_t hdr_version; @@ -58,6 +59,8 @@ struct pack_idx_option { */ int anomaly_alloc, anomaly_nr; uint32_t *anomaly; + + size_t delta_base_cache_limit; }; void reset_pack_idx_option(struct pack_idx_option *); @@ -84,20 +87,37 @@ struct progress; /* Note, the data argument could be NULL if object type is blob */ typedef int (*verify_fn)(const struct object_id *, enum object_type, unsigned long, void*, int*); -const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, const struct pack_idx_option *, const unsigned char *sha1); +const char *write_idx_file(const struct git_hash_algo *hash_algo, + const char *index_name, + struct pack_idx_entry **objects, + int nr_objects, + const struct pack_idx_option *, + const unsigned char *sha1); int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr); int verify_pack_index(struct packed_git *); int verify_pack(struct repository *, struct packed_git *, verify_fn fn, struct progress *, uint32_t); off_t write_pack_header(struct hashfile *f, uint32_t); -void fixup_pack_header_footer(int, unsigned char *, const char *, uint32_t, unsigned char *, off_t); -char *index_pack_lockfile(int fd, int *is_well_formed); +void fixup_pack_header_footer(const struct git_hash_algo *, int, + unsigned char *, const char *, uint32_t, + unsigned char *, off_t); +char *index_pack_lockfile(struct repository *r, int fd, int *is_well_formed); struct ref; void write_promisor_file(const char *promisor_name, struct ref **sought, int nr_sought); -const char *write_rev_file(const char *rev_name, struct pack_idx_entry **objects, uint32_t nr_objects, const unsigned char *hash, unsigned flags); -const char *write_rev_file_order(const char *rev_name, uint32_t *pack_order, uint32_t nr_objects, const unsigned char *hash, unsigned flags); +char *write_rev_file(const struct git_hash_algo *hash_algo, + const char *rev_name, + struct pack_idx_entry **objects, + uint32_t nr_objects, + const unsigned char *hash, + unsigned flags); +char *write_rev_file_order(const struct git_hash_algo *hash_algo, + const char *rev_name, + uint32_t *pack_order, + uint32_t nr_objects, + const unsigned char *hash, + unsigned flags); /* * The "hdr" output buffer should be at least this big, which will handle sizes @@ -115,7 +135,8 @@ int read_pack_header(int fd, struct pack_header *); struct packing_data; struct hashfile *create_tmp_packfile(char **pack_tmp_name); -void stage_tmp_packfiles(struct strbuf *name_buffer, +void stage_tmp_packfiles(const struct git_hash_algo *hash_algo, + struct strbuf *name_buffer, const char *pack_tmp_name, struct pack_idx_entry **written_list, uint32_t nr_written, diff --git a/packfile.c b/packfile.c index df4ba677197193..2d80d80cb3838d 100644 --- a/packfile.c +++ b/packfile.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" @@ -25,28 +25,15 @@ #include "pack-revindex.h" #include "promisor-remote.h" -char *odb_pack_name(struct strbuf *buf, - const unsigned char *hash, - const char *ext) +char *odb_pack_name(struct repository *r, struct strbuf *buf, + const unsigned char *hash, const char *ext) { strbuf_reset(buf); - strbuf_addf(buf, "%s/pack/pack-%s.%s", repo_get_object_directory(the_repository), - hash_to_hex(hash), ext); + strbuf_addf(buf, "%s/pack/pack-%s.%s", repo_get_object_directory(r), + hash_to_hex_algop(hash, r->hash_algo), ext); return buf->buf; } -char *sha1_pack_name(const unsigned char *sha1) -{ - static struct strbuf buf = STRBUF_INIT; - return odb_pack_name(&buf, sha1, "pack"); -} - -char *sha1_pack_index_name(const unsigned char *sha1) -{ - static struct strbuf buf = STRBUF_INIT; - return odb_pack_name(&buf, sha1, "idx"); -} - static unsigned int pack_used_ctr; static unsigned int pack_mmap_calls; static unsigned int peak_pack_open_windows; @@ -59,15 +46,15 @@ static size_t pack_mapped; #define SZ_FMT PRIuMAX static inline uintmax_t sz_fmt(size_t s) { return s; } -void pack_report(void) +void pack_report(struct repository *repo) { fprintf(stderr, "pack_report: getpagesize() = %10" SZ_FMT "\n" "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n" "pack_report: core.packedGitLimit = %10" SZ_FMT "\n", sz_fmt(getpagesize()), - sz_fmt(packed_git_window_size), - sz_fmt(packed_git_limit)); + sz_fmt(repo->settings.packed_git_window_size), + sz_fmt(repo->settings.packed_git_limit)); fprintf(stderr, "pack_report: pack_used_ctr = %10u\n" "pack_report: pack_mmap_calls = %10u\n" @@ -91,7 +78,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p) size_t idx_size; int fd = git_open(path), ret; struct stat st; - const unsigned int hashsz = the_hash_algo->rawsz; + const unsigned int hashsz = p->repo->hash_algo->rawsz; if (fd < 0) return -1; @@ -229,22 +216,33 @@ uint32_t get_pack_fanout(struct packed_git *p, uint32_t value) return ntohl(level1_ofs[value]); } -static struct packed_git *alloc_packed_git(int extra) +static struct packed_git *alloc_packed_git(struct repository *r, int extra) { struct packed_git *p = xmalloc(st_add(sizeof(*p), extra)); memset(p, 0, sizeof(*p)); p->pack_fd = -1; + p->repo = r; return p; } -struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path) +static char *pack_path_from_idx(const char *idx_path) +{ + size_t len; + if (!strip_suffix(idx_path, ".idx", &len)) + BUG("idx path does not end in .idx: %s", idx_path); + return xstrfmt("%.*s.pack", (int)len, idx_path); +} + +struct packed_git *parse_pack_index(struct repository *r, unsigned char *sha1, + const char *idx_path) { - const char *path = sha1_pack_name(sha1); + char *path = pack_path_from_idx(idx_path); size_t alloc = st_add(strlen(path), 1); - struct packed_git *p = alloc_packed_git(alloc); + struct packed_git *p = alloc_packed_git(r, alloc); memcpy(p->pack_name, path, alloc); /* includes NUL */ - hashcpy(p->hash, sha1, the_repository->hash_algo); + free(path); + hashcpy(p->hash, sha1, p->repo->hash_algo); if (check_packed_git_idx(idx_path, p)) { free(p); return NULL; @@ -279,7 +277,7 @@ static int unuse_one_window(struct packed_git *current) if (current) scan_windows(current, &lru_p, &lru_w, &lru_l); - for (p = the_repository->objects->packed_git; p; p = p->next) + for (p = current->repo->objects->packed_git; p; p = p->next) scan_windows(p, &lru_p, &lru_w, &lru_l); if (lru_p) { munmap(lru_w->base, lru_w->len); @@ -461,13 +459,13 @@ static void find_lru_pack(struct packed_git *p, struct packed_git **lru_p, struc *accept_windows_inuse = has_windows_inuse; } -static int close_one_pack(void) +static int close_one_pack(struct repository *r) { struct packed_git *p, *lru_p = NULL; struct pack_window *mru_w = NULL; int accept_windows_inuse = 1; - for (p = the_repository->objects->packed_git; p; p = p->next) { + for (p = r->objects->packed_git; p; p = p->next) { if (p->pack_fd == -1) continue; find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse); @@ -541,7 +539,7 @@ static int open_packed_git_1(struct packed_git *p) unsigned char hash[GIT_MAX_RAWSZ]; unsigned char *idx_hash; ssize_t read_result; - const unsigned hashsz = the_hash_algo->rawsz; + const unsigned hashsz = p->repo->hash_algo->rawsz; if (open_pack_index(p)) return error("packfile %s index unavailable", p->pack_name); @@ -556,7 +554,7 @@ static int open_packed_git_1(struct packed_git *p) pack_max_fds = 1; } - while (pack_max_fds <= pack_open_fds && close_one_pack()) + while (pack_max_fds <= pack_open_fds && close_one_pack(p->repo)) ; /* nothing */ p->pack_fd = git_open(p->pack_name); @@ -598,7 +596,7 @@ static int open_packed_git_1(struct packed_git *p) if (read_result != hashsz) return error("packfile %s signature is unavailable", p->pack_name); idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2; - if (!hasheq(hash, idx_hash, the_repository->hash_algo)) + if (!hasheq(hash, idx_hash, p->repo->hash_algo)) return error("packfile %s does not match index", p->pack_name); return 0; } @@ -611,7 +609,8 @@ static int open_packed_git(struct packed_git *p) return -1; } -static int in_window(struct pack_window *win, off_t offset) +static int in_window(struct repository *r, struct pack_window *win, + off_t offset) { /* We must promise at least one full hash after the * offset is available from this window, otherwise the offset @@ -621,7 +620,7 @@ static int in_window(struct pack_window *win, off_t offset) */ off_t win_off = win->offset; return win_off <= offset - && (offset + the_hash_algo->rawsz) <= (win_off + win->len); + && (offset + r->hash_algo->rawsz) <= (win_off + win->len); } unsigned char *use_pack(struct packed_git *p, @@ -638,21 +637,28 @@ unsigned char *use_pack(struct packed_git *p, */ if (!p->pack_size && p->pack_fd == -1 && open_packed_git(p)) die("packfile %s cannot be accessed", p->pack_name); - if (offset > (p->pack_size - the_hash_algo->rawsz)) + if (offset > (p->pack_size - p->repo->hash_algo->rawsz)) die("offset beyond end of packfile (truncated pack?)"); if (offset < 0) die(_("offset before end of packfile (broken .idx?)")); - if (!win || !in_window(win, offset)) { + if (!win || !in_window(p->repo, win, offset)) { if (win) win->inuse_cnt--; for (win = p->windows; win; win = win->next) { - if (in_window(win, offset)) + if (in_window(p->repo, win, offset)) break; } if (!win) { - size_t window_align = packed_git_window_size / 2; + size_t window_align; off_t len; + struct repo_settings *settings; + + /* lazy load the settings in case it hasn't been setup */ + prepare_repo_settings(p->repo); + settings = &p->repo->settings; + + window_align = settings->packed_git_window_size / 2; if (p->pack_fd == -1 && open_packed_git(p)) die("packfile %s cannot be accessed", p->pack_name); @@ -660,11 +666,12 @@ unsigned char *use_pack(struct packed_git *p, CALLOC_ARRAY(win, 1); win->offset = (offset / window_align) * window_align; len = p->pack_size - win->offset; - if (len > packed_git_window_size) - len = packed_git_window_size; + if (len > settings->packed_git_window_size) + len = settings->packed_git_window_size; win->len = (size_t)len; pack_mapped += win->len; - while (packed_git_limit < pack_mapped + + while (settings->packed_git_limit < pack_mapped && unuse_one_window(p)) ; /* nothing */ win->base = xmmap_gently(NULL, win->len, @@ -706,11 +713,13 @@ void unuse_pack(struct pack_window **w_cursor) } } -struct packed_git *add_packed_git(const char *path, size_t path_len, int local) +struct packed_git *add_packed_git(struct repository *r, const char *path, + size_t path_len, int local) { struct stat st; size_t alloc; struct packed_git *p; + struct object_id oid; /* * Make sure a corresponding .pack file exists and that @@ -724,7 +733,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local) * the use xsnprintf double-checks that) */ alloc = st_add3(path_len, strlen(".promisor"), 1); - p = alloc_packed_git(alloc); + p = alloc_packed_git(r, alloc); memcpy(p->pack_name, path, path_len); xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep"); @@ -751,9 +760,13 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local) p->pack_size = st.st_size; p->pack_local = local; p->mtime = st.st_mtime; - if (path_len < the_hash_algo->hexsz || - get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash)) - hashclr(p->hash, the_repository->hash_algo); + if (path_len < r->hash_algo->hexsz || + get_oid_hex_algop(path + path_len - r->hash_algo->hexsz, &oid, + r->hash_algo)) + hashclr(p->hash, r->hash_algo); + else + hashcpy(p->hash, oid.hash, r->hash_algo); + return p; } @@ -880,7 +893,7 @@ static void prepare_pack(const char *full_name, size_t full_name_len, /* Don't reopen a pack we already have. */ if (!hashmap_get(&data->r->objects->pack_map, &hent, pack_name)) { - p = add_packed_git(full_name, full_name_len, data->local); + p = add_packed_git(data->r, full_name, full_name_len, data->local); if (p) install_packed_git(data->r, p); } @@ -1242,8 +1255,10 @@ off_t get_delta_base(struct packed_git *p, *curpos += used; } else if (type == OBJ_REF_DELTA) { /* The base entry _must_ be in the same pack */ - base_offset = find_pack_entry_one(base_info, p); - *curpos += the_hash_algo->rawsz; + struct object_id oid; + oidread(&oid, base_info, p->repo->hash_algo); + base_offset = find_pack_entry_one(&oid, p); + *curpos += p->repo->hash_algo->rawsz; } else die("I am totally screwed"); return base_offset; @@ -1264,7 +1279,7 @@ static int get_delta_base_oid(struct packed_git *p, { if (type == OBJ_REF_DELTA) { unsigned char *base = use_pack(p, w_curs, curpos, NULL); - oidread(oid, base, the_repository->hash_algo); + oidread(oid, base, p->repo->hash_algo); return 0; } else if (type == OBJ_OFS_DELTA) { uint32_t base_pos; @@ -1489,7 +1504,9 @@ void clear_delta_base_cache(void) } static void add_delta_base_cache(struct packed_git *p, off_t base_offset, - void *base, unsigned long base_size, enum object_type type) + void *base, unsigned long base_size, + unsigned long delta_base_cache_limit, + enum object_type type) { struct delta_base_cache_entry *ent; struct list_head *lru, *tmp; @@ -1606,7 +1623,7 @@ int packed_object_info(struct repository *r, struct packed_git *p, goto out; } } else - oidclr(oi->delta_base_oid, the_repository->hash_algo); + oidclr(oi->delta_base_oid, p->repo->hash_algo); } oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED : @@ -1691,6 +1708,8 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC; int base_from_cache = 0; + prepare_repo_settings(p->repo); + write_pack_access_log(p, obj_offset); /* PHASE 1: drill down to the innermost base object */ @@ -1871,7 +1890,9 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset, * before we are done using it. */ if (!external_base) - add_delta_base_cache(p, base_obj_offset, base, base_size, type); + add_delta_base_cache(p, base_obj_offset, base, base_size, + p->repo->settings.delta_base_cache_limit, + type); free(delta_data); free(external_base); @@ -1895,7 +1916,7 @@ int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32 { const unsigned char *index_fanout = p->index_data; const unsigned char *index_lookup; - const unsigned int hashsz = the_hash_algo->rawsz; + const unsigned int hashsz = p->repo->hash_algo->rawsz; int index_lookup_width; if (!index_fanout) @@ -1920,7 +1941,7 @@ int nth_packed_object_id(struct object_id *oid, uint32_t n) { const unsigned char *index = p->index_data; - const unsigned int hashsz = the_hash_algo->rawsz; + const unsigned int hashsz = p->repo->hash_algo->rawsz; if (!index) { if (open_pack_index(p)) return -1; @@ -1931,11 +1952,10 @@ int nth_packed_object_id(struct object_id *oid, index += 4 * 256; if (p->index_version == 1) { oidread(oid, index + st_add(st_mult(hashsz + 4, n), 4), - the_repository->hash_algo); + p->repo->hash_algo); } else { index += 8; - oidread(oid, index + st_mult(hashsz, n), - the_repository->hash_algo); + oidread(oid, index + st_mult(hashsz, n), p->repo->hash_algo); } return 0; } @@ -1957,7 +1977,7 @@ void check_pack_index_ptr(const struct packed_git *p, const void *vptr) off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n) { const unsigned char *index = p->index_data; - const unsigned int hashsz = the_hash_algo->rawsz; + const unsigned int hashsz = p->repo->hash_algo->rawsz; index += 4 * 256; if (p->index_version == 1) { return ntohl(*((uint32_t *)(index + st_mult(hashsz + 4, n)))); @@ -1974,11 +1994,10 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n) } } -off_t find_pack_entry_one(const unsigned char *sha1, - struct packed_git *p) +off_t find_pack_entry_one(const struct object_id *oid, + struct packed_git *p) { const unsigned char *index = p->index_data; - struct object_id oid; uint32_t result; if (!index) { @@ -1986,8 +2005,7 @@ off_t find_pack_entry_one(const unsigned char *sha1, return 0; } - hashcpy(oid.hash, sha1, the_repository->hash_algo); - if (bsearch_pack(&oid, p, &result)) + if (bsearch_pack(oid, p, &result)) return nth_packed_object_offset(p, result); return 0; } @@ -2013,13 +2031,13 @@ int is_pack_valid(struct packed_git *p) return !open_packed_git(p); } -struct packed_git *find_sha1_pack(const unsigned char *sha1, - struct packed_git *packs) +struct packed_git *find_oid_pack(const struct object_id *oid, + struct packed_git *packs) { struct packed_git *p; for (p = packs; p; p = p->next) { - if (find_pack_entry_one(sha1, p)) + if (find_pack_entry_one(oid, p)) return p; } return NULL; @@ -2036,7 +2054,7 @@ static int fill_pack_entry(const struct object_id *oid, oidset_contains(&p->bad_objects, oid)) return 0; - offset = find_pack_entry_one(oid->hash, p); + offset = find_pack_entry_one(oid, p); if (!offset) return 0; @@ -2139,24 +2157,17 @@ int find_kept_pack_entry(struct repository *r, return 0; } -int has_object_pack(const struct object_id *oid) +int has_object_pack(struct repository *r, const struct object_id *oid) { struct pack_entry e; - return find_pack_entry(the_repository, oid, &e); + return find_pack_entry(r, oid, &e); } -int has_object_kept_pack(const struct object_id *oid, unsigned flags) +int has_object_kept_pack(struct repository *r, const struct object_id *oid, + unsigned flags) { struct pack_entry e; - return find_kept_pack_entry(the_repository, oid, flags, &e); -} - -int has_pack_index(const unsigned char *sha1) -{ - struct stat st; - if (stat(sha1_pack_index_name(sha1), &st)) - return 0; - return 1; + return find_kept_pack_entry(r, oid, flags, &e); } int for_each_object_in_pack(struct packed_git *p, @@ -2167,7 +2178,7 @@ int for_each_object_in_pack(struct packed_git *p, int r = 0; if (flags & FOR_EACH_OBJECT_PACK_ORDER) { - if (load_pack_revindex(the_repository, p)) + if (load_pack_revindex(p->repo, p)) return -1; } @@ -2203,15 +2214,14 @@ int for_each_object_in_pack(struct packed_git *p, return r; } -int for_each_packed_object(each_packed_object_fn cb, void *data, - enum for_each_object_flags flags) +int for_each_packed_object(struct repository *repo, each_packed_object_fn cb, + void *data, enum for_each_object_flags flags) { struct packed_git *p; int r = 0; int pack_errors = 0; - prepare_packed_git(the_repository); - for (p = get_all_packs(the_repository); p; p = p->next) { + for (p = get_all_packs(repo); p; p = p->next) { if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local) continue; if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) && @@ -2235,7 +2245,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, } static int add_promisor_object(const struct object_id *oid, - struct packed_git *pack UNUSED, + struct packed_git *pack, uint32_t pos UNUSED, void *set_) { @@ -2243,12 +2253,12 @@ static int add_promisor_object(const struct object_id *oid, struct object *obj; int we_parsed_object; - obj = lookup_object(the_repository, oid); + obj = lookup_object(pack->repo, oid); if (obj && obj->parsed) { we_parsed_object = 0; } else { we_parsed_object = 1; - obj = parse_object(the_repository, oid); + obj = parse_object(pack->repo, oid); } if (!obj) @@ -2289,14 +2299,14 @@ static int add_promisor_object(const struct object_id *oid, return 0; } -int is_promisor_object(const struct object_id *oid) +int is_promisor_object(struct repository *r, const struct object_id *oid) { static struct oidset promisor_objects; static int promisor_objects_prepared; if (!promisor_objects_prepared) { - if (repo_has_promisor_remote(the_repository)) { - for_each_packed_object(add_promisor_object, + if (repo_has_promisor_remote(r)) { + for_each_packed_object(r, add_promisor_object, &promisor_objects, FOR_EACH_OBJECT_PROMISOR_ONLY | FOR_EACH_OBJECT_PACK_ORDER); @@ -2305,3 +2315,23 @@ int is_promisor_object(const struct object_id *oid) } return oidset_contains(&promisor_objects, oid); } + +int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len) +{ + unsigned char *hdr; + char *c; + + hdr = out; + put_be32(hdr, PACK_SIGNATURE); + hdr += 4; + put_be32(hdr, strtoul(in, &c, 10)); + hdr += 4; + if (*c != ',') + return -1; + put_be32(hdr, strtoul(c + 1, &c, 10)); + hdr += 4; + if (*c) + return -1; + *len = hdr - out; + return 0; +} diff --git a/packfile.h b/packfile.h index 0f7865822916ff..00ada7a938f7a9 100644 --- a/packfile.h +++ b/packfile.h @@ -29,21 +29,8 @@ struct pack_entry { * * Example: odb_pack_name(out, sha1, "idx") => ".git/objects/pack/pack-1234..idx" */ -char *odb_pack_name(struct strbuf *buf, const unsigned char *sha1, const char *ext); - -/* - * Return the name of the (local) packfile with the specified sha1 in - * its name. The return value is a pointer to memory that is - * overwritten each time this function is called. - */ -char *sha1_pack_name(const unsigned char *sha1); - -/* - * Return the name of the (local) pack index file with the specified - * sha1 in its name. The return value is a pointer to memory that is - * overwritten each time this function is called. - */ -char *sha1_pack_index_name(const unsigned char *sha1); +char *odb_pack_name(struct repository *r, struct strbuf *buf, + const unsigned char *hash, const char *ext); /* * Return the basename of the packfile, omitting any containing directory @@ -51,7 +38,17 @@ char *sha1_pack_index_name(const unsigned char *sha1); */ const char *pack_basename(struct packed_git *p); -struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); +/* + * Parse the pack idx file found at idx_path and create a packed_git struct + * which can be used with find_pack_entry_one(). + * + * You probably don't want to use this function! It skips most of the normal + * sanity checks (including whether we even have the matching .pack file), + * and does not add the resulting packed_git struct to the internal list of + * packs. You probably want add_packed_git() instead. + */ +struct packed_git *parse_pack_index(struct repository *r, 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_name, void *data); @@ -84,10 +81,15 @@ struct packed_git *get_all_packs(struct repository *r); */ unsigned long repo_approximate_object_count(struct repository *r); -struct packed_git *find_sha1_pack(const unsigned char *sha1, - struct packed_git *packs); +/* + * Find the pack within the "packs" list whose index contains the object "oid". + * For general object lookups, you probably don't want this; use + * find_pack_entry() instead. + */ +struct packed_git *find_oid_pack(const struct object_id *oid, + struct packed_git *packs); -void pack_report(void); +void pack_report(struct repository *repo); /* * mmap the index file for the specified packfile (if it is not @@ -113,7 +115,8 @@ void close_pack(struct packed_git *); void close_object_store(struct raw_object_store *o); void unuse_pack(struct pack_window **); void clear_delta_base_cache(void); -struct packed_git *add_packed_git(const char *path, size_t path_len, int local); +struct packed_git *add_packed_git(struct repository *r, const char *path, + size_t path_len, int local); /* * Unlink the .pack and associated extension files. @@ -154,10 +157,10 @@ int nth_packed_object_id(struct object_id *, struct packed_git *, uint32_t n); off_t nth_packed_object_offset(const struct packed_git *, uint32_t n); /* - * If the object named sha1 is present in the specified packfile, + * If the object named by oid is present in the specified packfile, * return its offset within the packfile; otherwise, return 0. */ -off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *); +off_t find_pack_entry_one(const struct object_id *oid, struct packed_git *); int is_pack_valid(struct packed_git *); void *unpack_entry(struct repository *r, struct packed_git *, off_t, enum object_type *, unsigned long *); @@ -190,16 +193,15 @@ const struct packed_git *has_packed_and_bad(struct repository *, const struct ob int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e); int find_kept_pack_entry(struct repository *r, const struct object_id *oid, unsigned flags, struct pack_entry *e); -int has_object_pack(const struct object_id *oid); -int has_object_kept_pack(const struct object_id *oid, unsigned flags); - -int has_pack_index(const unsigned char *sha1); +int has_object_pack(struct repository *r, const struct object_id *oid); +int has_object_kept_pack(struct repository *r, const struct object_id *oid, + unsigned flags); /* * Return 1 if an object in a promisor packfile is or refers to the given * object, 0 otherwise. */ -int is_promisor_object(const struct object_id *oid); +int is_promisor_object(struct repository *r, const struct object_id *oid); /* * Expose a function for fuzz testing. @@ -209,9 +211,15 @@ int is_promisor_object(const struct object_id *oid); * * This function should not be used directly. It is exposed here only so that we * have a convenient entry-point for fuzz testing. For real uses, you should - * probably use open_pack_index() or parse_pack_index() instead. + * probably use open_pack_index() instead. */ int load_idx(const char *path, const unsigned int hashsz, void *idx_map, size_t idx_size, struct packed_git *p); +/* + * Parse a --pack_header option as accepted by index-pack and unpack-objects, + * turning it into the matching bytes we'd find in a pack. + */ +int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len); + #endif diff --git a/pager.c b/pager.c index 40b664f893c8ec..5531fff50eb73f 100644 --- a/pager.c +++ b/pager.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "config.h" #include "editor.h" @@ -84,7 +82,7 @@ static int core_pager_config(const char *var, const char *value, return 0; } -const char *git_pager(int stdout_is_tty) +const char *git_pager(struct repository *r, int stdout_is_tty) { const char *pager; @@ -94,7 +92,7 @@ const char *git_pager(int stdout_is_tty) pager = getenv("GIT_PAGER"); if (!pager) { if (!pager_program) - read_early_config(the_repository, + read_early_config(r, core_pager_config, NULL); pager = pager_program; } @@ -143,10 +141,10 @@ void prepare_pager_args(struct child_process *pager_process, const char *pager) pager_process->trace2_child_class = "pager"; } -void setup_pager(void) +void setup_pager(struct repository *r) { static int once = 0; - const char *pager = git_pager(isatty(1)); + const char *pager = git_pager(r, isatty(1)); if (!pager) return; @@ -293,7 +291,7 @@ static int pager_command_config(const char *var, const char *value, } /* returns 0 for "no pager", 1 for "use pager", and -1 for "not specified" */ -int check_pager_config(const char *cmd) +int check_pager_config(struct repository *r, const char *cmd) { struct pager_command_config_data data; @@ -301,7 +299,7 @@ int check_pager_config(const char *cmd) data.want = -1; data.value = NULL; - read_early_config(the_repository, pager_command_config, &data); + read_early_config(r, pager_command_config, &data); if (data.value) pager_program = data.value; diff --git a/pager.h b/pager.h index 103ecac476fdd6..d070be63489716 100644 --- a/pager.h +++ b/pager.h @@ -2,15 +2,16 @@ #define PAGER_H struct child_process; +struct repository; -const char *git_pager(int stdout_is_tty); -void setup_pager(void); +const char *git_pager(struct repository *r, int stdout_is_tty); +void setup_pager(struct repository *r); void wait_for_pager(void); int pager_in_use(void); int term_columns(void); void term_clear_line(void); int decimal_width(uintmax_t); -int check_pager_config(const char *cmd); +int check_pager_config(struct repository *r, const char *cmd); void prepare_pager_args(struct child_process *, const char *pager); extern int pager_use_color; diff --git a/parallel-checkout.c b/parallel-checkout.c index 01736f1352a5dc..7cc6b3052819ac 100644 --- a/parallel-checkout.c +++ b/parallel-checkout.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" diff --git a/parse-options.c b/parse-options.c index 30b9e68f8ac85d..35fbb3b0d633df 100644 --- a/parse-options.c +++ b/parse-options.c @@ -60,12 +60,12 @@ static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p, return 0; } -static void fix_filename(const char *prefix, char **file) +static char *fix_filename(const char *prefix, const char *file) { if (!file || !*file) - ; /* leave as NULL */ + return NULL; else - *file = prefix_filename_except_for_dash(prefix, *file); + return prefix_filename_except_for_dash(prefix, file); } static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p, @@ -129,18 +129,24 @@ static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p, return 0; case OPTION_FILENAME: + { + const char *value; + + FREE_AND_NULL(*(char **)opt->value); + err = 0; + if (unset) - *(const char **)opt->value = NULL; + value = NULL; else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) - *(const char **)opt->value = (const char *)opt->defval; + value = (const char *) opt->defval; else - err = get_arg(p, opt, flags, (const char **)opt->value); + err = get_arg(p, opt, flags, &value); if (!err) - fix_filename(p->prefix, (char **)opt->value); + *(char **)opt->value = fix_filename(p->prefix, value); return err; - + } case OPTION_CALLBACK: { const char *p_arg = NULL; @@ -1070,11 +1076,48 @@ static int usage_argh(const struct option *opts, FILE *outfile) !opts->argh || !!strpbrk(opts->argh, "()<>[]|"); if (opts->flags & PARSE_OPT_OPTARG) if (opts->long_name) - s = literal ? "[=%s]" : "[=<%s>]"; + /* + * TRANSLATORS: The "<%s>" part of this string + * stands for an optional value given to a command + * line option in the long form, and "<>" is there + * as a convention to signal that it is a + * placeholder (i.e. the user should substitute it + * with the real value). If your language uses a + * different convention, you can change "<%s>" part + * to match yours, e.g. it might use "|%s|" instead, + * or if the alphabet is different enough it may use + * "%s" without any placeholder signal. Most + * translations leave this message as is. + */ + s = literal ? "[=%s]" : _("[=<%s>]"); else - s = literal ? "[%s]" : "[<%s>]"; + /* + * TRANSLATORS: The "<%s>" part of this string + * stands for an optional value given to a command + * line option in the short form, and "<>" is there + * as a convention to signal that it is a + * placeholder (i.e. the user should substitute it + * with the real value). If your language uses a + * different convention, you can change "<%s>" part + * to match yours, e.g. it might use "|%s|" instead, + * or if the alphabet is different enough it may use + * "%s" without any placeholder signal. Most + * translations leave this message as is. + */ + s = literal ? "[%s]" : _("[<%s>]"); else - s = literal ? " %s" : " <%s>"; + /* + * TRANSLATORS: The "<%s>" part of this string stands for a + * value given to a command line option, and "<>" is there + * as a convention to signal that it is a placeholder + * (i.e. the user should substitute it with the real value). + * If your language uses a different convention, you can + * change "<%s>" part to match yours, e.g. it might use + * "|%s|" instead, or if the alphabet is different enough it + * may use "%s" without any placeholder signal. Most + * translations leave this message as is. + */ + s = literal ? " %s" : _(" <%s>"); return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("...")); } @@ -1276,6 +1319,16 @@ void NORETURN usage_with_options(const char * const *usagestr, exit(129); } +void show_usage_with_options_if_asked(int ac, const char **av, + const char * const *usagestr, + const struct option *opts) +{ + if (ac == 2 && !strcmp(av[1], "-h")) { + usage_with_options_internal(NULL, usagestr, opts, 0, 0); + exit(129); + } +} + void NORETURN usage_msg_opt(const char *msg, const char * const *usagestr, const struct option *options) diff --git a/parse-options.h b/parse-options.h index ae15342390837c..997ffbee8050d7 100644 --- a/parse-options.h +++ b/parse-options.h @@ -3,8 +3,10 @@ #include "gettext.h" +struct repository; + /** - * Refer to Documentation/technical/api-parse-options.txt for the API doc. + * Refer to Documentation/technical/api-parse-options.adoc for the API doc. */ enum parse_opt_type { @@ -73,7 +75,7 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx, const char *arg, int unset); typedef int parse_opt_subcommand_fn(int argc, const char **argv, - const char *prefix); + const char *prefix, struct repository *repo); /* * `type`:: @@ -351,6 +353,18 @@ struct option { .callback = parse_opt_noop_cb, \ } +static char *parse_options_noop_ignored_value MAYBE_UNUSED; +#define OPT_NOOP_ARG(s, l) { \ + .type = OPTION_CALLBACK, \ + .short_name = (s), \ + .long_name = (l), \ + .value = &parse_options_noop_ignored_value, \ + .argh = "ignored", \ + .help = N_("no-op (backward compatibility)"), \ + .flags = PARSE_OPT_HIDDEN, \ + .callback = parse_opt_noop_cb, \ +} + #define OPT_ALIAS(s, l, source_long_name) { \ .type = OPTION_ALIAS, \ .short_name = (s), \ @@ -388,6 +402,10 @@ int parse_options(int argc, const char **argv, const char *prefix, NORETURN void usage_with_options(const char * const *usagestr, const struct option *options); +void show_usage_with_options_if_asked(int ac, const char **av, + const char * const *usage, + const struct option *options); + NORETURN void usage_msg_opt(const char *msg, const char * const *usagestr, const struct option *options); @@ -418,6 +436,15 @@ static inline void die_for_incompatible_opt3(int opt1, const char *opt1_name, 0, ""); } +static inline void die_for_incompatible_opt2(int opt1, const char *opt1_name, + int opt2, const char *opt2_name) +{ + die_for_incompatible_opt4(opt1, opt1_name, + opt2, opt2_name, + 0, "", + 0, ""); +} + /* * Use these assertions for callbacks that expect to be called with NONEG and * NOARG respectively, and do not otherwise handle the "unset" and "arg" diff --git a/path-walk.c b/path-walk.c new file mode 100644 index 00000000000000..341bdd2ba4ef46 --- /dev/null +++ b/path-walk.c @@ -0,0 +1,609 @@ +/* + * path-walk.c: implementation for path-based walks of the object graph. + */ +#include "git-compat-util.h" +#include "path-walk.h" +#include "blob.h" +#include "commit.h" +#include "dir.h" +#include "hashmap.h" +#include "hex.h" +#include "list-objects.h" +#include "object.h" +#include "oid-array.h" +#include "prio-queue.h" +#include "repository.h" +#include "revision.h" +#include "string-list.h" +#include "strmap.h" +#include "tag.h" +#include "trace2.h" +#include "tree.h" +#include "tree-walk.h" + +static const char *root_path = ""; + +struct type_and_oid_list { + enum object_type type; + struct oid_array oids; + int maybe_interesting; +}; + +#define TYPE_AND_OID_LIST_INIT { \ + .type = OBJ_NONE, \ + .oids = OID_ARRAY_INIT \ +} + +struct path_walk_context { + /** + * Repeats of data in 'struct path_walk_info' for + * access with fewer characters. + */ + struct repository *repo; + struct rev_info *revs; + struct path_walk_info *info; + + /** + * Map a path to a 'struct type_and_oid_list' + * containing the objects discovered at that + * path. + */ + struct strmap paths_to_lists; + + /** + * Store the current list of paths in a priority queue, + * using object type as a sorting mechanism, mostly to + * make sure blobs are popped off the stack first. No + * other sort is made, so within each object type it acts + * like a stack and performs a DFS within the trees. + * + * Use path_stack_pushed to indicate whether a path + * was previously added to path_stack. + */ + struct prio_queue path_stack; + struct strset path_stack_pushed; +}; + +static int compare_by_type(const void *one, const void *two, void *cb_data) +{ + struct type_and_oid_list *list1, *list2; + const char *str1 = one; + const char *str2 = two; + struct path_walk_context *ctx = cb_data; + + list1 = strmap_get(&ctx->paths_to_lists, str1); + list2 = strmap_get(&ctx->paths_to_lists, str2); + + /* + * If object types are equal, then use path comparison. + */ + if (!list1 || !list2 || list1->type == list2->type) + return strcmp(str1, str2); + + /* Prefer tags to be popped off first. */ + if (list1->type == OBJ_TAG) + return -1; + if (list2->type == OBJ_TAG) + return 1; + + /* Prefer blobs to be popped off second. */ + if (list1->type == OBJ_BLOB) + return -1; + if (list2->type == OBJ_BLOB) + return 1; + + return 0; +} + +static void push_to_stack(struct path_walk_context *ctx, + const char *path) +{ + if (strset_contains(&ctx->path_stack_pushed, path)) + return; + + strset_add(&ctx->path_stack_pushed, path); + prio_queue_put(&ctx->path_stack, xstrdup(path)); +} + +static int add_tree_entries(struct path_walk_context *ctx, + const char *base_path, + struct object_id *oid) +{ + struct tree_desc desc; + struct name_entry entry; + struct strbuf path = STRBUF_INIT; + size_t base_len; + struct tree *tree = lookup_tree(ctx->repo, oid); + + if (!tree) { + error(_("failed to walk children of tree %s: not found"), + oid_to_hex(oid)); + return -1; + } else if (parse_tree_gently(tree, 1)) { + error("bad tree object %s", oid_to_hex(oid)); + return -1; + } + + strbuf_addstr(&path, base_path); + base_len = path.len; + + init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size); + while (tree_entry(&desc, &entry)) { + struct type_and_oid_list *list; + struct object *o; + /* Not actually true, but we will ignore submodules later. */ + enum object_type type = S_ISDIR(entry.mode) ? OBJ_TREE : OBJ_BLOB; + + /* Skip submodules. */ + if (S_ISGITLINK(entry.mode)) + continue; + + /* If the caller doesn't want blobs, then don't bother. */ + if (!ctx->info->blobs && type == OBJ_BLOB) + continue; + + if (type == OBJ_TREE) { + struct tree *child = lookup_tree(ctx->repo, &entry.oid); + o = child ? &child->object : NULL; + } else if (type == OBJ_BLOB) { + struct blob *child = lookup_blob(ctx->repo, &entry.oid); + o = child ? &child->object : NULL; + } else { + BUG("invalid type for tree entry: %d", type); + } + + if (!o) { + error(_("failed to find object %s"), + oid_to_hex(&o->oid)); + return -1; + } + + /* Skip this object if already seen. */ + if (o->flags & SEEN) + continue; + o->flags |= SEEN; + + strbuf_setlen(&path, base_len); + strbuf_add(&path, entry.path, entry.pathlen); + + /* + * Trees will end with "/" for concatenation and distinction + * from blobs at the same path. + */ + if (type == OBJ_TREE) + strbuf_addch(&path, '/'); + + if (ctx->info->pl) { + int dtype; + enum pattern_match_result match; + match = path_matches_pattern_list(path.buf, path.len, + path.buf + base_len, &dtype, + ctx->info->pl, + ctx->repo->index); + + if (ctx->info->pl->use_cone_patterns && + match == NOT_MATCHED) + continue; + else if (!ctx->info->pl->use_cone_patterns && + type == OBJ_BLOB && + match != MATCHED) + continue; + } + + if (!(list = strmap_get(&ctx->paths_to_lists, path.buf))) { + CALLOC_ARRAY(list, 1); + list->type = type; + strmap_put(&ctx->paths_to_lists, path.buf, list); + } + push_to_stack(ctx, path.buf); + + if (!(o->flags & UNINTERESTING)) + list->maybe_interesting = 1; + + oid_array_append(&list->oids, &entry.oid); + } + + free_tree_buffer(tree); + strbuf_release(&path); + return 0; +} + +/* + * For each path in paths_to_explore, walk the trees another level + * and add any found blobs to the batch (but only if they exist and + * haven't been added yet). + */ +static int walk_path(struct path_walk_context *ctx, + const char *path) +{ + struct type_and_oid_list *list; + int ret = 0; + + list = strmap_get(&ctx->paths_to_lists, path); + + if (!list) + BUG("provided path '%s' that had no associated list", path); + + if (!list->oids.nr) + return 0; + + if (ctx->info->prune_all_uninteresting) { + /* + * This is true if all objects were UNINTERESTING + * when added to the list. + */ + if (!list->maybe_interesting) + return 0; + + /* + * But it's still possible that the objects were set + * as UNINTERESTING after being added. Do a quick check. + */ + list->maybe_interesting = 0; + for (size_t i = 0; + !list->maybe_interesting && i < list->oids.nr; + i++) { + if (list->type == OBJ_TREE) { + struct tree *t = lookup_tree(ctx->repo, + &list->oids.oid[i]); + if (t && !(t->object.flags & UNINTERESTING)) + list->maybe_interesting = 1; + } else if (list->type == OBJ_BLOB) { + struct blob *b = lookup_blob(ctx->repo, + &list->oids.oid[i]); + if (b && !(b->object.flags & UNINTERESTING)) + list->maybe_interesting = 1; + } else { + /* Tags are always interesting if visited. */ + list->maybe_interesting = 1; + } + } + + /* We have confirmed that all objects are UNINTERESTING. */ + if (!list->maybe_interesting) + return 0; + } + + /* Evaluate function pointer on this data, if requested. */ + if ((list->type == OBJ_TREE && ctx->info->trees) || + (list->type == OBJ_BLOB && ctx->info->blobs) || + (list->type == OBJ_TAG && ctx->info->tags)) + ret = ctx->info->path_fn(path, &list->oids, list->type, + ctx->info->path_fn_data); + + /* Expand data for children. */ + if (list->type == OBJ_TREE) { + for (size_t i = 0; i < list->oids.nr; i++) { + ret |= add_tree_entries(ctx, + path, + &list->oids.oid[i]); + } + } + + oid_array_clear(&list->oids); + strmap_remove(&ctx->paths_to_lists, path, 1); + return ret; +} + +static void clear_paths_to_lists(struct strmap *map) +{ + struct hashmap_iter iter; + struct strmap_entry *e; + + hashmap_for_each_entry(&map->map, &iter, e, ent) { + struct type_and_oid_list *list = e->value; + oid_array_clear(&list->oids); + } + strmap_clear(map, 1); + strmap_init(map); +} + +static struct repository *edge_repo; +static struct type_and_oid_list *edge_tree_list; + +static void show_edge(struct commit *commit) +{ + struct tree *t = repo_get_commit_tree(edge_repo, commit); + + if (!t) + return; + + if (commit->object.flags & UNINTERESTING) + t->object.flags |= UNINTERESTING; + + if (t->object.flags & SEEN) + return; + t->object.flags |= SEEN; + + oid_array_append(&edge_tree_list->oids, &t->object.oid); +} + +static int setup_pending_objects(struct path_walk_info *info, + struct path_walk_context *ctx) +{ + struct type_and_oid_list *tags = NULL; + struct type_and_oid_list *tagged_blobs = NULL; + struct type_and_oid_list *root_tree_list = NULL; + + if (info->tags) + CALLOC_ARRAY(tags, 1); + if (info->blobs) + CALLOC_ARRAY(tagged_blobs, 1); + if (info->trees) + root_tree_list = strmap_get(&ctx->paths_to_lists, root_path); + + /* + * Pending objects include: + * * Commits at branch tips. + * * Annotated tags at tag tips. + * * Any kind of object at lightweight tag tips. + * * Trees and blobs in the index (with an associated path). + */ + for (size_t i = 0; i < info->revs->pending.nr; i++) { + struct object_array_entry *pending = info->revs->pending.objects + i; + struct object *obj = pending->item; + + /* Commits will be picked up by revision walk. */ + if (obj->type == OBJ_COMMIT) + continue; + + /* Navigate annotated tag object chains. */ + while (obj->type == OBJ_TAG) { + struct tag *tag = lookup_tag(info->revs->repo, &obj->oid); + if (!tag) { + error(_("failed to find tag %s"), + oid_to_hex(&obj->oid)); + return -1; + } + if (tag->object.flags & SEEN) + break; + tag->object.flags |= SEEN; + + if (tags) + oid_array_append(&tags->oids, &obj->oid); + obj = tag->tagged; + } + + if (obj->type == OBJ_TAG) + continue; + + /* We are now at a non-tag object. */ + if (obj->flags & SEEN) + continue; + obj->flags |= SEEN; + + switch (obj->type) { + case OBJ_TREE: + if (!info->trees) + continue; + if (pending->path) { + struct type_and_oid_list *list; + char *path = *pending->path ? xstrfmt("%s/", pending->path) + : xstrdup(""); + if (!(list = strmap_get(&ctx->paths_to_lists, path))) { + CALLOC_ARRAY(list, 1); + list->type = OBJ_TREE; + strmap_put(&ctx->paths_to_lists, path, list); + } + oid_array_append(&list->oids, &obj->oid); + free(path); + } else { + /* assume a root tree, such as a lightweight tag. */ + oid_array_append(&root_tree_list->oids, &obj->oid); + } + break; + + case OBJ_BLOB: + if (!info->blobs) + continue; + if (pending->path) { + struct type_and_oid_list *list; + char *path = pending->path; + if (!(list = strmap_get(&ctx->paths_to_lists, path))) { + CALLOC_ARRAY(list, 1); + list->type = OBJ_BLOB; + strmap_put(&ctx->paths_to_lists, path, list); + } + oid_array_append(&list->oids, &obj->oid); + } else { + /* assume a root tree, such as a lightweight tag. */ + oid_array_append(&tagged_blobs->oids, &obj->oid); + } + break; + + case OBJ_COMMIT: + /* Make sure it is in the object walk */ + if (obj != pending->item) + add_pending_object(info->revs, obj, ""); + break; + + default: + BUG("should not see any other type here"); + } + } + + /* + * Add tag objects and tagged blobs if they exist. + */ + if (tagged_blobs) { + if (tagged_blobs->oids.nr) { + const char *tagged_blob_path = "/tagged-blobs"; + tagged_blobs->type = OBJ_BLOB; + tagged_blobs->maybe_interesting = 1; + strmap_put(&ctx->paths_to_lists, tagged_blob_path, tagged_blobs); + push_to_stack(ctx, tagged_blob_path); + } else { + oid_array_clear(&tagged_blobs->oids); + free(tagged_blobs); + } + } + if (tags) { + if (tags->oids.nr) { + const char *tag_path = "/tags"; + tags->type = OBJ_TAG; + tags->maybe_interesting = 1; + strmap_put(&ctx->paths_to_lists, tag_path, tags); + push_to_stack(ctx, tag_path); + } else { + oid_array_clear(&tags->oids); + free(tags); + } + } + + return 0; +} + +/** + * Given the configuration of 'info', walk the commits based on 'info->revs' and + * call 'info->path_fn' on each discovered path. + * + * Returns nonzero on an error. + */ +int walk_objects_by_path(struct path_walk_info *info) +{ + int ret; + size_t commits_nr = 0, paths_nr = 0; + struct commit *c; + struct type_and_oid_list *root_tree_list; + struct type_and_oid_list *commit_list; + struct path_walk_context ctx = { + .repo = info->revs->repo, + .revs = info->revs, + .info = info, + .path_stack = { + .compare = compare_by_type, + .cb_data = &ctx + }, + .path_stack_pushed = STRSET_INIT, + .paths_to_lists = STRMAP_INIT + }; + + trace2_region_enter("path-walk", "commit-walk", info->revs->repo); + + CALLOC_ARRAY(commit_list, 1); + commit_list->type = OBJ_COMMIT; + + if (info->tags) + info->revs->tag_objects = 1; + + /* Insert a single list for the root tree into the paths. */ + CALLOC_ARRAY(root_tree_list, 1); + root_tree_list->type = OBJ_TREE; + root_tree_list->maybe_interesting = 1; + strmap_put(&ctx.paths_to_lists, root_path, root_tree_list); + push_to_stack(&ctx, root_path); + + /* + * Set these values before preparing the walk to catch + * lightweight tags pointing to non-commits and indexed objects. + */ + info->revs->blob_objects = info->blobs; + info->revs->tree_objects = info->trees; + + if (prepare_revision_walk(info->revs)) + die(_("failed to setup revision walk")); + + /* Walk trees to mark them as UNINTERESTING. */ + edge_repo = info->revs->repo; + edge_tree_list = root_tree_list; + mark_edges_uninteresting(info->revs, show_edge, + info->prune_all_uninteresting); + edge_repo = NULL; + edge_tree_list = NULL; + + info->revs->blob_objects = info->revs->tree_objects = 0; + + trace2_region_enter("path-walk", "pending-walk", info->revs->repo); + ret = setup_pending_objects(info, &ctx); + trace2_region_leave("path-walk", "pending-walk", info->revs->repo); + + if (ret) + return ret; + + while ((c = get_revision(info->revs))) { + struct object_id *oid; + struct tree *t; + commits_nr++; + + if (info->commits) + oid_array_append(&commit_list->oids, + &c->object.oid); + + /* If we only care about commits, then skip trees. */ + if (!info->trees && !info->blobs) + continue; + + oid = get_commit_tree_oid(c); + t = lookup_tree(info->revs->repo, oid); + + if (!t) { + error("could not find tree %s", oid_to_hex(oid)); + return -1; + } + + if (t->object.flags & SEEN) + continue; + t->object.flags |= SEEN; + oid_array_append(&root_tree_list->oids, oid); + } + + trace2_data_intmax("path-walk", ctx.repo, "commits", commits_nr); + trace2_region_leave("path-walk", "commit-walk", info->revs->repo); + + /* Track all commits. */ + if (info->commits && commit_list->oids.nr) + ret = info->path_fn("", &commit_list->oids, OBJ_COMMIT, + info->path_fn_data); + oid_array_clear(&commit_list->oids); + free(commit_list); + + trace2_region_enter("path-walk", "path-walk", info->revs->repo); + while (!ret && ctx.path_stack.nr) { + char *path = prio_queue_get(&ctx.path_stack); + paths_nr++; + + ret = walk_path(&ctx, path); + + free(path); + } + + /* Are there paths remaining? Likely they are from indexed objects. */ + if (!strmap_empty(&ctx.paths_to_lists)) { + struct hashmap_iter iter; + struct strmap_entry *entry; + + strmap_for_each_entry(&ctx.paths_to_lists, &iter, entry) + push_to_stack(&ctx, entry->key); + + while (!ret && ctx.path_stack.nr) { + char *path = prio_queue_get(&ctx.path_stack); + paths_nr++; + + ret = walk_path(&ctx, path); + + free(path); + } + } + + trace2_data_intmax("path-walk", ctx.repo, "paths", paths_nr); + trace2_region_leave("path-walk", "path-walk", info->revs->repo); + + clear_paths_to_lists(&ctx.paths_to_lists); + strset_clear(&ctx.path_stack_pushed); + clear_prio_queue(&ctx.path_stack); + return ret; +} + +void path_walk_info_init(struct path_walk_info *info) +{ + struct path_walk_info empty = PATH_WALK_INFO_INIT; + memcpy(info, &empty, sizeof(empty)); +} + +void path_walk_info_clear(struct path_walk_info *info) +{ + if (info->pl) { + clear_pattern_list(info->pl); + free(info->pl); + } +} diff --git a/path-walk.h b/path-walk.h new file mode 100644 index 00000000000000..473ee9d361c864 --- /dev/null +++ b/path-walk.h @@ -0,0 +1,80 @@ +/* + * path-walk.h : Methods and structures for walking the object graph in batches + * by the paths that can reach those objects. + */ +#include "object.h" /* Required for 'enum object_type'. */ + +struct rev_info; +struct oid_array; +struct pattern_list; + +/** + * The type of a function pointer for the method that is called on a list of + * objects reachable at a given path. + */ +typedef int (*path_fn)(const char *path, + struct oid_array *oids, + enum object_type type, + void *data); + +struct path_walk_info { + /** + * revs provides the definitions for the commit walk, including + * which commits are UNINTERESTING or not. This structure is + * expected to be owned by the caller. + */ + struct rev_info *revs; + + /** + * The caller wishes to execute custom logic on objects reachable at a + * given path. Every reachable object will be visited exactly once, and + * the first path to see an object wins. This may not be a stable choice. + */ + path_fn path_fn; + void *path_fn_data; + + /** + * Initialize which object types the path_fn should be called on. This + * could also limit the walk to skip blobs if not set. + */ + int commits; + int trees; + int blobs; + int tags; + + /** + * When 'prune_all_uninteresting' is set and a path has all objects + * marked as UNINTERESTING, then the path-walk will not visit those + * objects. It will not call path_fn on those objects and will not + * walk the children of such trees. + */ + int prune_all_uninteresting; + + /** + * Specify a sparse-checkout definition to match our paths to. Do not + * walk outside of this sparse definition. If the patterns are in + * cone mode, then the search may prune directories that are outside + * of the cone. If not in cone mode, then all tree paths will be + * explored but the path_fn will only be called when the path matches + * the sparse-checkout patterns. + */ + struct pattern_list *pl; +}; + +#define PATH_WALK_INFO_INIT { \ + .blobs = 1, \ + .trees = 1, \ + .commits = 1, \ + .tags = 1, \ +} + +void path_walk_info_init(struct path_walk_info *info); +void path_walk_info_clear(struct path_walk_info *info); + +/** + * Given the configuration of 'info', walk the commits based on 'info->revs' and + * call 'info->path_fn' on each discovered path. + * + * Returns nonzero on an error. + */ +int walk_objects_by_path(struct path_walk_info *info); diff --git a/path.c b/path.c index 93491bab141c56..910756c8b3249c 100644 --- a/path.c +++ b/path.c @@ -2,8 +2,6 @@ * Utilities for paths and pathnames */ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "abspath.h" #include "environment.h" @@ -30,7 +28,7 @@ static int get_st_mode_bits(const char *path, int *mode) return 0; } -struct strbuf *get_pathname(void) +static struct strbuf *get_pathname(void) { static struct strbuf pathname_array[4] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT @@ -387,10 +385,11 @@ void report_linked_checkout_garbage(struct repository *r) strbuf_release(&sb); } -static void adjust_git_path(const struct repository *repo, +static void adjust_git_path(struct repository *repo, struct strbuf *buf, int git_dir_len) { const char *base = buf->buf + git_dir_len; + if (is_dir_file(base, "info", "grafts")) strbuf_splice(buf, 0, buf->len, repo->graft_file, strlen(repo->graft_file)); @@ -399,8 +398,8 @@ static void adjust_git_path(const struct repository *repo, repo->index_file, strlen(repo->index_file)); else if (dir_prefix(base, "objects")) replace_dir(buf, git_dir_len + 7, repo->objects->odb->path); - else if (git_hooks_path && dir_prefix(base, "hooks")) - replace_dir(buf, git_dir_len + 5, git_hooks_path); + else if (repo_settings_get_hooks_path(repo) && dir_prefix(base, "hooks")) + replace_dir(buf, git_dir_len + 5, repo_settings_get_hooks_path(repo)); else if (repo->different_commondir) update_common_dir(buf, git_dir_len, repo->commondir); } @@ -414,12 +413,12 @@ static void strbuf_worktree_gitdir(struct strbuf *buf, else if (!wt->id) strbuf_addstr(buf, repo->commondir); else - strbuf_git_common_path(buf, repo, "worktrees/%s", wt->id); + repo_common_path_append(repo, buf, "worktrees/%s", wt->id); } -void repo_git_pathv(const struct repository *repo, - const struct worktree *wt, struct strbuf *buf, - const char *fmt, va_list args) +static void repo_git_pathv(struct repository *repo, + const struct worktree *wt, struct strbuf *buf, + const char *fmt, va_list args) { int gitdir_len; strbuf_worktree_gitdir(buf, repo, wt); @@ -432,7 +431,7 @@ void repo_git_pathv(const struct repository *repo, strbuf_cleanup_path(buf); } -char *repo_git_path(const struct repository *repo, +char *repo_git_path(struct repository *repo, const char *fmt, ...) { struct strbuf path = STRBUF_INIT; @@ -443,14 +442,27 @@ char *repo_git_path(const struct repository *repo, return strbuf_detach(&path, NULL); } -void strbuf_repo_git_path(struct strbuf *sb, - const struct repository *repo, - const char *fmt, ...) +const char *repo_git_path_append(struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) { va_list args; va_start(args, fmt); repo_git_pathv(repo, NULL, sb, fmt, args); va_end(args); + return sb->buf; +} + +const char *repo_git_path_replace(struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) +{ + va_list args; + strbuf_reset(sb); + va_start(args, fmt); + repo_git_pathv(repo, NULL, sb, fmt, args); + va_end(args); + return sb->buf; } char *mkpathdup(const char *fmt, ...) @@ -506,39 +518,56 @@ char *repo_worktree_path(const struct repository *repo, const char *fmt, ...) struct strbuf path = STRBUF_INIT; va_list args; + va_start(args, fmt); + do_worktree_path(repo, &path, fmt, args); + va_end(args); + + return strbuf_detach(&path, NULL); +} + +const char *repo_worktree_path_append(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) +{ + va_list args; + if (!repo->worktree) return NULL; va_start(args, fmt); - do_worktree_path(repo, &path, fmt, args); + do_worktree_path(repo, sb, fmt, args); va_end(args); - return strbuf_detach(&path, NULL); + return sb->buf; } -void strbuf_repo_worktree_path(struct strbuf *sb, - const struct repository *repo, - const char *fmt, ...) +const char *repo_worktree_path_replace(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) { va_list args; + strbuf_reset(sb); if (!repo->worktree) - return; + return NULL; va_start(args, fmt); do_worktree_path(repo, sb, fmt, args); va_end(args); + + return sb->buf; } /* Returns 0 on success, negative on failure. */ -static int do_submodule_path(struct strbuf *buf, const char *path, +static int do_submodule_path(struct repository *repo, + struct strbuf *buf, const char *path, const char *fmt, va_list args) { struct strbuf git_submodule_common_dir = STRBUF_INIT; struct strbuf git_submodule_dir = STRBUF_INIT; int ret; - ret = submodule_to_gitdir(&git_submodule_dir, path); + ret = submodule_to_gitdir(repo, &git_submodule_dir, path); if (ret) goto cleanup; @@ -557,13 +586,14 @@ static int do_submodule_path(struct strbuf *buf, const char *path, return ret; } -char *git_pathdup_submodule(const char *path, const char *fmt, ...) +char *repo_submodule_path(struct repository *repo, + const char *path, const char *fmt, ...) { int err; va_list args; struct strbuf buf = STRBUF_INIT; va_start(args, fmt); - err = do_submodule_path(&buf, path, fmt, args); + err = do_submodule_path(repo, &buf, path, fmt, args); va_end(args); if (err) { strbuf_release(&buf); @@ -572,22 +602,41 @@ char *git_pathdup_submodule(const char *path, const char *fmt, ...) return strbuf_detach(&buf, NULL); } -int strbuf_git_path_submodule(struct strbuf *buf, const char *path, - const char *fmt, ...) +const char *repo_submodule_path_append(struct repository *repo, + struct strbuf *buf, + const char *path, + const char *fmt, ...) { int err; va_list args; va_start(args, fmt); - err = do_submodule_path(buf, path, fmt, args); + err = do_submodule_path(repo, buf, path, fmt, args); va_end(args); + if (err) + return NULL; + return buf->buf; +} - return err; +const char *repo_submodule_path_replace(struct repository *repo, + struct strbuf *buf, + const char *path, + const char *fmt, ...) +{ + int err; + va_list args; + strbuf_reset(buf); + va_start(args, fmt); + err = do_submodule_path(repo, buf, path, fmt, args); + va_end(args); + if (err) + return NULL; + return buf->buf; } -void repo_common_pathv(const struct repository *repo, - struct strbuf *sb, - const char *fmt, - va_list args) +static void repo_common_pathv(const struct repository *repo, + struct strbuf *sb, + const char *fmt, + va_list args) { strbuf_addstr(sb, repo->commondir); if (sb->len && !is_dir_sep(sb->buf[sb->len - 1])) @@ -596,14 +645,38 @@ void repo_common_pathv(const struct repository *repo, strbuf_cleanup_path(sb); } -void strbuf_git_common_path(struct strbuf *sb, - const struct repository *repo, - const char *fmt, ...) +char *repo_common_path(const struct repository *repo, + const char *fmt, ...) { + struct strbuf sb = STRBUF_INIT; va_list args; va_start(args, fmt); + repo_common_pathv(repo, &sb, fmt, args); + va_end(args); + return strbuf_detach(&sb, NULL); +} + +const char *repo_common_path_append(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + repo_common_pathv(repo, sb, fmt, args); + va_end(args); + return sb->buf; +} + +const char *repo_common_path_replace(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) +{ + va_list args; + strbuf_reset(sb); + va_start(args, fmt); repo_common_pathv(repo, sb, fmt, args); va_end(args); + return sb->buf; } static struct passwd *getpw_str(const char *username, size_t len) @@ -684,7 +757,7 @@ char *interpolate_path(const char *path, int real_home) * links. User relative paths are also returned as they are given, * except DWIM suffixing. */ -const char *enter_repo(const char *path, int strict) +const char *enter_repo(const char *path, unsigned flags) { static struct strbuf validated_path = STRBUF_INIT; static struct strbuf used_path = STRBUF_INIT; @@ -692,7 +765,7 @@ const char *enter_repo(const char *path, int strict) if (!path) return NULL; - if (!strict) { + if (!(flags & ENTER_REPO_STRICT)) { static const char *suffix[] = { "/.git", "", ".git/.git", ".git", NULL, }; @@ -736,7 +809,8 @@ const char *enter_repo(const char *path, int strict) if (!suffix[i]) return NULL; gitfile = read_gitfile(used_path.buf); - die_upon_dubious_ownership(gitfile, NULL, used_path.buf); + if (!(flags & ENTER_REPO_ANY_OWNER_OK)) + die_upon_dubious_ownership(gitfile, NULL, used_path.buf); if (gitfile) { strbuf_reset(&used_path); strbuf_addstr(&used_path, gitfile); @@ -747,7 +821,8 @@ const char *enter_repo(const char *path, int strict) } else { const char *gitfile = read_gitfile(path); - die_upon_dubious_ownership(gitfile, NULL, path); + if (!(flags & ENTER_REPO_ANY_OWNER_OK)) + die_upon_dubious_ownership(gitfile, NULL, path); if (gitfile) path = gitfile; if (chdir(path)) @@ -763,21 +838,22 @@ const char *enter_repo(const char *path, int strict) return NULL; } -int calc_shared_perm(int mode) +int calc_shared_perm(struct repository *repo, + int mode) { int tweak; - if (get_shared_repository() < 0) - tweak = -get_shared_repository(); + if (repo_settings_get_shared_repository(repo) < 0) + tweak = -repo_settings_get_shared_repository(repo); else - tweak = get_shared_repository(); + tweak = repo_settings_get_shared_repository(repo); if (!(mode & S_IWUSR)) tweak &= ~0222; if (mode & S_IXUSR) /* Copy read bits to execute bits */ tweak |= (tweak & 0444) >> 2; - if (get_shared_repository() < 0) + if (repo_settings_get_shared_repository(repo) < 0) mode = (mode & ~0777) | tweak; else mode |= tweak; @@ -785,17 +861,17 @@ int calc_shared_perm(int mode) return mode; } - -int adjust_shared_perm(const char *path) +int adjust_shared_perm(struct repository *repo, + const char *path) { int old_mode, new_mode; - if (!get_shared_repository()) + if (!repo_settings_get_shared_repository(repo)) return 0; if (get_st_mode_bits(path, &old_mode) < 0) return -1; - new_mode = calc_shared_perm(old_mode); + new_mode = calc_shared_perm(repo, old_mode); if (S_ISDIR(old_mode)) { /* Copy read bits to execute bits */ new_mode |= (new_mode & 0444) >> 2; @@ -814,7 +890,7 @@ int adjust_shared_perm(const char *path) return 0; } -void safe_create_dir(const char *dir, int share) +void safe_create_dir(struct repository *repo, const char *dir, int share) { if (mkdir(dir, 0777) < 0) { if (errno != EEXIST) { @@ -822,7 +898,7 @@ void safe_create_dir(const char *dir, int share) exit(1); } } - else if (share && adjust_shared_perm(dir)) + else if (share && adjust_shared_perm(repo, dir)) die(_("Could not make %s writable by group"), dir); } @@ -1140,12 +1216,12 @@ int strbuf_normalize_path(struct strbuf *src) */ int longest_ancestor_length(const char *path, struct string_list *prefixes) { - int i, max_len = -1; + int max_len = -1; if (!strcmp(path, "/")) return -1; - for (i = 0; i < prefixes->nr; i++) { + for (size_t i = 0; i < prefixes->nr; i++) { const char *ceil = prefixes->items[i].string; int len = strlen(ceil); diff --git a/path.h b/path.h index e91d19fff60f45..65fe968a13a191 100644 --- a/path.h +++ b/path.h @@ -25,22 +25,20 @@ char *mkpathdup(const char *fmt, ...) __attribute__((format (printf, 1, 2))); /* - * The `strbuf_git_common_path` family of functions will construct a path into a + * The `repo_common_path` family of functions will construct a path into a * repository's common git directory, which is shared by all worktrees. */ - -/* - * Constructs a path into the common git directory of repository `repo` and - * append it in the provided buffer `sb`. - */ -void strbuf_git_common_path(struct strbuf *sb, - const struct repository *repo, - const char *fmt, ...) +char *repo_common_path(const struct repository *repo, + const char *fmt, ...) + __attribute__((format (printf, 2, 3))); +const char *repo_common_path_append(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) + __attribute__((format (printf, 3, 4))); +const char *repo_common_path_replace(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) __attribute__((format (printf, 3, 4))); -void repo_common_pathv(const struct repository *repo, - struct strbuf *buf, - const char *fmt, - va_list args); /* * The `repo_git_path` family of functions will construct a path into a repository's @@ -54,29 +52,16 @@ void repo_common_pathv(const struct repository *repo, * For an exhaustive list of the adjustments made look at `common_list` and * `adjust_git_path` in path.c. */ - -/* - * Return a path into the git directory of repository `repo`. - */ -char *repo_git_path(const struct repository *repo, +char *repo_git_path(struct repository *repo, const char *fmt, ...) __attribute__((format (printf, 2, 3))); - -/* - * Print a path into the git directory of repository `repo` into the provided - * buffer. - */ -void repo_git_pathv(const struct repository *repo, - const struct worktree *wt, struct strbuf *buf, - const char *fmt, va_list args); - -/* - * Construct a path into the git directory of repository `repo` and append it - * to the provided buffer `sb`. - */ -void strbuf_repo_git_path(struct strbuf *sb, - const struct repository *repo, - const char *fmt, ...) +const char *repo_git_path_append(struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) + __attribute__((format (printf, 3, 4))); +const char *repo_git_path_replace(struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) __attribute__((format (printf, 3, 4))); /* @@ -90,40 +75,44 @@ const char *worktree_git_path(struct repository *r, __attribute__((format (printf, 3, 4))); /* - * Return a path into the worktree of repository `repo`. + * The `repo_worktree_path` family of functions will construct a path into a + * repository's worktree. * - * If the repository doesn't have a worktree NULL is returned. + * Returns a `NULL` pointer in case the repository has no worktree. */ char *repo_worktree_path(const struct repository *repo, const char *fmt, ...) __attribute__((format (printf, 2, 3))); - -/* - * Construct a path into the worktree of repository `repo` and append it - * to the provided buffer `sb`. - * - * If the repository doesn't have a worktree nothing will be appended to `sb`. - */ -void strbuf_repo_worktree_path(struct strbuf *sb, - const struct repository *repo, +const char *repo_worktree_path_append(const struct repository *repo, + struct strbuf *sb, const char *fmt, ...) __attribute__((format (printf, 3, 4))); +const char *repo_worktree_path_replace(const struct repository *repo, + struct strbuf *sb, + const char *fmt, ...) + __attribute__((format (printf, 3, 4))); /* - * Return a path into a submodule's git directory located at `path`. `path` - * must only reference a submodule of the main repository (the_repository). - */ -char *git_pathdup_submodule(const char *path, const char *fmt, ...) - __attribute__((format (printf, 2, 3))); - -/* - * Construct a path into a submodule's git directory located at `path` and - * append it to the provided buffer `sb`. `path` must only reference a - * submodule of the main repository (the_repository). + * The `repo_submodule_path` family of functions will construct a path into a + * submodule's git directory located at `path`. `path` must be a submodule path + * as found in the index and must be part of the given repository. + * + * Returns a `NULL` pointer in case the submodule cannot be found. */ -int strbuf_git_path_submodule(struct strbuf *sb, const char *path, - const char *fmt, ...) +char *repo_submodule_path(struct repository *repo, + const char *path, + const char *fmt, ...) __attribute__((format (printf, 3, 4))); +const char *repo_submodule_path_append(struct repository *repo, + struct strbuf *sb, + const char *path, + const char *fmt, ...) + __attribute__((format (printf, 4, 5))); +const char *repo_submodule_path_replace(struct repository *repo, + struct strbuf *sb, + const char *path, + const char *fmt, ...) + __attribute__((format (printf, 4, 5))); void report_linked_checkout_garbage(struct repository *r); @@ -152,11 +141,26 @@ const char *git_path_shallow(struct repository *r); int ends_with_path_components(const char *path, const char *components); -int calc_shared_perm(int mode); -int adjust_shared_perm(const char *path); +int calc_shared_perm(struct repository *repo, int mode); +int adjust_shared_perm(struct repository *repo, const char *path); char *interpolate_path(const char *path, int real_home); -const char *enter_repo(const char *path, int strict); + +/* The bits are as follows: + * + * - ENTER_REPO_STRICT: callers that require exact paths (as opposed + * to allowing known suffixes like ".git", ".git/.git" to be + * omitted) can set this bit. + * + * - ENTER_REPO_ANY_OWNER_OK: callers that are willing to run without + * ownership check can set this bit. + */ +enum { + ENTER_REPO_STRICT = (1<<0), + ENTER_REPO_ANY_OWNER_OK = (1<<1), +}; + +const char *enter_repo(const char *path, unsigned flags); const char *remove_leading_path(const char *in, const char *prefix); const char *relative_path(const char *in, const char *prefix, struct strbuf *sb); int normalize_path_copy_len(char *dst, const char *src, int *prefix_len); @@ -215,101 +219,21 @@ char *xdg_cache_home(const char *filename); * directories under $GIT_DIR. Don't use it for working tree * directories. */ -void safe_create_dir(const char *dir, int share); - -/* - * Do not use this function. It is only exported to other subsystems until we - * can get rid of the below block of functions that implicitly rely on - * `the_repository`. - */ -struct strbuf *get_pathname(void); +void safe_create_dir(struct repository *repo, const char *dir, int share); # ifdef USE_THE_REPOSITORY_VARIABLE # include "strbuf.h" # include "repository.h" -/* - * Return a statically allocated path into the main repository's - * (the_repository) common git directory. - */ -__attribute__((format (printf, 1, 2))) -static inline const char *git_common_path(const char *fmt, ...) -{ - struct strbuf *pathname = get_pathname(); - va_list args; - va_start(args, fmt); - repo_common_pathv(the_repository, pathname, fmt, args); - va_end(args); - return pathname->buf; -} - -/* - * Construct a path into the main repository's (the_repository) git directory - * and place it in the provided buffer `buf`, the contents of the buffer will - * be overridden. - */ -__attribute__((format (printf, 2, 3))) -static inline char *git_path_buf(struct strbuf *buf, const char *fmt, ...) -{ - va_list args; - strbuf_reset(buf); - va_start(args, fmt); - repo_git_pathv(the_repository, NULL, buf, fmt, args); - va_end(args); - return buf->buf; -} - -/* - * Construct a path into the main repository's (the_repository) git directory - * and append it to the provided buffer `sb`. - */ -__attribute__((format (printf, 2, 3))) -static inline void strbuf_git_path(struct strbuf *sb, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - repo_git_pathv(the_repository, NULL, sb, fmt, args); - va_end(args); -} - -/* - * Return a statically allocated path into the main repository's - * (the_repository) git directory. - */ -__attribute__((format (printf, 1, 2))) -static inline const char *git_path(const char *fmt, ...) -{ - struct strbuf *pathname = get_pathname(); - va_list args; - va_start(args, fmt); - repo_git_pathv(the_repository, NULL, pathname, fmt, args); - va_end(args); - return pathname->buf; -} - #define GIT_PATH_FUNC(func, filename) \ const char *func(void) \ { \ static char *ret; \ if (!ret) \ - ret = git_pathdup(filename); \ + ret = repo_git_path(the_repository, filename); \ return ret; \ } -/* - * Return a path into the main repository's (the_repository) git directory. - */ -__attribute__((format (printf, 1, 2))) -static inline char *git_pathdup(const char *fmt, ...) -{ - struct strbuf path = STRBUF_INIT; - va_list args; - va_start(args, fmt); - repo_git_pathv(the_repository, NULL, &path, fmt, args); - va_end(args); - return strbuf_detach(&path, NULL); -} - # endif /* USE_THE_REPOSITORY_VARIABLE */ #endif /* PATH_H */ diff --git a/pathspec.c b/pathspec.c index 0fc6f84a6e6298..89663645e13dd4 100644 --- a/pathspec.c +++ b/pathspec.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" diff --git a/perl/FromCPAN/Mail/meson.build b/perl/FromCPAN/Mail/meson.build new file mode 100644 index 00000000000000..b4ff2fc0b24c95 --- /dev/null +++ b/perl/FromCPAN/Mail/meson.build @@ -0,0 +1,8 @@ +test_dependencies += custom_target( + input: 'Address.pm', + output: 'Address.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/FromCPAN/Mail', + depends: [git_version_file], +) diff --git a/perl/FromCPAN/meson.build b/perl/FromCPAN/meson.build new file mode 100644 index 00000000000000..1f9ea6ce8e8442 --- /dev/null +++ b/perl/FromCPAN/meson.build @@ -0,0 +1,10 @@ +test_dependencies += custom_target( + input: 'Error.pm', + output: 'Error.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/FromCPAN', + depends: [git_version_file], +) + +subdir('Mail') diff --git a/perl/Git.pm b/perl/Git.pm index 667152c6c6de6e..6f47d653abe522 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.008001; +require v5.26; 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 5454c3a6d2c433..162230af817722 100644 --- a/perl/Git/I18N.pm +++ b/perl/Git/I18N.pm @@ -1,5 +1,5 @@ package Git::I18N; -use 5.008001; +require v5.26; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); BEGIN { @@ -20,14 +20,14 @@ our @EXPORT_OK = @EXPORT; # this "'@@' [...] '@@'" pattern. use constant NO_GETTEXT_STR => '@@' . 'NO_GETTEXT' . '@@'; use constant NO_GETTEXT => ( - q[@@NO_GETTEXT@@] ne '' + q[@NO_GETTEXT@] ne '' and - q[@@NO_GETTEXT@@] ne NO_GETTEXT_STR + q[@NO_GETTEXT@] ne NO_GETTEXT_STR ); sub __bootstrap_locale_messages { our $TEXTDOMAIN = 'git'; - our $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@'; + our $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '@LOCALEDIR@'; die "NO_GETTEXT=" . NO_GETTEXT_STR if NO_GETTEXT; require POSIX; @@ -111,7 +111,7 @@ L<Locale::Messages>'s ngettext function or passthrough fallback function. =head2 N__($) No-operation that only returns its argument. Use this if you want xgettext to -extract the text to the pot template but do not want to trigger retrival of the +extract the text to the pot template but do not want to trigger retrieval of the translation at run time. =head1 AUTHOR diff --git a/perl/Git/LoadCPAN.pm b/perl/Git/LoadCPAN.pm index 8c7fa805f97390..92d63c71d24b65 100644 --- a/perl/Git/LoadCPAN.pm +++ b/perl/Git/LoadCPAN.pm @@ -1,5 +1,5 @@ package Git::LoadCPAN; -use 5.008001; +require v5.26; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); @@ -31,11 +31,11 @@ C<git.git> repository. Use it for anything else at your peril! # Makefile, and allows for detecting whether the module is loaded from # perl/Git as opposed to perl/build/Git, which is useful for one-off # testing without having Error.pm et al installed. -use constant NO_PERL_CPAN_FALLBACKS_STR => '@@' . 'NO_PERL_CPAN_FALLBACKS' . '@@'; +use constant NO_PERL_CPAN_FALLBACKS_STR => '@' . 'NO_PERL_CPAN_FALLBACKS' . '@'; use constant NO_PERL_CPAN_FALLBACKS => ( - q[@@NO_PERL_CPAN_FALLBACKS@@] ne '' + q[@NO_PERL_CPAN_FALLBACKS@] ne '' and - q[@@NO_PERL_CPAN_FALLBACKS@@] ne NO_PERL_CPAN_FALLBACKS_STR + q[@NO_PERL_CPAN_FALLBACKS@] ne NO_PERL_CPAN_FALLBACKS_STR ); sub import { diff --git a/perl/Git/LoadCPAN/Mail/meson.build b/perl/Git/LoadCPAN/Mail/meson.build new file mode 100644 index 00000000000000..89cde56be84912 --- /dev/null +++ b/perl/Git/LoadCPAN/Mail/meson.build @@ -0,0 +1,8 @@ +test_dependencies += custom_target( + input: 'Address.pm', + output: 'Address.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git/LoadCPAN/Mail', + depends: [git_version_file], +) diff --git a/perl/Git/LoadCPAN/meson.build b/perl/Git/LoadCPAN/meson.build new file mode 100644 index 00000000000000..1ee915c650517d --- /dev/null +++ b/perl/Git/LoadCPAN/meson.build @@ -0,0 +1,10 @@ +test_dependencies += custom_target( + input: 'Error.pm', + output: 'Error.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git/LoadCPAN', + depends: [git_version_file], +) + +subdir('Mail') diff --git a/perl/Git/Packet.pm b/perl/Git/Packet.pm index d896e6952399b0..00fd9c484a1eb8 100644 --- a/perl/Git/Packet.pm +++ b/perl/Git/Packet.pm @@ -1,5 +1,5 @@ package Git::Packet; -use 5.008001; +require v5.26; use strict; use warnings $ENV{GIT_PERL_FATAL_WARNINGS} ? qw(FATAL all) : (); BEGIN { diff --git a/perl/Git/SVN/Memoize/meson.build b/perl/Git/SVN/Memoize/meson.build new file mode 100644 index 00000000000000..233ec670d7de91 --- /dev/null +++ b/perl/Git/SVN/Memoize/meson.build @@ -0,0 +1,8 @@ +test_dependencies += custom_target( + input: 'YAML.pm', + output: 'YAML.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git/SVN', + depends: [git_version_file], +) diff --git a/perl/Git/SVN/meson.build b/perl/Git/SVN/meson.build new file mode 100644 index 00000000000000..44abaf42b7cea3 --- /dev/null +++ b/perl/Git/SVN/meson.build @@ -0,0 +1,21 @@ +foreach source : [ + 'Editor.pm', + 'Fetcher.pm', + 'GlobSpec.pm', + 'Log.pm', + 'Migration.pm', + 'Prompt.pm', + 'Ra.pm', + 'Utils.pm', +] + test_dependencies += custom_target( + input: source, + output: source, + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git/SVN', + depends: [git_version_file], + ) +endforeach + +subdir('Memoize') diff --git a/perl/Git/meson.build b/perl/Git/meson.build new file mode 100644 index 00000000000000..b21fa5591e7e79 --- /dev/null +++ b/perl/Git/meson.build @@ -0,0 +1,19 @@ +foreach source : [ + 'I18N.pm', + 'IndexInfo.pm', + 'LoadCPAN.pm', + 'Packet.pm', + 'SVN.pm', +] + test_dependencies += custom_target( + input: source, + output: source, + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git', + depends: [git_version_file], + ) +endforeach + +subdir('LoadCPAN') +subdir('SVN') diff --git a/perl/header_templates/fixed_prefix.template.pl b/perl/header_templates/fixed_prefix.template.pl index 857b4391a49939..d571ca5cde513a 100644 --- a/perl/header_templates/fixed_prefix.template.pl +++ b/perl/header_templates/fixed_prefix.template.pl @@ -1 +1 @@ -use lib (split(/@@PATHSEP@@/, $ENV{GITPERLLIB} || '@@INSTLIBDIR@@')); +use lib (split(/@PATHSEP@/, $ENV{GITPERLLIB} || '@INSTLIBDIR@')); diff --git a/perl/header_templates/runtime_prefix.template.pl b/perl/header_templates/runtime_prefix.template.pl index 9d28b3d8636c6c..e6f8e661a16451 100644 --- a/perl/header_templates/runtime_prefix.template.pl +++ b/perl/header_templates/runtime_prefix.template.pl @@ -3,7 +3,7 @@ # This finds our Git::* libraries relative to the script's runtime path. sub __git_system_path { my ($relpath) = @_; - my $gitexecdir_relative = '@@GITEXECDIR_REL@@'; + my $gitexecdir_relative = '@GITEXECDIR_REL@'; # GIT_EXEC_PATH is supplied by `git` or the test suite. my $exec_path; @@ -24,11 +24,11 @@ sub __git_system_path { } BEGIN { - use lib split /@@PATHSEP@@/, + use lib split /@PATHSEP@/, ( $ENV{GITPERLLIB} || do { - my $perllibdir = __git_system_path('@@PERLLIBDIR_REL@@'); + my $perllibdir = __git_system_path('@PERLLIBDIR_REL@'); (-e $perllibdir) || die("Invalid system path ($relpath): $path"); $perllibdir; } @@ -36,7 +36,7 @@ BEGIN # Export the system locale directory to the I18N module. The locale directory # is only installed if NO_GETTEXT is set. - $Git::I18N::TEXTDOMAINDIR = __git_system_path('@@LOCALEDIR_REL@@'); + $Git::I18N::TEXTDOMAINDIR = __git_system_path('@LOCALEDIR_REL@'); } # END RUNTIME_PREFIX generated code. diff --git a/perl/meson.build b/perl/meson.build new file mode 100644 index 00000000000000..2d4ab1c4a986f7 --- /dev/null +++ b/perl/meson.build @@ -0,0 +1,13 @@ +test_dependencies += custom_target( + input: 'Git.pm', + output: 'Git.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5', + depends: [git_version_file], +) + +subdir('Git') +if get_option('perl_cpan_fallback') + subdir('FromCPAN') +endif diff --git a/pkt-line.c b/pkt-line.c index 24479eae4dbe2a..a5bcbc96fb340f 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -39,7 +39,6 @@ static int packet_trace_pack(const char *buf, unsigned int len, int sideband) static void packet_trace(const char *buf, unsigned int len, int write) { - int i; struct strbuf out; static int in_pack, sideband; @@ -72,7 +71,7 @@ static void packet_trace(const char *buf, unsigned int len, int write) get_trace_prefix(), write ? '>' : '<'); /* XXX we should really handle printable utf8 */ - for (i = 0; i < len; i++) { + for (unsigned int i = 0; i < len; i++) { /* suppress newlines */ if (buf[i] == '\n') continue; @@ -338,30 +337,32 @@ int write_packetized_from_buf_no_flush_count(const char *src_in, size_t len, } static int get_packet_data(int fd, char **src_buf, size_t *src_size, - void *dst, unsigned size, int options) + void *dst, size_t size, int options) { - ssize_t ret; + size_t bytes_read; if (fd >= 0 && src_buf && *src_buf) BUG("multiple sources given to packet_read"); /* Read up to "size" bytes from our source, whatever it is. */ if (src_buf && *src_buf) { - ret = size < *src_size ? size : *src_size; - memcpy(dst, *src_buf, ret); - *src_buf += ret; - *src_size -= ret; + bytes_read = size < *src_size ? size : *src_size; + memcpy(dst, *src_buf, bytes_read); + *src_buf += bytes_read; + *src_size -= bytes_read; } else { - ret = read_in_full(fd, dst, size); + ssize_t ret = read_in_full(fd, dst, size); if (ret < 0) { if (options & PACKET_READ_GENTLE_ON_READ_ERROR) return error_errno(_("read error")); die_errno(_("read error")); } + + bytes_read = (size_t) ret; } /* And complain if we didn't get enough bytes to satisfy the read. */ - if (ret != size) { + if (bytes_read != size) { if (options & PACKET_READ_GENTLE_ON_EOF) return -1; @@ -370,7 +371,7 @@ static int get_packet_data(int fd, char **src_buf, size_t *src_size, die(_("the remote end hung up unexpectedly")); } - return ret; + return 0; } int packet_length(const char lenbuf_hex[4], size_t size) diff --git a/po/TEAMS b/po/TEAMS index 2775a971aa7a45..9a6a15cd9a1661 100644 --- a/po/TEAMS +++ b/po/TEAMS @@ -7,8 +7,8 @@ Leader: Alexander Shopov <ash@kambanaria.org> Language: ca (Catalan) Repository: https://github.com/Softcatala/git-po -Leader: Jordi Mas <jmas@softcatala.org> -Members: Alex Henrie <alexhenrie24@gmail.com> +Leader: Mikel Forcada <mikel.forcada@gmail.com> +Members: Jordi Mas <jmas@softcatala.org> Language: de (German) Repository: https://github.com/ralfth/git diff --git a/po/bg.po b/po/bg.po index 9e1ae613cf66dd..37d127faac7169 100644 --- a/po/bg.po +++ b/po/bg.po @@ -1,7 +1,7 @@ # Bulgarian translation of git po-file. -# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024 Alexander Shopov <ash@kambanaria.org>. +# Copyright (C) 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025 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, 2024. +# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025. # ======================== # DICTIONARY TO MERGE IN GIT GUI # ------------------------ @@ -222,7 +222,18 @@ # reftable таблица с указатели # its referent '%s' сочещия го „%s“ # dry run пробно изпълнение -# +# mailmap файл за съответствията на имената и адресите на е-поща +# unit test поединичен тест +# test suite група тестове +# object database базата от данни за обектите +# expecting integer изисква се число +# timeout максимално изчакване +# init timeout максимално първоначално изчакване +# implies option включва опцията +# cache-tree кеша на обектите-дървета +# acquire lock придобивам ключалка +# detached отделѐн, несвързан +# revision walk обхождане на версиите # # ------------------------ # „$var“ - може да не сработва за shell има gettext и eval_gettext - проверка - намират се лесно по „$ @@ -249,10 +260,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.45\n" +"Project-Id-Version: git 2.48\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-20 07:37+0200\n" -"PO-Revision-Date: 2024-07-21 22:27+0300\n" +"POT-Creation-Date: 2025-03-05 22:57+0000\n" +"PO-Revision-Date: 2025-03-06 09:15+0100\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -562,8 +573,8 @@ msgstr "" #, c-format msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? " msgstr "" -"Премахване на промяната в права̀та за достъп от работното дърво [y,n,q,a," -"d%s,?]? " +"Премахване на промяната в права̀та за достъп от работното дърво " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? " @@ -603,8 +614,8 @@ msgstr "" #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Премахване на промяната в права̀та за достъп от индекса и работното дърво [y," -"n,q,a,d%s,?]? " +"Премахване на промяната в права̀та за достъп от индекса и работното дърво " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? " @@ -639,8 +650,8 @@ msgstr "" #, c-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Прилагане на промяната в права̀та за достъп от индекса и работното дърво [y,n," -"q,a,d%s,?]? " +"Прилагане на промяната в права̀та за достъп от индекса и работното дърво " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " @@ -674,8 +685,8 @@ msgstr "" #, c-format msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? " msgstr "" -"Прилагане на промяната в права̀та за достъп към работното дърво [y,n,q,a," -"d%s,?]? " +"Прилагане на промяната в права̀та за достъп към работното дърво " +"[y,n,q,a,d%s,?]? " #, c-format msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? " @@ -808,7 +819,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j — без решение за парчето, към следващото парче без решение\n" @@ -820,6 +831,7 @@ msgstr "" "s — разделяне на текущото парче на по-малки\n" "e — ръчно редактиране на текущото парче\n" "p — извеждане на текущото парче\n" +"P — извеждане на текущото парче през програма за прелистване\n" "? — извеждане на помощта\n" #, c-format @@ -890,12 +902,12 @@ msgstr "Променени са само двоични файлове." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" "За да изключите това предупреждение, изпълнете:\n" "\n" -" git config advice.%s false" +" git config set advice.%s false" #, c-format msgid "%shint:%s%.*s%s\n" @@ -1013,8 +1025,8 @@ msgstr "" "\n" " git switch -\n" "\n" -"Може да спрете това съобщение със задаване на настройката „advice." -"detachedHead“\n" +"Може да спрете това съобщение със задаване на настройката " +"„advice.detachedHead“\n" "да е „false“ (лъжа̀).\n" #, c-format @@ -1244,7 +1256,7 @@ msgstr "двоичната кръпка не може да се приложи #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" -"двоичната кръпка за „%s“ води до неправилни резултати (очакваше се: „%s“, а " +"двоичната кръпка за „%s“ води до неправилни резултати (изисква се: „%s“, а " "бе получено: „%s“)" #, c-format @@ -1516,6 +1528,15 @@ msgstr "" "пробване с тройно сливане, ако това не сработи — стандартно прилагане на " "кръпка" +msgid "for conflicts, use our version" +msgstr "при конфликти да се ползва локалната версия" + +msgid "for conflicts, use their version" +msgstr "при конфликти да се ползва чуждата версия" + +msgid "for conflicts, use a union version" +msgstr "при конфликти да се ползва обединена версия" + msgid "build a temporary index based on embedded index information" msgstr "" "създаване на временен индекс на база на включената информация за индекса" @@ -1563,6 +1584,9 @@ msgstr "добавяне на тази НАЧАЛНА_ДИРЕКТОРИЯ къ msgid "don't return error for empty patches" msgstr "да не се връща грешка при празни кръпки" +msgid "--ours, --theirs, and --union require --3way" +msgstr "опциите „--ours“, „--theirs“ и „--union“ изискват опцията „--3way“" + #, c-format msgid "cannot stream blob %s" msgstr "обектът-BLOB „%s“ не може да се обработи" @@ -1634,6 +1658,10 @@ msgstr "неправилно име на обект: „%s“" msgid "not a tree object: %s" msgstr "не е обект-дърво: %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "неуспешно разпакетиране на обект-дърво „%s“" + #, c-format msgid "File not found: %s" msgstr "Файлът „%s“ липсва" @@ -2628,13 +2656,25 @@ msgstr "git archive: протоколна грешка" msgid "git archive: expected a flush" msgstr "git archive: очакваше се изчистване на буферите чрез „flush“" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=БРОЙ] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "проблем при зареждане на частично хранилище" + +msgid "Minimum number of objects to request at a time" +msgstr "Минимален БРОЙ обекти заявявани наведнъж" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Ограничаване на липсващите обекти до текущото частично хранилище" + msgid "" "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) [ВЕРСИЯ…]" @@ -2771,9 +2811,6 @@ msgstr "" "на „git bisect terms“ е подаден неправилен аргумент „%s“\n" "Поддържат се опциите „--term-good“/„--term-old“ и „--term-bad„/„--term-new“." -msgid "revision walk setup failed\n" -msgstr "неуспешно настройване на обхождането на версиите\n" - #, c-format msgid "could not open '%s' for appending" msgstr "файлът „%s“ не може да се отвори за добавяне" @@ -2920,7 +2957,7 @@ msgstr "ОПЦИИте_ЗА_ВЕРСИЯТА са документирани в #, c-format msgid "expecting a color: %s" -msgstr "трябва да е цвят: %s" +msgstr "изисква се цвят: %s" msgid "must end with a color" msgstr "трябва да завършва с цвят" @@ -3333,8 +3370,8 @@ msgid "HEAD not found below refs/heads!" msgstr "В директорията „refs/heads“ липсва файл „HEAD“" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" "може да се ползва клон с опцията „--recurse-submodules“, само ако " "настройката „submodule.propagateBranches“ е зададена" @@ -3410,10 +3447,6 @@ msgstr "" msgid "git version:\n" msgstr "версия на git:\n" -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "грешка при изпълнението на „uname()“ — „%s“ (%d)\n" - msgid "compiler info: " msgstr "компилатор: " @@ -3637,8 +3670,8 @@ msgstr "позволяване на опциите „-s“ и „-t“ да р msgid "use mail map file" msgstr "" -"използване на файл за съответствията на имената и адресите на е-поща („." -"mailmap“)" +"използване на файл за съответствията на имената и адресите на е-поща " +"(„.mailmap“)" msgid "Batch objects requested on stdin (or --batch-all-objects)" msgstr "" @@ -3789,9 +3822,17 @@ msgstr "git check-mailmap [ОПЦИЯ…] КОНТАКТ…" msgid "also read contacts from stdin" msgstr "четене на контакти и от стандартния вход" -#, c-format -msgid "unable to parse contact: %s" -msgstr "контактът не може да бъде анализиран: %s" +msgid "read additional mailmap entries from file" +msgstr "" +"изчитане на допълнителните съответствия на имена и адреси на е-поща от ФАЙЛ" + +msgid "blob" +msgstr "обект-BLOB" + +msgid "read additional mailmap entries from blob" +msgstr "" +"изчитане на допълнителните съответствия на имена и адреси на е-поща от обект-" +"BLOB" msgid "no contacts specified" msgstr "не са указани контакти" @@ -4145,6 +4186,10 @@ msgstr "задаването на път е несъвместимо с прем msgid "'%s' cannot be used with switching branches" msgstr "опцията „%s“ е несъвместима с преминаването от един клон към друг" +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "„%s“ изисква пътища, които да се изтеглят" + #, c-format msgid "'%s' cannot be used with '%s'" msgstr "опцията „%s“ е несъвместима с „%s“" @@ -4178,7 +4223,7 @@ msgstr "" "„zdiff3“)" msgid "detach HEAD at named commit" -msgstr "отделяне на указателя „HEAD“ към указаното подаване" +msgstr "отделяне на указателя „HEAD“ при указаното подаване" msgid "force checkout (throw away local modifications)" msgstr "принудително изтегляне (вашите промѐни ще бъдат занулени)" @@ -4192,8 +4237,8 @@ msgstr "нов неродѐн клон" msgid "update ignored files (default)" msgstr "обновяване на игнорираните файлове (стандартно)" -msgid "do not check if another worktree is holding the given ref" -msgstr "без проверка дали друго работно дърво държи указателя" +msgid "do not check if another worktree is using this branch" +msgstr "без проверка дали друго работно дърво ползва този клон" msgid "checkout our version for unmerged files" msgstr "изтегляне на вашата версия на неслетите файлове" @@ -4426,10 +4471,102 @@ msgid "remove only ignored files" msgstr "изтриване само на игнорирани файлове" msgid "clean.requireForce is true and -f not given: refusing to clean" -msgstr "Настройката „clean.requireForce“ е зададена, което изисква опцията „-f“. Няма да се извърши изчистване" +msgstr "" +"Настройката „clean.requireForce“ е зададена, което изисква опцията „-f“. " +"Няма да се извърши изчистване" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "" +"ПРЕДУПРЕЖДЕНИЕ: не може да се добави алтернативен източник на „%s“: %s\n" + +#, c-format +msgid "failed to stat '%s'" +msgstr "не може да бъде получена информация чрез „stat“ за „%s“" + +#, c-format +msgid "%s exists and is not a directory" +msgstr "„%s“ съществува и не е директория" + +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "„%s“ е символна връзка, не може да се клонира с опцията „--local“" + +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "неуспешно итериране по „%s“" + +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "" +"символната връзка „%s“ съществува, не може да се клонира с опцията „--local“" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "неуспешно изтриване на „%s“" + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "твърдата връзка не може да се провери при „%s“" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "твърдата връзка е различна от източника „%s“" + +#, c-format +msgid "failed to create link '%s'" +msgstr "връзката „%s“ не може да бъде създадена" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "файлът не може да бъде копиран като „%s“" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "неуспешно итериране по „%s“" + +#, c-format +msgid "done.\n" +msgstr "действието завърши.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Клонирането бе успешно за разлика от подготовката на работното дърво\n" +"за определен клон. Все пак може да проверите кои файлове и от кой\n" +"клон в момента са изтеглени с командата „git status“. Може да\n" +"завършите изтеглянето на клона с командата:\n" +"\n" +" git restore --source=HEAD :/\n" + +msgid "remote did not send all necessary objects" +msgstr "отдалеченото хранилище не изпрати всички необходими обекти." + +#, c-format +msgid "unable to update %s" +msgstr "обектът „%s“ не може да бъде обновен" + +msgid "failed to initialize sparse-checkout" +msgstr "частичното изтегляне не може да се инициализира" + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "" +"указателят „HEAD“ от отдалеченото хранилище сочи към нещо, което не " +"съществува. Изтегляне не може да се извърши" + +msgid "unable to checkout working tree" +msgstr "работното дърво не може да бъде подготвено" + +msgid "unable to write parameters to config file" +msgstr "настройките не може да бъдат записани в конфигурационния файл" + +msgid "cannot repack to clean up" +msgstr "не може да се извърши пакетиране за изчистване на файловете" + +msgid "cannot unlink temporary alternates file" +msgstr "временният файл за алтернативни обекти не може да бъде изтрит" msgid "don't clone shallow repository" msgstr "без клониране на плитко хранилище" @@ -4483,6 +4620,9 @@ msgstr "използване на това ИМЕ вместо „origin“ пр msgid "checkout <branch> instead of the remote's HEAD" msgstr "изтегляне на този КЛОН, а не соченият от отдалечения указател „HEAD“" +msgid "clone single revision <rev> and check out" +msgstr "клониране на единствена ВЕРСИЯ и изтегляне в работната директория" + msgid "path to git-upload-pack on the remote" msgstr "път към командата „git-upload-pack“ на отдалеченото хранилище" @@ -4495,10 +4635,10 @@ msgstr "плитко клониране до тази ДЪЛБОЧИНА" msgid "create a shallow clone since a specific time" msgstr "плитко клониране до момент във времето" -msgid "revision" -msgstr "ВЕРСИЯ" +msgid "ref" +msgstr "УКАЗ" -msgid "deepen history of shallow clone, excluding rev" +msgid "deepen history of shallow clone, excluding ref" msgstr "задълбочаване на историята на плитко хранилище до изключващ указател" msgid "clone only one branch, HEAD or --branch" @@ -4506,9 +4646,8 @@ msgstr "" "клониране само на един клон — или сочения от отдалечения „HEAD“, или изрично " "зададения с „--branch“" -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "" -"без клониране на етикети, като последващите доставяния няма да ги следят" +msgid "clone tags, and make later fetches not to follow them" +msgstr "клониране на етикети, като последващите доставяния няма да ги следят" msgid "any cloned submodules will be shallow" msgstr "всички клонирани подмодули ще са плитки" @@ -4552,104 +4691,8 @@ msgid "a URI for downloading bundles before fetching from origin remote" msgstr "" "АДРЕС за доставяне на пратки на git преди доставяне от отдалеченото хранилище" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "" -"ПРЕДУПРЕЖДЕНИЕ: не може да се добави алтернативен източник на „%s“: %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "не може да бъде получена информация чрез „stat“ за „%s“" - -#, c-format -msgid "%s exists and is not a directory" -msgstr "„%s“ съществува и не е директория" - -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "„%s“ е символна връзка, не може да се клонира с опцията „--local“" - -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "неуспешно итериране по „%s“" - -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "" -"символната връзка „%s“ съществува, не може да се клонира с опцията „--local“" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "неуспешно изтриване на „%s“" - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "твърдата връзка не може да се провери при „%s“" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "твърдата връзка е различна от източника „%s“" - -#, c-format -msgid "failed to create link '%s'" -msgstr "връзката „%s“ не може да бъде създадена" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "файлът не може да бъде копиран като „%s“" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "неуспешно итериране по „%s“" - -#, c-format -msgid "done.\n" -msgstr "действието завърши.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Клонирането бе успешно за разлика от подготовката на работното дърво\n" -"за определен клон. Все пак може да проверите кои файлове и от кой\n" -"клон в момента са изтеглени с командата „git status“. Може да\n" -"завършите изтеглянето на клона с командата:\n" -"\n" -" git restore --source=HEAD :/\n" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "" -"Клонът „%s“ от отдалеченото хранилище, което клонирате,\n" -"и който следва да бъде изтеглен, не съществува." - -msgid "remote did not send all necessary objects" -msgstr "отдалеченото хранилище не изпрати всички необходими обекти." - -#, c-format -msgid "unable to update %s" -msgstr "обектът „%s“ не може да бъде обновен" - -msgid "failed to initialize sparse-checkout" -msgstr "частичното изтегляне не може да се инициализира" - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "" -"указателят „HEAD“ от отдалеченото хранилище сочи към нещо, което не " -"съществува. Изтегляне не може да се извърши" - -msgid "unable to checkout working tree" -msgstr "работното дърво не може да бъде подготвено" - -msgid "unable to write parameters to config file" -msgstr "настройките не може да бъдат записани в конфигурационния файл" - -msgid "cannot repack to clean up" -msgstr "не може да се извърши пакетиране за изчистване на файловете" - -msgid "cannot unlink temporary alternates file" -msgstr "временният файл за алтернативни обекти не може да бъде изтрит" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]" msgid "Too many arguments." msgstr "Прекалено много аргументи." @@ -4758,6 +4801,10 @@ msgstr "отдалеченият транспорт върна грешка" msgid "Remote branch %s not found in upstream %s" msgstr "Отдалеченият клон „%s“ липсва в клонираното хранилище „%s“" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "Отдалечената версия „%s“ липсва в клонираното хранилище „%s“" + msgid "You appear to have cloned an empty repository." msgstr "Изглежда клонирахте празно хранилище." @@ -4937,9 +4984,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree: не може да се прочете" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4947,13 +4994,13 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a|--interactive|--patch] [-s] [-v] [-u РЕЖИМ] [--amend]\n" +"git commit [-a|--interactive|--patch] [-s] [-v] [-u[РЕЖИМ]] [--amend]\n" " [--dry-run] [(-c|-C|--squash) ПОДАВАНЕ |--fixup [(amend|" -"reword):]ПОДАВАНЕ)]\n" +"reword):]ПОДАВАНЕ]\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" " [--] [ПЪТ…]" @@ -5465,11 +5512,10 @@ msgstr "git config list [ОПЦИЯ_ЗА_ФАЙЛ] [ОПЦИЯ_ЗА_ИЗВЕЖД msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" "git config get [ОПЦИЯ_ЗА_ФАЙЛ] [ОПЦИЯ_ЗА_ИЗВЕЖДАНЕ] [--includes] [--all] [--" -"regexp=РЕГ_ИЗР][--value=СТОЙНОСТ] [--fixed-value] [--default=СТАНДАРТНО] ИМЕ" +"regexp] [--value=СТОЙНОСТ] [--fixed-value] [--default=СТАНДАРТНО] ИМЕ" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5480,9 +5526,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" -"git config unset [ОПЦИЯ_ЗА_ФАЙЛ] [--all] [--value=СТОЙНОСТ] [--fixed-value]" +"git config unset [ОПЦИЯ_ЗА_ФАЙЛ] [--all] [--value=СТОЙНОСТ] [--fixed-value] " +"ИМЕ" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [ОПЦИЯ_ЗА_ФАЙЛ] СТАРО_ИМЕ НОВО_ИМЕ" @@ -5497,6 +5544,14 @@ msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "" "git config [ОПЦИЯ_ЗА_ФАЙЛ] --get-colorbool ИМЕ [СТАНД_ИЗХОД_НА_ТЕРМИНАЛ]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [ОПЦИЯ_ЗА_ФАЙЛ] [ОПЦИЯ_ЗА_ИЗВЕЖДАНЕ] [--includes] [--all] [--" +"regexp=РЕГ_ИЗР][--value=СТОЙНОСТ] [--fixed-value] [--default=СТАНДАРТНО] ИМЕ" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5926,12 +5981,8 @@ msgid "traversed %lu commits\n" msgstr "обходени са %lu подавания\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"открити са над %i етикета, изведени са последните %i,\n" -"търсенето бе прекратено при „%s“.\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "открити са %i етикета. Търсенето приключи при „%s“\n" #, c-format msgid "describe %s\n" @@ -6326,8 +6377,8 @@ msgstr "" " git config fetch.showForcedUpdates false\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "хранилището „%s“ не изпрати всички необходими обекти\n" +msgid "%s did not send all necessary objects" +msgstr "хранилището „%s“ не изпрати всички необходими обекти" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -6366,8 +6417,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "стойността „%2$s“ за опцията „%1$s“ не е съвместима с „%3$s“" #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "опцията „%s“ се прескача при „%s“\n" +msgid "option \"%s\" is ignored for %s" +msgstr "опцията „%s“ се прескача при „%s“" #, c-format msgid "%s is not a valid object" @@ -6377,6 +6428,27 @@ msgstr "„%s“ е неправилен обект" msgid "the object %s does not exist" msgstr "обектът „%s“ не съществува" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Изпълнете\n" +"\n" +" git remote set-head %s %s\n" +"\n" +"за да следвате промяната или задайте друга стойност на настройката\n" +"„remote.%s.followRemoteHEAD, ако не искате тези съобщения.\n" +"Изпълнението на\n" +"\n" +" git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s\n" +"\n" +"ще изключи предупреждението, докато отдалеченият указател HEAD не\n" +"започне да сочи нещо друго." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "" "засечени са множество клони, това е несъвместимо с опцията „--set-upstream“" @@ -6516,6 +6588,9 @@ msgstr "КАРТА_С_УКАЗАТЕЛИ" msgid "specify fetch refmap" msgstr "указване на КАРТАта_С_УКАЗАТЕЛИ за доставяне" +msgid "revision" +msgstr "ВЕРСИЯ" + msgid "report that we have only objects reachable from this object" msgstr "докладване, че всички обекти може са достижими при започване от този" @@ -6571,8 +6646,8 @@ msgid "protocol does not support --negotiate-only, exiting" msgstr "протоколът не поддържа опцията „--negotiate-only“, изход от програмата" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" "опцията „--filter“ може да се ползва само с отдалеченото хранилище указано в " "настройката „extensions.partialclone“" @@ -6672,7 +6747,8 @@ msgid "config key storing a list of repository paths" msgstr "настройка, която съдържа списък с пътища към хранилища" msgid "keep going even if command fails in a repository" -msgstr "продължаване на действието дори и командата да е неуспешна в някое хранилище" +msgstr "" +"продължаване на действието дори и командата да е неуспешна в някое хранилище" msgid "missing --config=<config>" msgstr "липсва --config=НАСТРОЙКА" @@ -6821,7 +6897,7 @@ msgstr "„%s“ сочи към нещо необичайно (%s)" #, c-format msgid "%s: detached HEAD points at nothing" -msgstr "%s: несвързаният връх „HEAD“ не сочи към нищо" +msgstr "%s: отделеният връх „HEAD“ не сочи към нищо" #, c-format msgid "notice: %s points to an unborn branch (%s)" @@ -7046,6 +7122,9 @@ msgstr "изчерпателно търсене на боклука (за сме msgid "enable auto-gc mode" msgstr "включване на автоматичното събиране на боклука (auto-gc)" +msgid "perform garbage collection in the background" +msgstr "събиране на боклука във фонов режим" + msgid "force running gc even if there may be another gc running" msgstr "" "изрично стартиране на събирането на боклука, дори и ако вече работи друго " @@ -7054,6 +7133,9 @@ msgstr "" msgid "repack all other packs except the largest pack" msgstr "препакетиране на всичко без най-големия пакет" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "префикс на имената на пакетите за окастрени обекти" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "неразпозната стойност на „gc.logExpiry“ %s" @@ -7128,8 +7210,8 @@ msgstr "неуспешно изпълнение на „git multi-pack-index rep msgid "" "skipping incremental-repack task because core.multiPackIndex is disabled" msgstr "" -"задачата „incremental-repack“ се прескача, защото настройката „core." -"multiPackIndex“ е изключена" +"задачата „incremental-repack“ се прескача, защото настройката " +"„core.multiPackIndex“ е изключена" #, c-format msgid "lock file '%s' exists, skipping maintenance" @@ -7150,6 +7232,9 @@ msgstr "задачата „%s“ не може да се избере пове msgid "run tasks based on the state of the repository" msgstr "изпълняване на задачи според състоянието на хранилището" +msgid "perform maintenance in the background" +msgstr "извършване на дейностите по поддръжка на заден фон" + msgid "frequency" msgstr "честота" @@ -7247,8 +7332,25 @@ msgstr "липсват както таймери на systemd, така и cront msgid "%s scheduler is not available" msgstr "планиращият модул „%s“ липсва" -msgid "another process is scheduling background maintenance" -msgstr "друг процес задава поддръжката на заден фон" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"Файлът-ключалка „%s.lock“ не може да бъде създаден: %s\n" +"\n" +"Изглежда, че и друг процес на git-maintenance(1) е пуснат в това\n" +"хранилище. Уверете се, че всички подобни процеси са спрени и опитайте\n" +"отново. Ако това не помогне, вероятната причина е, че някой процес на\n" +"git-maintenance(1) в това хранилище е забил. За да продължите работа,\n" +"ще трябва ръчно да изтриете файла:" + +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "не може да се придобие ключалката за поддръжката на заден фон" msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=ПЛАНИРАЩ_МОДУЛ]" @@ -7832,9 +7934,31 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "дължината на веригата е %d: %lu обект" msgstr[1] "дължината на веригата е %d: %lu обекта" +msgid "could not start pack-objects to repack local links" +msgstr "" +"командата „pack-objects“ не може да се стартира за препакетирането на " +"локалните връзки" + +msgid "failed to feed local object to pack-objects" +msgstr "локалните обекти не може да се подадат на командата „pack-objects“" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: от „pack-objects“ се изискват редове само с пълни шестнайсетични " +"указатели." + +msgid "could not finish pack-objects to repack local links" +msgstr "" +"командата „pack-objects“ не може да завърши за препакетирането на локалните " +"връзки" + msgid "Cannot come back to cwd" msgstr "Процесът не може да се върне към предишната работна директория" +#, c-format +msgid "bad --pack_header: %s" +msgstr "неправилна стойност за „--pack_header“: „%s“" + #, c-format msgid "bad %s" msgstr "неправилна стойност „%s“" @@ -7843,6 +7967,9 @@ msgstr "неправилна стойност „%s“" msgid "unknown hash algorithm '%s'" msgstr "непознат алгоритъм за контролни суми „%s“" +msgid "--promisor cannot be used with a pack name" +msgstr "опцията „--promisor“ е несъвместима с име на пакет" + msgid "--stdin requires a git repository" msgstr "„--stdin“ изисква хранилище на git" @@ -8029,9 +8156,6 @@ msgstr "опцията „-LДИАПАЗОН:ФАЙЛ“ не може да се msgid "Final output: %d %s\n" msgstr "Резултат: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "не може да бъде създадена директория за временни обекти" - #, c-format msgid "git show %s: bad file" msgstr "git show %s: повреден файл" @@ -8622,15 +8746,6 @@ msgstr "сливане на базата на „diff3“" msgid "use a zealous diff3 based merge" msgstr "засилено сливане на базата на „diff3“" -msgid "for conflicts, use our version" -msgstr "при конфликти да се ползва локалната версия" - -msgid "for conflicts, use their version" -msgstr "при конфликти да се ползва чуждата версия" - -msgid "for conflicts, use a union version" -msgstr "при конфликти да се ползва обединена версия" - msgid "<algorithm>" msgstr "АЛГОРИТЪМ" @@ -8736,10 +8851,6 @@ msgstr "непозната опция за стратегия: -X%s" msgid "malformed input line: '%s'." msgstr "входен ред с неправилен формат: „%s“." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "сливането не може да продължи — %d-тото завърши с грешка" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [ОПЦИЯ…] [ПОДАВАНЕ…]" @@ -9110,6 +9221,9 @@ msgstr "" msgid "write multi-pack bitmap" msgstr "запазване на многопакетната битова маска" +msgid "write a new incremental MIDX" +msgstr "запазване на нов файл с нарастващ индекс за множество пакети" + msgid "write multi-pack index containing only given indexes" msgstr "" "запазване на битовата маска за множество пакети, съдържаща само дадените " @@ -9248,11 +9362,14 @@ msgstr "git notes [--ref УКАЗАТЕЛ_ЗА_БЕЛЕЖКА] [list [ОБЕКТ msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" +"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" +"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " +"| -C) <object>] [<object>] [-e]\n" "git notes [--ref УКАЗАТЕЛ_ЗА_БЕЛЕЖКА] add [-f] [--allow-empty] [--" "[no-]separator|--separator=<paragraph-break>] [--[no-]stripspace] [-m " -"СЪОБЩЕНИЕ|-F ФАЙЛ|(-c|-C) ОБЕКТ] [ОБЕКТ]" +"СЪОБЩЕНИЕ|-F ФАЙЛ|(-c|-C) ОБЕКТ] [ОБЕКТ] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" @@ -9261,11 +9378,11 @@ msgstr "" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref УКАЗАТЕЛ_ЗА_БЕЛЕЖКА] append [--allow-empty] [--" "[no-]separator|--separator=КРАЙ_НА_АБЗАЦ] [--[no-]stripspace] [-m СЪОБЩЕНИЕ " -"| -F ФАЙЛ|(-c|-C) ОБЕКТ] [ОБЕКТ]" +"| -F ФАЙЛ|(-c|-C) ОБЕКТ] [ОБЕКТ] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref УКАЗАТЕЛ_ЗА_БЕЛЕЖКА] edit [--allow-empty] [ОБЕКТ]" @@ -9387,6 +9504,9 @@ msgstr "ФАЙЛ със съдържанието на бележката" msgid "reuse and edit specified note object" msgstr "преизползване и редактиране на указания ОБЕКТ-бележка" +msgid "edit note message in editor" +msgstr "редактиране на съобщението в редактора" + msgid "reuse specified note object" msgstr "преизползване на указания ОБЕКТ-бележка" @@ -9576,6 +9696,13 @@ msgstr "" "git pack-objects [ОПЦИЯ…] ПРЕФИКС_НА_ИМЕТО [< СПИСЪК_С_УКАЗАТЕЛИ|< " "СПИСЪК_С_ОБЕКТИ]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "неправилна опция „--name-hash-version“: %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "текущо опцията „--write-bitmap-index“ изисква „--name-hash-version=1“" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9625,7 +9752,7 @@ msgstr "неуспешно записване на индекси на база #, c-format msgid "wrote %<PRIu32> objects while expecting %<PRIu32>" -msgstr "бяха записани %<PRIu32> обекти, а се очакваха %<PRIu32>" +msgstr "бяха записани %<PRIu32> обекти, а се изискват %<PRIu32>" msgid "disabling bitmap writing, as some objects are not being packed" msgstr "" @@ -9905,6 +10032,9 @@ msgstr "как да се обработват липсващите обекти" msgid "do not pack objects in promisor packfiles" msgstr "без пакетиране на обекти в гарантиращи пакети" +msgid "implies --missing=allow-any" +msgstr "включва опцията „--missing=allow-any“" + msgid "respect islands during delta compression" msgstr "без промяна на групите при делта компресия" @@ -9914,6 +10044,11 @@ msgstr "протокол" msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "без ползване на настройки „uploadpack.blobpackfileuri“ с този протокол" +msgid "use the specified name-hash function to group similar objects" +msgstr "" +"използване на указаната функция за контролни суми за групиране на подобните " +"обекти" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "веригата с разлики е прекалено дълбока — %d, ще се ползва %d" @@ -10280,7 +10415,7 @@ msgid "" " git push %s HEAD:<name-of-remote-branch>\n" msgstr "" "В момента не сте на никой клон. За да изтласкате историята до състоянието,\n" -"сочено в момента от указателя „HEAD“, използвайте командата:\n" +"сочено в момента от (несвързания) указател „HEAD“, използвайте командата:\n" "\n" " git push %s HEAD:ИМЕ_НА_ОТДАЛЕЧЕНИЯ_КЛОН\n" @@ -11193,8 +11328,11 @@ msgstr "не е указан журнал с подавания за изтри msgid "invalid ref format: %s" msgstr "неправилен формат на указател: %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=ФОРМАТ [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=ФОРМАТ [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "указване на форма̀та за указател, към който да се конвертира" @@ -11202,6 +11340,9 @@ msgstr "указване на форма̀та за указател, към к msgid "perform a non-destructive dry-run" msgstr "пробно изпълнение — без промяна на данни" +msgid "drop reflogs entirely during the migration" +msgstr "журналът на указателите да се изтрие изцяло по време на миграцията" + msgid "missing --ref-format=<format>" msgstr "липсва опцията --ref-format=ФОРМАТ" @@ -11209,6 +11350,12 @@ msgstr "липсва опцията --ref-format=ФОРМАТ" msgid "repository already uses '%s' format" msgstr "хранилището вече ползва форма̀та „%s“" +msgid "enable strict checking" +msgstr "строги проверки" + +msgid "'git refs verify' takes no arguments" +msgstr "командата „git refs verify“ не приема аргументи" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -11548,6 +11695,30 @@ msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Локалният указател, настроен за „git push“%s:" msgstr[1] " Локалните указатели, настроени за „git push“%s:" +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "„%s/HEAD“ не е променен и сочи към „%s“\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "„%s/HEAD“ е променен от „%s“ и сега сочи към „%s“\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "„%s/HEAD“ е създаден и сочи към „%s“\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "„%s/HEAD“ е отделѐн при „%s“ и сочи към „%s“\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"„%s/HEAD“ сочеше към „%s“ (което не е отдалечен клон), но сега сочи към " +"„%s“\n" + msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "задаване на refs/remotes/ИМЕ/HEAD според отдалеченото хранилище" @@ -11570,7 +11741,7 @@ msgid "Not a valid ref: %s" msgstr "Неправилен указател: %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "„%s“ не може да се настрои" #, c-format @@ -11642,8 +11813,14 @@ msgstr "Никой от адресите, които не са за изтлас msgid "be verbose; must be placed before a subcommand" msgstr "повече подробности. Поставя се пред подкоманда" -msgid "git repack [<options>]" -msgstr "git repack [ОПЦИЯ…]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=БРОЙ] [--depth=БРОЙ] [--threads=БРОЙ] [--keep-pack=ИМЕ_НА_ПАКЕТ]\n" +"[--write-midx] [--name-hash-version=БРОЙ]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11731,6 +11908,11 @@ msgid "pass --no-reuse-object to git-pack-objects" msgstr "" "подаване на опцията „--no-reuse-object“ на командата „git-pack-objects“" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"укажете функция за контролни суми за групиране на подобните обекти по път" + msgid "do not run git-update-server-info" msgstr "без изпълнение на командата „git-update-server-info“" @@ -11783,9 +11965,6 @@ msgstr "откриване на геометрична прогресия с ч msgid "write a multi-pack index of the resulting packs" msgstr "запазване на многопакетен индекс за създадените пакети" -msgid "pack prefix to store a pack containing pruned objects" -msgstr "префикс на имената на пакетите за окастрени обекти" - msgid "pack prefix to store a pack containing filtered out objects" msgstr "префикс на имената на пакетите за филтрирани обекти" @@ -12002,9 +12181,6 @@ 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 "всички зададени положителни версии трябва да са указатели" @@ -12243,8 +12419,8 @@ msgstr "" " или: git rev-parse --sq-quote [АРГУМЕНТ…]\n" " или: git rev-parse [ОПЦИЯ…] [АРГУМЕНТ…]\n" "\n" -"За повече информация за първия вариант изпълнете „git rev-parse --parseopt -" -"h“" +"За повече информация за първия вариант изпълнете „git rev-parse --parseopt " +"-h“" msgid "--resolve-git-dir requires an argument" msgstr "опцията „--resolve-git-dir“ изисква аргумент" @@ -12668,10 +12844,10 @@ msgstr "указателят не съществува" msgid "failed to look up reference" msgstr "соченото от указателя липсва" -msgid "only show tags (can be combined with branches)" +msgid "only show tags (can be combined with --branches)" msgstr "извеждане на етикетите (може да се комбинира с „--branches“ за клони)" -msgid "only show branches (can be combined with tags)" +msgid "only show branches (can be combined with --tags)" msgstr "извеждане на клоните (може да се комбинира с „--tags“ за етикети)" msgid "check for reference existence without resolving" @@ -12727,6 +12903,10 @@ msgstr "директорията „%s“ не може да бъде изтри msgid "failed to create directory for sparse-checkout file" msgstr "директорията за частично изтегляне „%s“ не може да бъде създадена" +#, c-format +msgid "unable to fdopen %s" +msgstr "обектът „%s“ не може да бъде отворен с „fdopen“" + msgid "failed to initialize worktree config" msgstr "настройките на работното дърво не може да се инициализират" @@ -13071,7 +13251,7 @@ msgstr "добавяне на „# “ в началото на всеки ре #, c-format msgid "Expecting a full ref name, got %s" -msgstr "Очаква се пълно име на указател, а не „%s“" +msgstr "Изисква се пълно име на указател, а не „%s“" #, c-format msgid "could not get a repository handle for submodule '%s'" @@ -13185,8 +13365,8 @@ msgid "couldn't hash object from '%s'" msgstr "неуспешно изчисляване на контролната сума на обект от „%s“" #, c-format -msgid "unexpected mode %o\n" -msgstr "неочакван режим „%o“\n" +msgid "unexpected mode %o" +msgstr "неочакван режим „%o“" msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "" @@ -13498,7 +13678,8 @@ msgid "don't print cloning progress" msgstr "без извеждане на напредъка на клонирането" msgid "disallow cloning into non-empty directory, implies --init" -msgstr "предотвратяване на клониране в непразна история, включва „--init“" +msgstr "" +"предотвратяване на клониране в непразна история, включва опцията „--init“" msgid "" "git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] " @@ -14355,6 +14536,9 @@ msgstr "задаване на режима на следене (виж git-branc msgid "try to match the new branch name with a remote-tracking branch" msgstr "опит за напасване на името на новия клон с това на следящ клон" +msgid "use relative paths for worktrees" +msgstr "използване на относителни пътища за работните дървета" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "опциите „%s“, „%s“ и „%s“ са несъвместими" @@ -14636,6 +14820,26 @@ msgstr "файлът „%s“ не може да бъде създаден" msgid "index-pack died" msgstr "командата „git index-pack“ не завърши успешно" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "директорията „%s“ е в индекса, но не е частична" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "повреденият кеш на обектите-дървета съдържа записи извън индекса" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "„%s“ с флагове 0x%x не трябва да е в кеша на обектите-дървета" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "неправилно поддърво „%.*s“" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "" +"кешираният обект-дърво за пътя „%.*s“ не съвпада. Изисква се „%s“, а не „%s“" + msgid "terminating chunk id appears earlier than expected" msgstr "идентификаторът за краен откъс се явява по-рано от очакваното" @@ -14680,6 +14884,9 @@ msgstr "Внасяне на хранилище на GNU Arch в Git" msgid "Create an archive of files from a named tree" msgstr "Създаване на архив с файловете от именовано дърво" +msgid "Download missing objects in a partial clone" +msgstr "Изтегляне на липсващите обекти в частично хранилище" + msgid "Use binary search to find the commit that introduced a bug" msgstr "Двоично търсене на промяната, която е причинила грешка" @@ -15420,7 +15627,7 @@ msgstr "временният файл на гра̀фа с подаваният #, c-format msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits" msgstr "" -"не може да се слеят графове с %<PRIuMAX> и %<PRIuMAX> подавания (съответно)" +"не може да се слеят гра̀фи с %<PRIuMAX> и %<PRIuMAX> подавания (съответно)" #, c-format msgid "cannot merge graph %s, too many commits: %<PRIuMAX>" @@ -15442,8 +15649,8 @@ msgid "" "attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " "(%d) is not supported" msgstr "" -"опит за запис на гра̀фа с подаванията, но настройката „commitGraph." -"changedPathsVersion“ (%d) не се поддържа" +"опит за запис на гра̀фа с подаванията, но настройката " +"„commitGraph.changedPathsVersion“ (%d) не се поддържа" msgid "too many commits to write graph" msgstr "прекалено много подавания за записване на гра̀фа" @@ -15530,7 +15737,7 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "Поддръжката на „<GIT_DIR>/info/grafts“ е остаряла.\n" "В бъдеща версия на Git ще бъде премахната.\n" @@ -15542,7 +15749,7 @@ msgstr "" "\n" "За да изключите това съобщение, изпълнете:\n" "\n" -" git config advice.graftFileDeprecated false" +" git config set advice.graftFileDeprecated false" #, c-format msgid "commit %s exists in commit-graph but not in the object database" @@ -16397,6 +16604,24 @@ msgstr "адресът е без схема: %s" msgid "credential url cannot be parsed: %s" msgstr "адресът за идентификация не може да се анализира: „%s“" +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "" +"неправилна стойност за „timeout“ (максимално изчакване) „%s“, изисква се " +"неотрицателно цяло число" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "" +"неправилна стойност за „init-timeout“ (максимално първоначално изчакване): " +"„%s“, изисква се неотрицателно цяло число" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "" +"неправилна стойност за „max-connections“ (максималния брой връзки): „%s“, " +"изисква се цяло число" + msgid "in the future" msgstr "в бъдещето" @@ -16662,6 +16887,12 @@ msgstr "неправилен аргумент към „%s“" msgid "invalid regex given to -I: '%s'" msgstr "неправилен регулярен израз подаден към „-I“: „%s“" +msgid "-G requires a non-empty argument" +msgstr "опцията „-G“ изисква аргумент" + +msgid "-S requires a non-empty argument" +msgstr "опцията „-S“ изисква аргумент" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "неразпознат параметър към опцията „--submodule“: „%s“" @@ -17122,6 +17353,22 @@ msgstr "неправилен път към пространства от име msgid "too many args to run %s" msgstr "прекалено много аргументи за изпълнение „%s“" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Пробвате да доставите „%s“, което е в гра̀фа с подаванията, но не и в базата " +"от данни за обектите.\n" +"Най-вероятната причина е повредено хранилище.\n" +"За да поправите хранилището като изтеглите липсващия обект наново, " +"изпълнете:\n" +"\n" +" git fetch --refetch" + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: очаква се плитък списък" @@ -17722,11 +17969,12 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" "Куката „%s“ се прескача, защото липсват права̀ за изпълнение.\n" "За да изключите това предупреждение, изпълнете:\n" -" git config advice.ignoredHook false" +"\n" +" git config set advice.ignoredHook false" msgid "not a git repository" msgstr "не е хранилище на Git" @@ -17743,15 +17991,9 @@ msgstr "" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Управлението на делегирането не се поддържа от cURL < 7.22.0" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "Задаването на постоянен публичен ключ не се поддържа от cURL < 7.39.0" - msgid "Unknown value for http.proactiveauth" msgstr "Непозната стойност за „http.proactiveauth“" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "„CURLSSLOPT_NO_REVOKE“ не се поддържа от cURL < 7.44.0" - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "Неподдържана реализация на SSL „%s“. Поддържат се:" @@ -17918,13 +18160,16 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "Файлът-ключалка „%s.lock“ не може да бъде създаден: %s" +msgid "unable to create temporary object directory" +msgstr "не може да бъде създадена директория за временни обекти" + #, c-format msgid "could not write loose object index %s" msgstr "индексът с непакетирани обекти не може да се запише: %s" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "грешка при записа на индекса с непакетирани обекти %s\n" +msgid "failed to write loose object index %s" +msgstr "грешка при записа на индекса с непакетирани обекти „%s“" #, c-format msgid "unexpected line: '%s'" @@ -17940,6 +18185,10 @@ msgstr "цитирани знаци CRLF" msgid "unable to format message: %s" msgstr "съобщението не може да се форматира: %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "неправилен размер на маркер: „%s“, изисква се цяло число" + #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Неуспешно сливане на подмодула „%s“ (не е изтеглен)" @@ -18486,6 +18735,18 @@ msgstr "пакетът не може да се зареди" msgid "could not open index for %s" msgstr "индексът за „%s“ не може да се отвори" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "не може да се създаде връзка „%s“, която да сочи към „%s“" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "индексът за множество пакети не може да бъде изчистен при „%s“" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "" +"нарастващият индекс за множество пакети с битова маска не може да се запише" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "" "индексът за множество пакети се прескача, защото сумата за проверка не " @@ -18518,11 +18779,25 @@ msgid "refusing to write multi-pack .bitmap without any objects" msgstr "" "многопакетната битова маска без никакви обекти не може да бъде запазена" +msgid "unable to create temporary MIDX layer" +msgstr "не може да се създаде временен слой за индекса за множество пакети" + msgid "could not write multi-pack bitmap" msgstr "многопакетната битова маска не може да бъде запазена" +msgid "unable to open multi-pack-index chain file" +msgstr "файлът с веригата на гра̀фа с подаванията не може да се отвори" + +msgid "unable to rename new multi-pack-index layer" +msgstr "слой в индекса за множество пакети не може да се преименува" + msgid "could not write multi-pack-index" -msgstr "индексът за множество пакети не може да бъде запазен" +msgstr "индексът за множество пакети не може да се запази" + +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "" +"пакети за нарастващия индекс за множество пакети не може да се обявят за " +"остарели" msgid "Counting referenced objects" msgstr "Преброяване на свързаните обекти" @@ -18530,6 +18805,9 @@ msgstr "Преброяване на свързаните обекти" msgid "Finding and deleting unreferenced packfiles" msgstr "Търсене и изтриване на несвързаните пакетни файлове" +msgid "cannot repack an incremental multi-pack-index" +msgstr "нарастващият индекс за множество пакети не може да се препакетира" + msgid "could not start pack-objects" msgstr "командата „pack-objects“ не може да бъде стартирана" @@ -18598,6 +18876,35 @@ msgstr "" "неправилна подредба на имената в индекс за множество пакети: „%s“ се появи " "преди „%s“" +msgid "multi-pack-index chain file too small" +msgstr "файлът с веригата за индекса за множество пакети е твърде малък" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "" +"броят подавания в основния индекс за множество пакети е прекалено голям: " +"%<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "" +"броят обекти в основния индекс за множество пакети е прекалено голям: " +"%<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "" +"грешка във веригата на индекса за множество пакети: ред „%s“ не е контролна " +"сума" + +msgid "unable to find all multi-pack index files" +msgstr "някои файлове на индекса за множество пакети не може да бъдат открити" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "" +"неправилна позиция на обект в индекса за множество пакети. Вероятно " +"индексът е повреден" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "" @@ -18620,10 +18927,6 @@ msgid "multi-pack-index large offset out of bounds" msgstr "" "стойността на отместването в индекса за множество пакети е извън диапазона" -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "индексът за множество пакети не може да бъде изчистен при „%s“" - msgid "multi-pack-index file exists, but failed to parse" msgstr "" "файлът с индекса за множество пакети съществува, но не може да бъде " @@ -18848,10 +19151,22 @@ msgstr "пакетираният обект „%s“ (в „%s“) е повре msgid "missing mapping of %s to %s" msgstr "липсва съответствие на „%s“ към „%s“" +#, c-format +msgid "unable to open %s" +msgstr "обектът „%s“ не може да бъде отворен" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "съдържанието на файловете „%s“ и „%s“ е различно" + #, c-format msgid "unable to write file %s" msgstr "файлът „%s“ не може да бъде записан" +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "смаляващият се файл „%s“ не може да бъде записван" + #, c-format msgid "unable to set permission to '%s'" msgstr "права̀та за достъп до „%s“ не може да бъдат зададени" @@ -18933,10 +19248,6 @@ msgstr "неподдържан вид файл: „%s“" msgid "%s is not a valid '%s' object" msgstr "„%s“ е неправилен обект от вид „%s“" -#, c-format -msgid "unable to open %s" -msgstr "обектът „%s“ не може да бъде отворен" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "неправилна контролна сума за „%s“ (трябва да е %s)" @@ -19038,7 +19349,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "При нормална работа Git никога не създава указатели, които завършват\n" "с 40 шестнадесетични знака, защото стандартно те ще бъдат прескачани.\n" @@ -19050,7 +19361,7 @@ msgstr "" "се създава подобен указател. Прегледайте тези указатели и ги изтрийте.\n" "За да изключите това съобщение, изпълнете:\n" "\n" -" git config advice.objectNameWarning false" +" config set advice.objectNameWarning false" #, c-format msgid "log for '%.*s' only goes back to %s" @@ -19221,15 +19532,6 @@ 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“ е неправилен" - msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "" "повредена таблица със съответствия: местоположението на тройката е извън " @@ -19465,6 +19767,52 @@ msgstr "непознат флаг „%c“" msgid "unknown non-ascii option in string: `%s'" msgstr "непозната стойност извън „ascii“ в низа: „%s“" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=%s]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[%s]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " %s" + msgid "..." msgstr "…" @@ -19551,6 +19899,21 @@ msgstr "неправилна булева стойност „%s“ за „%s msgid "failed to parse %s" msgstr "„%s“ не може да бъде анализиран" +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "неуспешно обхождане на дъщерните елементи на дървото „%s“: то липсва" + +#, c-format +msgid "failed to find object %s" +msgstr "обектът „%s“ липсва" + +#, c-format +msgid "failed to find tag %s" +msgstr "етикетът „%s“ липсва" + +msgid "failed to setup revision walk" +msgstr "неуспешно настройване на обхождането на версиите" + #, c-format msgid "Could not make %s writable by group" msgstr "Не може да се дадат права̀ за запис в директорията „%s“ на групата" @@ -19700,6 +20063,22 @@ msgstr "" msgid "could not fetch %s from promisor remote" msgstr "„%s“ не може да се достави от гарантиращото хранилище" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "има хранилище с име „%s“, но адресът му сочи към „%s“, а не към „%s“" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "непозната стойност „%s“ за настройката „%s“" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "непознат елемент „%s“ в информацията за отдалеченото хранилище" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "липсва приетото вече хранилище-гарант „%s“" + msgid "object-info: expected flush after arguments" msgstr "object-info: след аргументите се очаква изчистване на буферите" @@ -20211,6 +20590,10 @@ msgstr "очаква се положителна широчина с лексе msgid "expected format: %%(ahead-behind:<committish>)" msgstr "очакван формат: %%(ahead-behind:ПОДАВАНЕ)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "очакван формат: %%(is-base:ПОДАВАНЕ)" + #, c-format msgid "malformed field name: %.*s" msgstr "неправилно име на обект: „%.*s“" @@ -20349,7 +20732,8 @@ msgid "" "\n" "\tgit branch -m <name>\n" msgstr "" -"Първоначалният клон ще се казва „%s“. Това може да се променѝ. Може да зададете\n" +"Първоначалният клон ще се казва „%s“. Това може да се променѝ. Може да " +"зададете\n" "настройката и да спрете това съобщение. За това изпълнете:\n" "\n" " git config --global init.defaultBranch ИМЕ\n" @@ -20383,19 +20767,27 @@ msgstr "журналът с подаванията за указателя „%s msgid "log for %s is empty" msgstr "журналът с подаванията за указателя „%s“ е празен" -msgid "refusing to force and skip creation of reflog" -msgstr "" -"принудителна операция без създаване на журнал на указателите няма да се " -"приеме" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "указател не може да се обнови с грешно име „%s“" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "журналът на указателите няма да се обнови с псевдо указателя „%s“" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "псевдо указателят „%s“ няма да се обнови" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "журналът на указателите няма да се обнови с грешно име „%s“" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "указател не може да се обнови с грешно име „%s“" + +msgid "refusing to force and skip creation of reflog" +msgstr "" +"принудителна операция без създаване на журнал на указателите няма да се " +"приеме" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "неуспешно обновяване на указателя (update_ref) „%s“: %s" @@ -20445,6 +20837,17 @@ msgstr "" "указателят „%s“ не може да се заключи: очакваше се файл с указател с цел " "„%s“, но вместо това е обикновен указател" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "файлът с указател „%s“ не може да се прочете" + +#, c-format +msgid "cannot open directory %s" +msgstr "директорията „%s“ не може да бъде отворена" + +msgid "Checking references consistency" +msgstr "Проверка на валидността на указателите" + #, c-format msgid "refname is dangerous: %s" msgstr "опасно име на указател: %s" @@ -20521,6 +20924,14 @@ msgstr "името на указател „%s“ е символен указа msgid "invalid refspec '%s'" msgstr "неправилен указател: „%s“" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "шаблонът „%s“ не съдържа „*“" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "заместителят „%s“ не съдържа „*“" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "" @@ -20648,6 +21059,28 @@ msgstr "remote-curl: опит за доставяне без локално хр msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: непозната команда „%s“ от git" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"изчитането на отдалеченото хранилище от „%s/%s“ предстои да бъде " +"премахнато.\n" +"Ако все още ползвате директорията „remotes/“, препоръчваме да я мигрирате\n" +"към следящи директории на база настройки чрез командата:\n" +"\n" +" git remote rename %s %s\n" +"\n" +"Ако не може поради някаква причина, молим да ни известите за нея с\n" +"е-писмо до пощенския списък: <git@vger.kernel.org>." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "" @@ -20659,6 +21092,10 @@ msgstr "зададен е повече от един пакет за получ msgid "more than one uploadpack given, using the first" msgstr "зададен е повече от един пакет за изпращане, ще се ползва първият" +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "непознатата стойност за „followRemoteHEAD“: „%s“, се прескача" + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "непозната стойност за „transfer.credentialsInUrl“: „%s“" @@ -20679,14 +21116,6 @@ msgstr "„%s“ обикновено следи „%s“, а не „%s“" msgid "%s tracks both %s and %s" msgstr "„%s“ следи както „%s“, така и „%s“" -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "ключ „%s“ на шаблона не съдържа „*“" - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "стойност „%s“ на шаблона не съдържа „*“" - #, c-format msgid "src refspec %s does not match any" msgstr "указателят на версия-източник „%s“ не съвпада с никой обект" @@ -20993,7 +21422,9 @@ msgstr "„%s“ съществува и не е символна връзка" msgid "" "--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, " "REVERT_HEAD or REBASE_HEAD" -msgstr "„--merge“ изисква някой от псевдо указателите „MERGE_HEAD“, „CHERRY_PICK_HEAD“, „REVERT_HEAD“ или „REBASE_HEAD“" +msgstr "" +"„--merge“ изисква някой от псевдо указателите „MERGE_HEAD“, " +"„CHERRY_PICK_HEAD“, „REVERT_HEAD“ или „REBASE_HEAD“" #, c-format msgid "could not get commit for --ancestry-path argument %s" @@ -21097,12 +21528,15 @@ msgstr "да се свалят метаданните само за изтегл msgid "create repository within 'src' directory" msgstr "създаване на хранилище в директория „src“" +msgid "specify if tags should be fetched during clone" +msgstr "указва дали етикетите да се доставят при клониране" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch ОСНОВЕН_КЛОН] [--full-clone]\n" -" [--[no-]src] АДРЕС [ЗАЧИСЛЕНА_ДИРЕКТОРИЯ]" +" [--[no-]src] [--[no-]tags] АДРЕС [ЗАЧИСЛЕНА_ДИРЕКТОРИЯ]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -21120,6 +21554,10 @@ msgstr "основният клон на „%s“ не може да бъде п msgid "could not configure remote in '%s'" msgstr "отдалеченото хранилище в „%s“ не може да се настрои" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "етикетите в „%s“ не може са се изключат" + #, c-format msgid "could not configure '%s'" msgstr "„%s“ не може да се настрои" @@ -22240,6 +22678,10 @@ msgstr "процесът не може да се върне към предиш msgid "failed to stat '%*s%s%s'" msgstr "не може да бъде получена информация чрез „stat“ за „%*s%s%s“" +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "пътят за безопасна директория (safe.directory) „%s“ не е абсолютен" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -22647,6 +23089,28 @@ msgstr "" "какъв брой записи в кеша на обектите-дървета да се отбележат като невалидни " "(стандартно е 0)" +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk ОПЦИЯ… -- ОПЦИЯ_ЗА_ВЕРСИИ…" + +msgid "toggle inclusion of blob objects" +msgstr "превключване на поместването на обекти-BLOB" + +msgid "toggle inclusion of commit objects" +msgstr "превключване на поместването на обекти-подавания" + +msgid "toggle inclusion of tag objects" +msgstr "превключване на поместването на обекти-етикети" + +msgid "toggle inclusion of tree objects" +msgstr "превключване на поместването на обекти-дърво" + +msgid "toggle pruning of uninteresting paths" +msgstr "" +"превключване на окастрянето на пътищата, които не представляват интерес" + +msgid "read a pattern list over stdin" +msgstr "изчитане на списък с шаблони от стандартния вход" + #, c-format msgid "commit %s is not marked reachable" msgstr "подаването „%s“ не е отбелязано като достижимо" @@ -22654,6 +23118,11 @@ msgstr "подаването „%s“ не е отбелязано като до msgid "too many commits marked reachable" msgstr "прекалено много подавания са отбелязани като достижими" +msgid "could not determine MIDX preferred pack" +msgstr "" +"предпочитаният пакет за файла с индекса за множество пакети не може да се " +"определи" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [ОПЦИЯ…]" @@ -22715,6 +23184,24 @@ msgstr "лексема" msgid "command token to send to the server" msgstr "командна лексема за пращане" +msgid "unit-test [<options>]" +msgstr "unit-test [ОПЦИЯ…]" + +msgid "immediately exit upon the first failed test" +msgstr "незабавен изход след първия неуспешен тест" + +msgid "suite[::test]" +msgstr "ГРУПА[::ТЕСТ]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "изпълнение на тази ГРУПА или конкретен тест с име ГРУПА::ТЕСТ" + +msgid "suite" +msgstr "ГРУПА" + +msgid "exclude test suite <suite>" +msgstr "прескачане на тази ГРУПА тестове" + #, c-format msgid "running trailer command '%s' failed" msgstr "неуспешно изпълнение на завършващата команда „%s“" @@ -22963,7 +23450,9 @@ msgid "bundle-uri operation not supported by protocol" msgstr "операцията „bundle-uri“ (адреси на пратки) не се поддържа от протокола" msgid "could not retrieve server-advertised bundle-uri list" -msgstr "списъкът с адреси на пратки обявени за налични от сървъра не може да се получи " +msgstr "" +"списъкът с адреси на пратки обявени за налични от сървъра не може да се " +"получи " msgid "operation not supported by protocol" msgstr "опцията не се поддържа от протокола" @@ -23258,6 +23747,10 @@ msgstr "грешка: " msgid "warning: " msgstr "предупреждение: " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "грешка при изпълнението на „uname()“ — „%s“ (%d)\n" + msgid "Fetching objects" msgstr "Доставяне на обектите" @@ -23290,6 +23783,9 @@ msgstr "„.git“ е повреден" msgid ".git file incorrect" msgstr "„.git“ е неправилен" +msgid ".git file absolute/relative path mismatch" +msgstr "несъвпадение на абсолютния/относителния път на „.git“" + msgid "not a valid path" msgstr "неправилен път" @@ -23305,6 +23801,9 @@ msgstr "не може да се открие хранилище: „.git“ е msgid "gitdir unreadable" msgstr "директорията „gitdir“ не може да се прочете" +msgid "gitdir absolute/relative path mismatch" +msgstr "„gitdir“ указва несъвпадение на абсолютния/относителния път" + msgid "gitdir incorrect" msgstr "неправилна директория „gitdir“" @@ -23341,6 +23840,14 @@ msgstr "„%s“ не може да се изчисти в „%s“" msgid "failed to set extensions.worktreeConfig setting" msgstr "неуспешно задаване на настройката „extensions.worktreeConfig“" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"форматът на хранилището не може да се обнови за поддръжката на относителни " +"работни дървета" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "неуспешно задаване на настройката „extensions.relativeWorktrees“" + #, c-format msgid "could not setenv '%s'" msgstr "променливата на средата „%s“ не може да се зададе чрез „setenv“" @@ -23915,6 +24422,9 @@ msgstr "„%s.final“ съдържа подготвеното е-писмо.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "опцията „--dump-aliases“ е несъвместима с другите опции\n" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "опциите „--dump-aliases“ и „--translate-aliases“ са несъвместими\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" diff --git a/po/ca.po b/po/ca.po index bcb4da80fb9afe..ace9b3ca460a68 100644 --- a/po/ca.po +++ b/po/ca.po @@ -77,186 +77,238 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\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" +"POT-Creation-Date: 2024-10-05 01:20+0000\n" +"PO-Revision-Date: 2024-10-05 09:03+0200\n" +"Last-Translator: Mikel Forcada <mikel.forcada@gmail.com>\n" "Language-Team: Catalan\n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.3.1\n" +"X-Generator: Poedit 3.2.2\n" +#: add-interactive.c #, c-format msgid "Huh (%s)?" msgstr "Perdó (%s)?" +#: add-interactive.c builtin/merge.c builtin/rebase.c reset.c sequencer.c msgid "could not read index" msgstr "no s'ha pogut llegir l'índex" +#: add-interactive.c msgid "binary" msgstr "binari" +#: add-interactive.c msgid "nothing" msgstr "res" +#: add-interactive.c msgid "unchanged" msgstr "sense canvis" +#: add-interactive.c msgid "Update" msgstr "Actualitza" +#: add-interactive.c #, c-format msgid "could not stage '%s'" msgstr "no s'ha pogut fer «stage» «%s»" +#: add-interactive.c builtin/stash.c reset.c sequencer.c msgid "could not write index" msgstr "no s'ha pogut escriure l'índex" +#: add-interactive.c #, c-format msgid "updated %d path\n" msgid_plural "updated %d paths\n" msgstr[0] "actualitzat %d camí\n" msgstr[1] "actualitzats %d camins\n" +#: add-interactive.c #, c-format msgid "note: %s is untracked now.\n" msgstr "nota: %s està ara sense seguiment.\n" +#: add-interactive.c apply.c builtin/checkout.c builtin/reset.c #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "make_cache_entry ha fallat per al camí «%s»" +#: add-interactive.c msgid "Revert" msgstr "Reverteix" +#: add-interactive.c msgid "Could not parse HEAD^{tree}" msgstr "No s'ha pogut analitzar HEAD^{tree}" +#: add-interactive.c #, c-format msgid "reverted %d path\n" msgid_plural "reverted %d paths\n" msgstr[0] "revertit %d camí\n" msgstr[1] "revertits %d camins\n" +#: add-interactive.c #, c-format msgid "No untracked files.\n" msgstr "Sense fitxers no seguits.\n" +#: add-interactive.c msgid "Add untracked" msgstr "Afegeix sense seguiment" +#: add-interactive.c #, c-format msgid "added %d path\n" msgid_plural "added %d paths\n" msgstr[0] "afegit %d camí\n" msgstr[1] "afegits %d camins\n" +#: add-interactive.c #, c-format msgid "ignoring unmerged: %s" msgstr "s'està ignorant allò no fusionat: %s" +#: add-interactive.c #, c-format msgid "Only binary files changed.\n" msgstr "Només han canviat fitxers binaris.\n" +#: add-interactive.c #, c-format msgid "No changes.\n" msgstr "Sense canvis.\n" +#: add-interactive.c msgid "Patch update" msgstr "Actualització del pedaç" +#: add-interactive.c msgid "Review diff" msgstr "Reviseu les diferències" +#: add-interactive.c msgid "show paths with changes" msgstr "mostra els camins amb canvis" +#: add-interactive.c msgid "add working tree state to the staged set of changes" msgstr "afegeix l'estat de l'arbre de treball al conjunt de canvis «staged»" +#: add-interactive.c msgid "revert staged set of changes back to the HEAD version" msgstr "reverteix el conjunt de canvis «staged» a la versió HEAD" +#: add-interactive.c msgid "pick hunks and update selectively" msgstr "selecciona els trossos i actualitza selectivament" +#: add-interactive.c msgid "view diff between HEAD and index" msgstr "visualitza les diferències entre HEAD i l'índex" +#: add-interactive.c msgid "add contents of untracked files to the staged set of changes" msgstr "afegeix contingut de fitxers no seguits al conjunt de canvis «staged»" +#: add-interactive.c msgid "Prompt help:" msgstr "Mostra ajuda:" +#: add-interactive.c msgid "select a single item" msgstr "seleccioneu un únic ítem" +#: add-interactive.c msgid "select a range of items" msgstr "seleccioneu un rang d'ítems" +#: add-interactive.c msgid "select multiple ranges" msgstr "seleccioneu rangs múltiples" +#: add-interactive.c msgid "select item based on unique prefix" msgstr "seleccioneu un ítem basant-se en un prefix únic" +#: add-interactive.c msgid "unselect specified items" msgstr "desselecciona els ítems especificats" +#: add-interactive.c msgid "choose all items" msgstr "trieu tots els ítems" +#: add-interactive.c msgid "(empty) finish selecting" msgstr "(buit) finalitza la selecció" +#: add-interactive.c msgid "select a numbered item" msgstr "seleccioneu un ítem numerat" +#: add-interactive.c msgid "(empty) select nothing" msgstr "(buit) no seleccionis res" +#: add-interactive.c builtin/clean.c msgid "*** Commands ***" msgstr "*** Ordres ***" +#: add-interactive.c builtin/clean.c msgid "What now" msgstr "I ara què" +#: add-interactive.c msgid "staged" msgstr "staged" +#: add-interactive.c msgid "unstaged" msgstr "unstaged" +#: add-interactive.c apply.c builtin/am.c builtin/bugreport.c builtin/clone.c +#: builtin/diagnose.c builtin/fetch.c builtin/hook.c builtin/merge.c +#: builtin/pull.c builtin/submodule--helper.c msgid "path" msgstr "camí" +#: add-interactive.c msgid "could not refresh index" msgstr "no s'ha pogut actualitzar l'índex" +#: add-interactive.c builtin/clean.c #, c-format msgid "Bye.\n" msgstr "Adeu.\n" +#: add-patch.c #, c-format msgid "Stage mode change [y,n,q,a,d%s,?]? " msgstr "Canvia el mode de «stage» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Stage deletion [y,n,q,a,d%s,?]? " msgstr "Suprimeix «stage» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Stage addition [y,n,q,a,d%s,?]? " msgstr "Afegeix a «stage» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Stage this hunk [y,n,q,a,d%s,?]? " msgstr "Fer un «stage» d'aquest tros [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "staging." @@ -264,6 +316,7 @@ msgstr "" "Si el pedaç s'aplica netament, el tros editat es marcarà immediatament per a " "«staging»." +#: add-patch.c msgid "" "y - stage this hunk\n" "n - do not stage this hunk\n" @@ -275,24 +328,30 @@ msgstr "" "n - no facis «stage» d'aquest tros\n" "q - surt; no facis «stage» d'aquest tros ni de cap altre restant\n" "a - fes «stage» d'aquest tros i de tota la resta de trossos del fitxer\n" -"d - no facis «stage» d'aquest tros ni de cap altre restant del fitxer\n" +"d - no facis «stage» d'aquest tros ni de cap altre tros posterior del " +"fitxer\n" +#: add-patch.c #, c-format msgid "Stash mode change [y,n,q,a,d%s,?]? " msgstr "Canvia el mode de «stash» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Stash deletion [y,n,q,a,d%s,?]? " msgstr "Suprimeix «stash» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Stash addition [y,n,q,a,d%s,?]? " msgstr "Afegeix a «stash» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Stash this hunk [y,n,q,a,d%s,?]? " msgstr "Fer un «stash» d'aquest tros [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "stashing." @@ -300,6 +359,7 @@ msgstr "" "Si el pedaç s'aplica de forma neta, el tros editat es marcarà immediatament " "per a «stashing»." +#: add-patch.c msgid "" "y - stash this hunk\n" "n - do not stash this hunk\n" @@ -311,24 +371,30 @@ msgstr "" "n - no facis «stash» d'aquest tros\n" "q - surt; no facis «stash» d'aquest tros ni de cap altre restant\n" "a - fes «stash» d'aquest tros i de tota la resta de trossos del fitxer\n" -"d - no facis «stash» d'aquest tros ni de cap altre restant del fitxer\n" +"d - no facis «stash» d'aquest tros ni de cap altre tros posterior del " +"fitxer\n" +#: add-patch.c #, c-format msgid "Unstage mode change [y,n,q,a,d%s,?]? " msgstr "Canvia el mode de «unstage» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Unstage deletion [y,n,q,a,d%s,?]? " msgstr "Suprimeix «Unstage» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Unstage addition [y,n,q,a,d%s,?]? " msgstr "Afegeix a «unstage» [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Unstage this hunk [y,n,q,a,d%s,?]? " msgstr "Fer un «unstage» d'aquest tros [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "unstaging." @@ -336,6 +402,7 @@ msgstr "" "Si el pedaç s'aplica netament, el tros editat es marcarà immediatament per a " "«unstaging»." +#: add-patch.c msgid "" "y - unstage this hunk\n" "n - do not unstage this hunk\n" @@ -349,22 +416,27 @@ msgstr "" "a - fes «unstage» d'aquest tros i de tota la resta de trossos del fitxer\n" "d - no facis «unstage» d'aquest tros ni de cap altre restant del fitxer\n" +#: add-patch.c #, c-format msgid "Apply mode change to index [y,n,q,a,d%s,?]? " msgstr "Aplica el canvi de mode a l'índex [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply deletion to index [y,n,q,a,d%s,?]? " msgstr "Aplica la supressió a l'índex [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply addition to index [y,n,q,a,d%s,?]? " msgstr "Aplica l'addició a l'índex [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply this hunk to index [y,n,q,a,d%s,?]? " msgstr "Aplica aquest tros a l'índex [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "applying." @@ -372,6 +444,7 @@ msgstr "" "Si el pedaç s'aplica netament, el tros editat es marcarà immediatament per a " "aplicar-lo." +#: add-patch.c msgid "" "y - apply this hunk to index\n" "n - do not apply this hunk to index\n" @@ -385,22 +458,27 @@ msgstr "" "a - aplica aquest tros i tots els trossos posteriors en el fitxer\n" "d - no apliquis aquest tros ni cap dels trossos posteriors en el fitxer\n" +#: add-patch.c #, c-format msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? " msgstr "Descarta el canvi de mode de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? " msgstr "Descarta suprimir de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Discard addition from worktree [y,n,q,a,d%s,?]? " msgstr "Descarta l'addició de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? " msgstr "Descarta aquest tros de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "discarding." @@ -408,6 +486,7 @@ msgstr "" "Si el pedaç s'aplica netament, el tros editat es marcarà immediatament per a " "ser descartat." +#: add-patch.c msgid "" "y - discard this hunk from worktree\n" "n - do not discard this hunk from worktree\n" @@ -421,26 +500,31 @@ msgstr "" "a - descarta aquest tros i tots els trossos posteriors en el fitxer\n" "d - no descartis aquest tros ni cap dels trossos posteriors en el fitxer\n" +#: add-patch.c #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " msgstr "" "Descarta el canvi de mode de l'índex i de l'arbre de treball [y,n,q,a," "d%s,?]? " +#: add-patch.c #, c-format msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? " msgstr "Descarta suprimir de l'índex i de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Discard addition from index and worktree [y,n,q,a,d%s,?]? " msgstr "" "Descarta l'addició de l'índex i de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? " msgstr "" "Descarta aquest tros de l'índex i de l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "y - discard this hunk from index and worktree\n" "n - do not discard this hunk from index and worktree\n" @@ -454,23 +538,28 @@ msgstr "" "a - descarta aquest tros i tots els trossos posteriors en el fitxer\n" "d - no descartis aquest tros ni cap dels trossos posteriors en el fitxer\n" +#: add-patch.c #, c-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " msgstr "" "Aplica el canvi de mode a l'índex i a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " msgstr "Aplica la supressió a l'índex i a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? " msgstr "Aplica l'addició a l'índex i a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? " msgstr "Aplica aquest tros a l'índex i a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "y - apply this hunk to index and worktree\n" "n - do not apply this hunk to index and worktree\n" @@ -484,22 +573,27 @@ msgstr "" "a - aplica aquest tros i tots els trossos posteriors en el fitxer\n" "d - no apliquis aquest tros ni cap dels trossos posteriors en el fitxer\n" +#: add-patch.c #, c-format msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? " msgstr "Aplica el canvi de mode a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? " msgstr "Aplica la supressió a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply addition to worktree [y,n,q,a,d%s,?]? " msgstr "Aplica l'addició a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c #, c-format msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? " msgstr "Aplica aquest tros a l'arbre de treball [y,n,q,a,d%s,?]? " +#: add-patch.c msgid "" "y - apply this hunk to worktree\n" "n - do not apply this hunk to worktree\n" @@ -513,23 +607,29 @@ msgstr "" "a - aplica aquest tros i tots els trossos posteriors en el fitxer\n" "d - no apliquis aquest tros ni cap dels trossos posteriors en el fitxer\n" +#: add-patch.c #, c-format msgid "could not parse hunk header '%.*s'" msgstr "no s'ha pogut analitzar la capçalera del tros «%.*s»" +#: add-patch.c msgid "could not parse diff" msgstr "no s'ha pogut analitzar el diff" +#: add-patch.c msgid "could not parse colored diff" msgstr "no s'ha pogut analitzar el diff acolorit" +#: add-patch.c #, c-format msgid "failed to run '%s'" msgstr "no s'ha pogut executar «%s»" +#: add-patch.c msgid "mismatched output from interactive.diffFilter" msgstr "sortida no coincident des d'interactive.diffFilter" +#: add-patch.c msgid "" "Your filter must maintain a one-to-one correspondence\n" "between its input and output lines." @@ -537,6 +637,7 @@ msgstr "" "El filtre ha de mantenir una correspondència d'un a un\n" "entre les línies d'entrada i sortida." +#: add-patch.c #, c-format msgid "" "expected context line #%d in\n" @@ -545,6 +646,7 @@ msgstr "" "s'esperava la línia amb contingut #%d a\n" "%.*s" +#: add-patch.c #, c-format msgid "" "hunks do not overlap:\n" @@ -557,22 +659,25 @@ msgstr "" "\tno acaben amb:\n" "%.*s" +#: add-patch.c msgid "Manual hunk edit mode -- see bottom for a quick guide.\n" msgstr "" "Mode d'edició de trossos manual - vegeu més avall per a una guia ràpida.\n" +#: add-patch.c #, c-format msgid "" "---\n" "To remove '%c' lines, make them ' ' lines (context).\n" "To remove '%c' lines, delete them.\n" -"Lines starting with %c will be removed.\n" +"Lines starting with %s will be removed.\n" msgstr "" "---\n" "Per a eliminar les línies «%c», convertiu-les en línies ' ' (context).\n" "Per a eliminar les línies «%c», suprimiu-les.\n" -"Les línies que comencin per %c s'eliminaran.\n" +"Les línies que comencin per %s s'eliminaran.\n" +#: add-patch.c msgid "" "If it does not apply cleanly, you will be given an opportunity to\n" "edit again. If all lines of the hunk are removed, then the edit is\n" @@ -582,9 +687,11 @@ msgstr "" "de nou. Si s'eliminen totes les línies del tros, llavors l'edició s'avorta\n" "i el tros es deixa sense cap canvi.\n" +#: add-patch.c msgid "could not parse hunk header" msgstr "no s'ha pogut analitzar la capçalera del tros" +#: add-patch.c msgid "'git apply --cached' failed" msgstr "«git apply --cached» ha fallat" @@ -594,21 +701,26 @@ msgstr "«git apply --cached» ha fallat" #. (saying "n" for "no" discards!) if the translation #. of the word "no" does not start with n. #. +#: add-patch.c msgid "" "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? " msgstr "" "El tros editat no s'aplica. Editeu-lo de nou (si responeu «no» es " "descartarà) [y/n]? " +#: add-patch.c msgid "The selected hunks do not apply to the index!" msgstr "Els trossos seleccionats no s'apliquen a l'índex!" +#: add-patch.c msgid "Apply them to the worktree anyway? " msgstr "Voleu aplicar-los igualment a l'arbre de treball? " +#: add-patch.c msgid "Nothing was applied.\n" msgstr "No s'ha aplicat res.\n" +#: add-patch.c msgid "" "j - leave this hunk undecided, see next undecided hunk\n" "J - leave this hunk undecided, see next hunk\n" @@ -618,69 +730,105 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" -"j - deixa aquest tros sense decidir, veure el tros sense decidir següent\n" -"J - deixa aquest tros sense decidir, veure el tros següent\n" -"k - deixa aquest tros sense decidir, veure el tros sense decidir anterior\n" -"K - deixa aquest tros sense decidir, veure el tros anterior\n" -"g - selecciona el tros on voleu anar\n" -"/ - cerca un tros que coincideixi amb l'expressió regular donada\n" -"s - divideix el tros actual en trossos més petits\n" +"j - deixa aquest tros sense decidir, veges el tros següent no decidit \n" +"J - deixa aquest tros sense decidir, veges el tros següent\n" +"k - deixa aquest tros sense decidir, veges el tros anterior no decidit ºn\n" +"K - deixa aquest tros sense decidir, veges el tros anterior\n" +"g - selecciona un tros a on anar\n" +"/ - cerca un tros que concorde amb l'expressió regular donada\n" +"s - divideix el tros actual en trossos més menuts\n" "e - edita manualment el tros actual\n" -"? - mostra l'ajuda\n" +"p - imprimeix el tros actual, «P» per a usar el paginador\n" +"? - imprimeix l'ajuda\n" +#: add-patch.c +#, c-format +msgid "Only one letter is expected, got '%s'" +msgstr "S'espera una lletra, s'ha obtingut «%s»" + +#: add-patch.c msgid "No previous hunk" msgstr "Sense tros previ" +#: add-patch.c msgid "No next hunk" msgstr "No hi ha tros següent" +#: add-patch.c msgid "No other hunks to goto" msgstr "No hi ha altres trossos on anar-hi" +#: add-patch.c msgid "go to which hunk (<ret> to see more)? " -msgstr "ves a quin tros (<ret> per a veure'n més)? " +msgstr "ves a quin tros (<intro> per a veure'n més)? " +#: add-patch.c msgid "go to which hunk? " msgstr "ves a quin tros? " +#: add-patch.c #, c-format msgid "Invalid number: '%s'" msgstr "Número no vàlid: «%s»" +#: add-patch.c #, c-format msgid "Sorry, only %d hunk available." msgid_plural "Sorry, only %d hunks available." msgstr[0] "Només %d tros disponible." msgstr[1] "Només %d trossos disponibles." +#: add-patch.c msgid "No other hunks to search" msgstr "No hi ha cap altre tros a cercar" +#: add-patch.c msgid "search for regex? " msgstr "cerca per expressió regular? " +#: add-patch.c #, c-format msgid "Malformed search regexp %s: %s" msgstr "Expressió regular de cerca mal formada %s: %s" +#: add-patch.c msgid "No hunk matches the given pattern" msgstr "No hi ha trossos que coincideixin amb el patró donat" +#: add-patch.c msgid "Sorry, cannot split this hunk" msgstr "No es pot dividir aquest tros" +#: add-patch.c #, c-format msgid "Split into %d hunks." msgstr "Divideix en %d trossos." +#: add-patch.c msgid "Sorry, cannot edit this hunk" msgstr "No es pot editar aquest tros" +#: add-patch.c +#, c-format +msgid "Unknown command '%s' (use '?' for help)" +msgstr "Ordre desconeguda: «%s» (useu «?» per a obtenir ajuda)" + +#: add-patch.c msgid "'git apply' failed" msgstr "«git apply» ha fallat" +#: add-patch.c +msgid "No changes." +msgstr "No hi ha canvis." + +#: add-patch.c +msgid "Only binary files changed." +msgstr "Només han canviat els fitxers binaris." + +#: advice.c #, c-format msgid "" "\n" @@ -689,28 +837,36 @@ msgstr "" "\n" "Desactiva aquest missatge amb «git config advice.%s false»" +#: advice.c #, c-format -msgid "%shint: %.*s%s\n" -msgstr "%sconsell: %.*s%s\n" +msgid "%shint:%s%.*s%s\n" +msgstr "%sconsell:%s%.*s%s\n" +#: advice.c msgid "Cherry-picking is not possible because you have unmerged files." msgstr "Fer «cherry pick» no és possible perquè teniu fitxers sense fusionar." +#: advice.c msgid "Committing is not possible because you have unmerged files." msgstr "Cometre no és possible perquè teniu fitxers sense fusionar." +#: advice.c msgid "Merging is not possible because you have unmerged files." msgstr "Fusionar no és possible perquè teniu fitxers sense fusionar." +#: advice.c msgid "Pulling is not possible because you have unmerged files." msgstr "Baixar no és possible perquè teniu fitxers sense fusionar." +#: advice.c msgid "Reverting is not possible because you have unmerged files." msgstr "Revertir no és possible perquè teniu fitxers sense fusionar." +#: advice.c msgid "Rebasing is not possible because you have unmerged files." msgstr "Fer «rebase» no és possible perquè teniu fitxers sense fusionar." +#: advice.c 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." @@ -719,18 +875,23 @@ msgstr "" "«git add/rm <fitxer>» segons sigui apropiat per a\n" "marcar la resolució i feu una comissió." +#: advice.c msgid "Exiting because of an unresolved conflict." msgstr "S'està sortint a causa d'un conflicte no resolt." +#: advice.c builtin/merge.c msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "No heu conclòs la vostra fusió (MERGE_HEAD existeix)." +#: advice.c msgid "Please, commit your changes before merging." msgstr "Cometeu els vostres canvis abans de fusionar." +#: advice.c msgid "Exiting because of unfinished merge." msgstr "S'està sortint a causa d'una fusió no terminada." +#: advice.c msgid "" "Diverging branches can't be fast-forwarded, you need to either:\n" "\n" @@ -748,9 +909,11 @@ msgstr "" "\n" "\tgit rebase\n" +#: advice.c msgid "Not possible to fast-forward, aborting." msgstr "No és possible avançar ràpidament, s'està avortant." +#: advice.c #, c-format msgid "" "The following paths and/or pathspecs matched paths that exist\n" @@ -761,6 +924,7 @@ msgstr "" "amb camins que existeixen fora de la vostra definició de\n" "«sparse-checkout», així que no serà actualitzaran en l'índex:\n" +#: advice.c msgid "" "If you intend to update such entries, try one of the following:\n" "* Use the --sparse option.\n" @@ -770,6 +934,7 @@ msgstr "" "* Utilitzeu l'opció --sparse.\n" "* Inhabiliteu o modifiqueu les regles de dispersió." +#: advice.c #, c-format msgid "" "Note: switching to '%s'.\n" @@ -810,6 +975,7 @@ msgstr "" "«false»\n" "\n" +#: advice.c #, c-format msgid "" "The following paths have been moved outside the\n" @@ -820,6 +986,7 @@ msgstr "" "definició de sparse-checkout però no són dispersos\n" "a causa de modificacions en local.\n" +#: advice.c msgid "" "To correct the sparsity of these paths, do the following:\n" "* Use \"git add --sparse <paths>\" to update the index\n" @@ -829,79 +996,108 @@ msgstr "" "* Useu «git add --sparse <paths>» per a actualitzar l'índex\n" "* Useu «git sparse-checkout reapply» per a aplicar les regles de dispersió" +#: alias.c msgid "cmdline ends with \\" msgstr "la línia d'ordres acaba amb \\" +#: alias.c msgid "unclosed quote" msgstr "cometes no tancades" +#: alias.c builtin/cat-file.c builtin/notes.c builtin/prune-packed.c +#: builtin/receive-pack.c builtin/refs.c builtin/tag.c t/helper/test-pkt-line.c msgid "too many arguments" msgstr "hi ha massa arguments" +#: apply.c #, c-format msgid "unrecognized whitespace option '%s'" msgstr "opció d'espai en blanc «%s» no reconeguda" +#: apply.c #, c-format msgid "unrecognized whitespace ignore option '%s'" msgstr "opció ignora l'espai en blanc «%s» no reconeguda" +#: 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 "les opcions «%s» i «%s» no es poden usar juntes" +#: apply.c #, c-format msgid "'%s' outside a repository" msgstr "«%s» fora d'un repositori" +#: apply.c msgid "failed to read patch" msgstr "s'ha produït un error en llegir el pedaç" +#: apply.c msgid "patch too large" msgstr "el pedaç és massa gran" +#: apply.c #, c-format msgid "Cannot prepare timestamp regexp %s" msgstr "No es pot preparar l'expressió regular de marca de temps %s" +#: apply.c #, c-format msgid "regexec returned %d for input: %s" msgstr "regexec ha retornat %d per a l'entrada: %s" +#: apply.c #, c-format msgid "unable to find filename in patch at line %d" msgstr "no s'ha pogut trobar el nom de fitxer en el pedaç a la línia %d" +#: apply.c #, c-format msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d" msgstr "" "git apply: git-diff incorrecte - s'esperava /dev/null, s'ha rebut %s en la " "línia %d" +#: apply.c #, c-format msgid "git apply: bad git-diff - inconsistent new filename on line %d" msgstr "" "git apply: git-diff incorrecte - nom de fitxer nou inconsistent en la línia " "%d" +#: apply.c #, c-format msgid "git apply: bad git-diff - inconsistent old filename on line %d" msgstr "" "git apply: git-diff incorrecte - nom de fitxer antic inconsistent en la " "línia %d" +#: apply.c #, c-format msgid "git apply: bad git-diff - expected /dev/null on line %d" msgstr "git apply: git-diff incorrecte - s'esperava /dev/null en la línia %d" +#: apply.c #, c-format msgid "invalid mode on line %d: %s" msgstr "mode no vàlid en la línia %d: %s" +#: apply.c #, c-format msgid "inconsistent header lines %d and %d" msgstr "línies de capçalera %d i %d inconsistents" +#: apply.c #, c-format msgid "" "git diff header lacks filename information when removing %d leading pathname " @@ -916,75 +1112,93 @@ msgstr[1] "" "a la capçalera de git diff li manca informació de nom de fitxer en eliminar " "%d components de nom de camí inicial (línia %d)" +#: apply.c #, c-format msgid "git diff header lacks filename information (line %d)" msgstr "" "a la capçalera de git diff li manca informació de nom de fitxer (línia %d)" +#: apply.c #, c-format msgid "recount: unexpected line: %.*s" msgstr "recompte: línia inesperada: %.*s" +#: apply.c #, c-format msgid "patch fragment without header at line %d: %.*s" msgstr "fragment de pedaç sense capçalera a la línia %d: %.*s" +#: apply.c msgid "new file depends on old contents" msgstr "el fitxer nou depèn dels continguts antics" +#: apply.c msgid "deleted file still has contents" msgstr "el fitxer suprimit encara té continguts" +#: apply.c #, c-format msgid "corrupt patch at line %d" msgstr "pedaç malmès a la línia %d" +#: apply.c #, c-format msgid "new file %s depends on old contents" msgstr "el fitxer nou %s depèn dels continguts antics" +#: apply.c #, c-format msgid "deleted file %s still has contents" msgstr "el fitxer suprimit %s encara té continguts" +#: apply.c #, c-format msgid "** warning: file %s becomes empty but is not deleted" msgstr "** advertència: el fitxer %s queda buit però no se suprimeix" +#: apply.c #, c-format msgid "corrupt binary patch at line %d: %.*s" msgstr "pedaç binari malmès a la línia %d: %.*s" +#: apply.c #, c-format msgid "unrecognized binary patch at line %d" msgstr "pedaç binari no reconegut a la línia %d" +#: apply.c #, c-format msgid "patch with only garbage at line %d" msgstr "pedaç amb només escombraries a la línia %d" +#: apply.c #, c-format msgid "unable to read symlink %s" msgstr "no s'ha pogut llegir l'enllaç simbòlic %s" +#: apply.c #, c-format msgid "unable to open or read %s" msgstr "no s'ha pogut obrir o llegir %s" +#: apply.c #, c-format msgid "invalid start of line: '%c'" msgstr "inici de línia no vàlid: «%c»" +#: apply.c #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." msgstr[0] "El tros #%d ha tingut èxit a %d (desplaçament d'%d línia)." msgstr[1] "El tros #%d ha tingut èxit a %d (desplaçament de %d línies)." +#: apply.c #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "El context s'ha reduït a (%ld/%ld) per a aplicar el fragment a %d" +#: apply.c #, c-format msgid "" "while searching for:\n" @@ -993,19 +1207,23 @@ msgstr "" "tot cercant:\n" "%.*s" +#: apply.c #, c-format msgid "missing binary patch data for '%s'" msgstr "manquen les dades de pedaç binari de «%s»" +#: apply.c #, c-format msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'" msgstr "no es pot aplicar al revés un pedaç binari sense el tros revés a «%s»" +#: apply.c #, c-format msgid "cannot apply binary patch to '%s' without full index line" msgstr "" "no es pot aplicar un pedaç binari a «%s» sense la línia d'índex completa" +#: apply.c #, c-format msgid "" "the patch applies to '%s' (%s), which does not match the current contents." @@ -1013,235 +1231,287 @@ msgstr "" "el pedaç s'aplica a «%s» (%s), el qual no coincideix amb els continguts " "actuals." +#: apply.c #, c-format msgid "the patch applies to an empty '%s' but it is not empty" msgstr "el pedaç s'aplica a un «%s» buit però no és buit" +#: apply.c #, c-format msgid "the necessary postimage %s for '%s' cannot be read" msgstr "no es pot llegir la postimatge %s necessària per a «%s»" +#: apply.c #, c-format msgid "binary patch does not apply to '%s'" msgstr "el pedaç binari no s'aplica a «%s»" +#: apply.c #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" "el pedaç binari a «%s» crea un resultat incorrecte (s'esperava %s, s'ha " "rebut %s)" +#: apply.c #, c-format msgid "patch failed: %s:%ld" msgstr "el pedaç ha fallat: %s:%ld" +#: apply.c builtin/mv.c #, c-format msgid "cannot checkout %s" msgstr "no es pot agafar %s" +#: apply.c midx.c pack-mtimes.c pack-revindex.c setup.c #, c-format msgid "failed to read %s" msgstr "s'ha produït un error en llegir %s" +#: apply.c #, c-format msgid "reading from '%s' beyond a symbolic link" msgstr "s'està llegint de «%s» més enllà d'un enllaç simbòlic" +#: apply.c #, c-format msgid "path %s has been renamed/deleted" msgstr "el camí %s s'ha canviat de nom / s'ha suprimit" +#: apply.c #, c-format msgid "%s: does not exist in index" msgstr "%s: no existeix en l'índex" +#: apply.c #, c-format msgid "%s: does not match index" msgstr "%s: no coincideix amb l'índex" +#: apply.c msgid "repository lacks the necessary blob to perform 3-way merge." msgstr "" "al repositori li manca el blob necessari per a fer a una fusió de 3 vies." +#: apply.c #, c-format msgid "Performing three-way merge...\n" msgstr "S'està fent una fusió de 3 vies...\n" +#: apply.c #, c-format msgid "cannot read the current contents of '%s'" msgstr "no es poden llegir els continguts actuals de «%s»" +#: apply.c #, c-format msgid "Failed to perform three-way merge...\n" msgstr "S'ha produït un error en fer una fusió de tres vies...\n" +#: apply.c #, c-format msgid "Applied patch to '%s' with conflicts.\n" msgstr "S'ha aplicat el pedaç a «%s» amb conflictes.\n" +#: apply.c #, c-format msgid "Applied patch to '%s' cleanly.\n" msgstr "S'ha aplicat el pedaç a «%s» netament.\n" +#: apply.c #, c-format msgid "Falling back to direct application...\n" msgstr "S'està usant alternativament l'aplicació directa...\n" +#: apply.c msgid "removal patch leaves file contents" msgstr "el pedaç d'eliminació deixa els continguts dels fitxers" +#: apply.c #, c-format msgid "%s: wrong type" msgstr "%s: tipus erroni" +#: apply.c #, c-format msgid "%s has type %o, expected %o" msgstr "%s és del tipus %o, s'esperava %o" +#: apply.c read-cache.c #, c-format msgid "invalid path '%s'" msgstr "camí no vàlid: «%s»" +#: apply.c #, c-format msgid "%s: already exists in index" msgstr "%s: ja existeix en l'índex" +#: apply.c #, c-format msgid "%s: already exists in working directory" msgstr "%s: ja existeix en el directori de treball" +#: apply.c #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "el mode nou (%o) de %s no coincideix amb el mode antic (%o)" +#: apply.c #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "el mode nou (%o) de %s no coincideix amb el mode antic (%o) de %s" +#: apply.c #, c-format msgid "affected file '%s' is beyond a symbolic link" msgstr "el fitxer afectat «%s» és més enllà d'un enllaç simbòlic" +#: apply.c #, c-format msgid "%s: patch does not apply" msgstr "%s: el pedaç no s'aplica" +#: apply.c #, c-format msgid "Checking patch %s..." msgstr "S'està comprovant el pedaç %s..." +#: apply.c #, c-format msgid "sha1 information is lacking or useless for submodule %s" msgstr "falta la informació sha1 o és inútil per al submòdul %s" +#: apply.c #, c-format msgid "mode change for %s, which is not in current HEAD" msgstr "canvi de mode per a %s, el qual no està en la HEAD actual" +#: apply.c #, c-format msgid "sha1 information is lacking or useless (%s)." msgstr "falta informació sha1 o és inútil (%s)." +#: apply.c #, c-format msgid "could not add %s to temporary index" msgstr "no s'ha pogut afegir %s a l'índex temporal" +#: apply.c #, c-format msgid "could not write temporary index to %s" msgstr "no s'ha pogut escriure l'índex temporal a %s" +#: apply.c #, c-format msgid "unable to remove %s from index" msgstr "no s'ha pogut eliminar %s de l'índex" +#: apply.c #, c-format msgid "corrupt patch for submodule %s" msgstr "pedaç malmès per al submòdul %s" +#: apply.c #, c-format msgid "unable to stat newly created file '%s'" msgstr "no s'ha pogut fer stat al fitxer novament creat «%s»" +#: apply.c #, c-format msgid "unable to create backing store for newly created file %s" msgstr "" "no s'ha pogut crear un magatzem de suport per al fitxer novament creat %s" +#: apply.c #, c-format msgid "unable to add cache entry for %s" msgstr "no s'ha pogut afegir una entrada de cau per a %s" +#: apply.c builtin/bisect.c builtin/gc.c #, c-format msgid "failed to write to '%s'" msgstr "no s'ha pogut escriure a «%s»" +#: apply.c #, c-format msgid "closing file '%s'" msgstr "s'està tancant el fitxer «%s»" +#: apply.c #, c-format msgid "unable to write file '%s' mode %o" msgstr "no s'ha pogut escriure el fitxer «%s» mode %o" +#: apply.c #, c-format msgid "Applied patch %s cleanly." msgstr "El pedaç %s s'ha aplicat netament." +#: apply.c msgid "internal error" msgstr "error intern" +#: apply.c #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "S'està aplicant el pedaç %%s amb %d rebuig..." msgstr[1] "S'està aplicant el pedaç %%s amb %d rebutjos..." -#, c-format -msgid "truncating .rej filename to %.*s.rej" -msgstr "s'està truncant el nom del fitxer .rej a %.*s.rej" - +#: apply.c #, c-format msgid "cannot open %s" msgstr "no es pot obrir %s" +#: apply.c rerere.c #, c-format msgid "cannot unlink '%s'" msgstr "no es pot fer «unlink» de «%s»" +#: apply.c #, c-format msgid "Hunk #%d applied cleanly." msgstr "El tros #%d s'ha aplicat netament." +#: apply.c #, c-format msgid "Rejected hunk #%d." msgstr "S'ha rebutjat el tros #%d." +#: apply.c #, c-format msgid "Skipped patch '%s'." msgstr "S'ha omès el pedaç «%s»." +#: apply.c msgid "No valid patches in input (allow with \"--allow-empty\")" msgstr "No hi ha pedaços vàlids a l'entrada (permeteu-los amb «--allow-empty»)" +#: apply.c t/helper/test-cache-tree.c msgid "unable to read index file" msgstr "no es pot llegir el fitxer d'índex" +#: apply.c #, c-format msgid "can't open patch '%s': %s" msgstr "no es pot obrir el pedaç «%s»: %s" +#: apply.c #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "s'ha silenciat %d error d'espai en blanc" msgstr[1] "s'han silenciat %d errors d'espai en blanc" +#: apply.c #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." msgstr[0] "%d línia afegeix errors d'espai en blanc." msgstr[1] "%d línies afegeixen errors d'espai en blanc." +#: apply.c #, c-format msgid "%d line applied after fixing whitespace errors." msgid_plural "%d lines applied after fixing whitespace errors." @@ -1250,287 +1520,398 @@ msgstr[0] "" msgstr[1] "" "S'han aplicat %d línies després d'arreglar els errors d'espai en blanc." +#: apply.c builtin/mv.c builtin/rm.c msgid "Unable to write new index file" msgstr "No s'ha pogut escriure un fitxer d'índex nou" +#: apply.c msgid "don't apply changes matching the given path" msgstr "no apliquis els canvis que coincideixin amb el camí donat" +#: apply.c msgid "apply changes matching the given path" msgstr "aplica els canvis que coincideixin amb el camí donat" +#: apply.c builtin/am.c msgid "num" msgstr "nombre" +#: apply.c msgid "remove <num> leading slashes from traditional diff paths" msgstr "" "elimina <nombre> barres obliqües inicials dels camins de diferència " "tradicionals" +#: apply.c msgid "ignore additions made by the patch" msgstr "ignora afegiments fets pel pedaç" +#: apply.c msgid "instead of applying the patch, output diffstat for the input" msgstr "" "en lloc d'aplicar el pedaç, emet les estadístiques de diferència de l'entrada" +#: apply.c msgid "show number of added and deleted lines in decimal notation" msgstr "mostra el nombre de línies afegides i suprimides en notació decimal" +#: apply.c msgid "instead of applying the patch, output a summary for the input" msgstr "en lloc d'aplicar el pedaç, emet un resum de l'entrada" +#: apply.c msgid "instead of applying the patch, see if the patch is applicable" msgstr "en lloc d'aplicar el pedaç, determina si el pedaç és aplicable" +#: apply.c msgid "make sure the patch is applicable to the current index" msgstr "assegura que el pedaç sigui aplicable a l'índex actual" +#: apply.c msgid "mark new files with `git add --intent-to-add`" msgstr "marca els fitxers nous amb «git add --intent-to-add»" +#: apply.c msgid "apply a patch without touching the working tree" msgstr "aplica un pedaç sense tocar l'arbre de treball" +#: apply.c msgid "accept a patch that touches outside the working area" msgstr "accepta un pedaç que toqui fora de l'àrea de treball" +#: apply.c msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "aplica el pedaç també (useu amb --stat/--summary/--check)" +#: apply.c msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "" "intenta una fusió de tres vies, si falla intenta llavors un pedaç normal" +#: apply.c builtin/merge-file.c +msgid "for conflicts, use our version" +msgstr "en conflictes, usa la nostra versió" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use their version" +msgstr "en conflictes, usa la seva versió" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use a union version" +msgstr "en conflictes, usa una versió d'unió" + +#: apply.c msgid "build a temporary index based on embedded index information" msgstr "construeix un índex temporal basat en la informació d'índex incrustada" +#: apply.c builtin/checkout-index.c msgid "paths are separated with NUL character" msgstr "els camins se separen amb el caràcter NUL" +#: apply.c msgid "ensure at least <n> lines of context match" msgstr "assegura't que almenys <n> línies de context coincideixin" +#: apply.c builtin/am.c builtin/interpret-trailers.c builtin/pack-objects.c +#: builtin/rebase.c msgid "action" msgstr "acció" +#: apply.c msgid "detect new or modified lines that have whitespace errors" msgstr "" "detecta les línies noves o modificades que tinguin errors d'espai en blanc" +#: apply.c msgid "ignore changes in whitespace when finding context" msgstr "ignora els canvis d'espai en blanc en cercar context" +#: apply.c msgid "apply the patch in reverse" msgstr "aplica el pedaç al revés" +#: apply.c msgid "don't expect at least one line of context" msgstr "no esperis almenys una línia de context" +#: apply.c msgid "leave the rejected hunks in corresponding *.rej files" msgstr "deixa els trossos rebutjats en fitxers *.rej corresponents" +#: apply.c msgid "allow overlapping hunks" msgstr "permet trossos superposats" +#: apply.c msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "tolera una línia nova incorrectament detectada al final del fitxer" +#: apply.c msgid "do not trust the line counts in the hunk headers" msgstr "no confiïs en els recomptes de línia en les capçaleres dels trossos" +#: apply.c builtin/am.c msgid "root" msgstr "arrel" +#: apply.c msgid "prepend <root> to all filenames" msgstr "anteposa <arrel> a tots els noms de fitxer" +#: apply.c msgid "don't return error for empty patches" msgstr "no retornis l'error per als pedaços buits" +#: apply.c +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs, i --union requereixen --3way" + +#: archive-tar.c archive-zip.c #, c-format msgid "cannot stream blob %s" msgstr "no es pot transmetre el blob %s" +#: archive-tar.c archive-zip.c #, c-format msgid "unsupported file mode: 0%o (SHA1: %s)" msgstr "mode de fitxer no compatible: 0%o (SHA1: %s)" +#: archive-tar.c archive-zip.c builtin/pack-objects.c #, c-format msgid "deflate error (%d)" msgstr "error de deflació (%d)" +#: archive-tar.c #, c-format msgid "unable to start '%s' filter" msgstr "no s'ha pogut iniciar el filtre «%s»" +#: archive-tar.c msgid "unable to redirect descriptor" msgstr "no s'ha pogut redirigir el descriptor" +#: archive-tar.c #, c-format msgid "'%s' filter reported error" msgstr "«%s» error reportat pel filtre" +#: archive-zip.c #, c-format msgid "path is not valid UTF-8: %s" msgstr "el camí no és vàlid en UTF-8: %s" +#: archive-zip.c #, c-format msgid "path too long (%d chars, SHA1: %s): %s" msgstr "el camí és massa llarg (%d caràcters, SHA1: %s): %s" +#: archive-zip.c #, c-format msgid "timestamp too large for this system: %<PRIuMAX>" msgstr "marca de temps massa gran per a aquest sistema: %<PRIuMAX>" +#: archive.c msgid "git archive [<options>] <tree-ish> [<path>...]" msgstr "git archive [<opcions>] <arbre> [<camí>...]" +#: archive.c msgid "" "git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]" msgstr "" "git archive --remote <repositori> [--exec <ordre>] [<opcions>] <arbre> " "[<camí>...]" +#: archive.c msgid "git archive --remote <repo> [--exec <cmd>] --list" msgstr "git archive --remote <repositori> [--exec <ordre>] --list" +#: archive.c builtin/gc.c builtin/notes.c builtin/tag.c #, c-format msgid "cannot read '%s'" msgstr "no es pot llegir «%s»" +#: archive.c #, c-format msgid "pathspec '%s' matches files outside the current directory" msgstr "" "l'especificació de camí «%s» coincideix amb fitxers fora del directori actual" +#: archive.c builtin/add.c builtin/rm.c #, c-format msgid "pathspec '%s' did not match any files" msgstr "l'especificació de camí «%s» no ha coincidit amb cap fitxer" +#: archive.c #, c-format msgid "no such ref: %.*s" msgstr "no existeix la referència: %.*s" +#: archive.c #, c-format msgid "not a valid object name: %s" msgstr "no és un nom d'objecte vàlid: %s" +#: archive.c t/helper/test-cache-tree.c #, c-format msgid "not a tree object: %s" msgstr "no és un objecte d'arbre: %s" +#: archive.c +#, c-format +msgid "failed to unpack tree object %s" +msgstr "s'ha produït un error en desempaquetar l'objecte d'arbre %s" + +#: archive.c #, c-format msgid "File not found: %s" msgstr "Fitxer no trobat: %s" +#: archive.c #, c-format msgid "Not a regular file: %s" msgstr "No és un fitxer normal: %s" +#: archive.c #, c-format msgid "unclosed quote: '%s'" msgstr "cometes no tancades: «%s»" +#: archive.c #, c-format msgid "missing colon: '%s'" msgstr "falten els dos punts: «%s»" +#: archive.c #, c-format msgid "empty file name: '%s'" msgstr "nom de fitxer buit: «%s»" +#: archive.c msgid "fmt" msgstr "format" +#: archive.c msgid "archive format" msgstr "format d'arxiu" +#: archive.c builtin/log.c parse-options.h msgid "prefix" msgstr "prefix" +#: archive.c msgid "prepend prefix to each pathname in the archive" msgstr "anteposa el prefix a cada nom de camí en l'arxiu" +#: archive.c builtin/blame.c builtin/commit-tree.c builtin/config.c +#: builtin/fast-export.c builtin/gc.c builtin/grep.c builtin/hash-object.c +#: builtin/ls-files.c builtin/notes.c builtin/read-tree.c parse-options.h msgid "file" msgstr "fitxer" +#: archive.c msgid "add untracked file to archive" msgstr "inclou els fitxers no seguits a l'arxiu" +#: archive.c msgid "path:content" msgstr "camí: contingut" +#: archive.c builtin/archive.c msgid "write the archive to this file" msgstr "escriu l'arxiu a aquest fitxer" +#: archive.c msgid "read .gitattributes in working directory" msgstr "llegeix .gitattributes en el directori de treball" +#: archive.c msgid "report archived files on stderr" msgstr "informa de fitxers arxivats en stderr" +#: archive.c builtin/clone.c builtin/fetch.c builtin/pack-objects.c +#: builtin/pull.c msgid "time" msgstr "data" +#: archive.c msgid "set modification time of archive entries" msgstr "estableix l'hora de modificació de les entrades de l'arxiu" +#: archive.c msgid "set compression level" msgstr "estableix el nivell de compressió" +#: archive.c msgid "list supported archive formats" msgstr "llista els formats d'arxiu admesos" +#: archive.c builtin/archive.c builtin/clone.c builtin/submodule--helper.c msgid "repo" msgstr "repositori" +#: archive.c builtin/archive.c msgid "retrieve the archive from remote repository <repo>" msgstr "recupera l'arxiu del repositori remot <repositori>" +#: archive.c builtin/archive.c builtin/difftool.c builtin/notes.c msgid "command" msgstr "ordre" +#: archive.c builtin/archive.c msgid "path to the remote git-upload-archive command" msgstr "camí a l'ordre git-upload-archive remota" +#: archive.c msgid "Unexpected option --remote" msgstr "Opció inesperada --remote" +#: archive.c builtin/add.c builtin/checkout.c builtin/clone.c builtin/commit.c +#: builtin/fast-export.c builtin/index-pack.c builtin/log.c builtin/reset.c +#: builtin/rm.c builtin/stash.c builtin/worktree.c fetch-pack.c http-fetch.c +#: revision.c #, c-format msgid "the option '%s' requires '%s'" msgstr "l'opció «%s» requereix «%s»" +#: archive.c msgid "Unexpected option --output" msgstr "Opció inesperada --output" +#: archive.c t/unit-tests/unit-test.c #, c-format msgid "extra command line parameter '%s'" msgstr "paràmetre extra de la línia d'ordres «%s»" +#: archive.c #, c-format msgid "Unknown archive format '%s'" msgstr "Format d'arxiu desconegut «%s»" +#: archive.c #, c-format msgid "Argument not supported for format '%s': -%d" msgstr "Argument no admès per al format «%s»: -%d" +#: attr.c #, c-format msgid "%.*s is not a valid attribute name" msgstr "%.*s no és un nom d'atribut vàlid" +#: attr.c msgid "unable to add additional attribute" msgstr "no s'ha pogut afegir l'atribut addicional" +#: attr.c #, c-format msgid "ignoring overly long attributes line %d" msgstr "s'ignorarà la línia d'atributs massa llarga %d" +#: attr.c #, c-format msgid "%s not allowed: %s:%d" msgstr "%s no està permès: %s:%d" +#: attr.c msgid "" "Negative patterns are ignored in git attributes\n" "Use '\\!' for literal leading exclamation." @@ -1538,41 +1919,56 @@ msgstr "" "Els patrons negatius s'ignoren en els atributs de git\n" "Useu «\\!» per exclamació capdavantera literal." +#: attr.c #, c-format msgid "cannot fstat gitattributes file '%s'" msgstr "no es pot fer fstat gitattributes al fitxer «%s»" +#: attr.c #, c-format msgid "ignoring overly large gitattributes file '%s'" msgstr "s'ignorarà el fitxer «%s» gitattributes per a ser massa gran" +#: attr.c #, c-format msgid "ignoring overly large gitattributes blob '%s'" msgstr "s'ignorarà el blob «%s» gitattributes per a ser massa gran" +#: attr.c +msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo" +msgstr "no es pot usar --attr-source o GIT_ATTR_SOURCE sense repository" + +#: attr.c msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "--attr-source incorrecte o GIT_ATTR_SOURCE" +#: attr.c read-cache.c #, c-format msgid "unable to stat '%s'" msgstr "no s'ha pogut fer «stat» a «%s»" +#: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c +#: builtin/pack-objects.c combine-diff.c object-file.c rerere.c #, c-format msgid "unable to read %s" msgstr "no s'ha pogut llegir %s" +#: bisect.c #, c-format msgid "Badly quoted content in file '%s': %s" msgstr "Comentari amb cometes errònies en el fitxer «%s»: %s" +#: bisect.c #, c-format msgid "We cannot bisect more!\n" msgstr "No podem bisecar més!\n" +#: bisect.c #, c-format msgid "Not a valid commit name %s" msgstr "No és un nom de comissió vàlid %s" +#: bisect.c #, c-format msgid "" "The merge base %s is bad.\n" @@ -1581,6 +1977,7 @@ msgstr "" "La base de fusió %s és errònia.\n" "Això vol dir que el defecte s'ha arreglat entre %s i [%s].\n" +#: bisect.c #, c-format msgid "" "The merge base %s is new.\n" @@ -1589,6 +1986,7 @@ msgstr "" "La base de fusió %s és nova.\n" "La propietat s'ha canviat entre %s i [%s].\n" +#: bisect.c #, c-format msgid "" "The merge base %s is %s.\n" @@ -1597,6 +1995,7 @@ msgstr "" "La base de fusió %s és %s.\n" "Això vol dir que la primera comissió «%s» és entre %s i [%s].\n" +#: bisect.c #, c-format msgid "" "Some %s revs are not ancestors of the %s rev.\n" @@ -1607,6 +2006,7 @@ msgstr "" "git bisect no pot funcionar correctament en aquest cas.\n" "Potser heu confós les revisions %s i %s?\n" +#: bisect.c #, c-format msgid "" "the merge base between %s and [%s] must be skipped.\n" @@ -1618,29 +2018,41 @@ msgstr "" "%s.\n" "Continuem de totes maneres." +#: bisect.c #, c-format msgid "Bisecting: a merge base must be tested\n" msgstr "Bisecant: s'ha de provar una base de fusió\n" +#: bisect.c #, c-format msgid "a %s revision is needed" msgstr "es necessita una revisió %s" +#: bisect.c #, c-format msgid "could not create file '%s'" msgstr "no s'ha pogut crear el fitxer «%s»" +#: bisect.c builtin/notes.c +#, c-format +msgid "unable to start 'show' for object '%s'" +msgstr "no s'ha pogut iniciar «show» per a l'objecte «%s»" + +#: bisect.c builtin/merge.c #, c-format msgid "could not read file '%s'" msgstr "no s'ha pogut llegir el fitxer «%s»" +#: bisect.c msgid "reading bisect refs failed" msgstr "la lectura de les referències de bisecció ha fallat" +#: bisect.c #, c-format msgid "%s was both %s and %s\n" msgstr "%s era ambdós %s i %s\n" +#: bisect.c #, c-format msgid "" "No testable commit found.\n" @@ -1649,6 +2061,7 @@ msgstr "" "No s'ha trobat cap comissió comprovable.\n" "Potser heu començat amb paràmetres de camí incorrectes?\n" +#: bisect.c #, c-format msgid "(roughly %d step)" msgid_plural "(roughly %d steps)" @@ -1658,36 +2071,46 @@ msgstr[1] "(aproximadament %d passos)" #. TRANSLATORS: the last %s will be replaced with "(roughly %d #. steps)" translation. #. +#: bisect.c #, c-format msgid "Bisecting: %d revision left to test after this %s\n" msgid_plural "Bisecting: %d revisions left to test after this %s\n" msgstr[0] "Bisecant: manca %d revisió a provar després d'aquesta %s\n" msgstr[1] "Bisecant: manquen %d revisions a provar després d'aquesta %s\n" +#: blame.c msgid "--contents and --reverse do not blend well." msgstr "--contents i --reverse no funcionen bé juntes." +#: blame.c msgid "--reverse and --first-parent together require specified latest commit" msgstr "" "--reverse i --first-parent junts requereixen una última comissió especificada" +#: blame.c builtin/bisect.c builtin/commit.c builtin/log.c builtin/merge.c +#: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c +#: remote.c sequencer.c submodule.c msgid "revision walk setup failed" msgstr "la configuració del recorregut de revisions ha fallat" +#: blame.c msgid "" "--reverse --first-parent together require range along first-parent chain" msgstr "" "--reverse --first-parent junts requereixen un rang de la cadena de pares " "primers" +#: blame.c #, c-format msgid "no such path %s in %s" msgstr "no hi ha tal camí %s en %s" +#: blame.c #, c-format msgid "cannot read blob %s for path %s" msgstr "no es pot llegir el blob %s per al camí %s" +#: branch.c msgid "" "cannot inherit upstream tracking configuration of multiple refs when " "rebasing is requested" @@ -1695,25 +2118,31 @@ msgstr "" "no es pot heretar la configuració del seguiment de la font de múltiples " "referències quan es demana fer «rebase»" +#: branch.c #, c-format msgid "not setting branch '%s' as its own upstream" msgstr "no s'està establert la branca «%s» com a la seva pròpia font" +#: branch.c #, c-format msgid "branch '%s' set up to track '%s' by rebasing." msgstr "la branca «%s» està configurada per a seguir «%s» fent «rebase»." +#: branch.c #, c-format msgid "branch '%s' set up to track '%s'." msgstr "la branca «%s» està configurada per a seguir «%s»." +#: branch.c #, c-format msgid "branch '%s' set up to track:" msgstr "la branca «%s» està configurada per a seguir:" +#: branch.c msgid "unable to write upstream branch configuration" msgstr "no es pot escriure la configuració de la branca font" +#: branch.c msgid "" "\n" "After fixing the error cause you may try to fix up\n" @@ -1723,18 +2152,21 @@ msgstr "" "Després de corregir la causa de l'error, podeu intentar\n" "corregir la informació de seguiment remot executant:" +#: branch.c #, c-format msgid "asked to inherit tracking from '%s', but no remote is set" msgstr "" "s'ha demanat que hereti el seguiment de «%s», però no s'ha establert cap " "remot" +#: branch.c #, c-format msgid "asked to inherit tracking from '%s', but no merge configuration is set" msgstr "" "s'ha demanat que hereti el seguiment de «%s», però no s'ha establert cap " "configuració de fusionat" +#: branch.c #, c-format msgid "not tracking: ambiguous information for ref '%s'" msgstr "no s'està seguint: informació ambigua per a la referència «%s»" @@ -1750,6 +2182,7 @@ msgstr "no s'està seguint: informació ambigua per a la referència «%s»" #. you'll probably want to swap the "%s" and leading " " space #. around. #. +#: branch.c object-name.c #, c-format msgid " %s\n" msgstr " %s\n" @@ -1757,6 +2190,7 @@ msgstr " %s\n" #. TRANSLATORS: The second argument is a \n-delimited list of #. duplicate refspecs, composed above. #. +#: branch.c #, c-format msgid "" "There are multiple remotes whose fetch refspecs map to the remote\n" @@ -1777,30 +2211,40 @@ msgstr "" "els diferents refspecs remots s'assignen a diferents espais de noms\n" "de seguiment." +#: branch.c #, c-format msgid "'%s' is not a valid branch name" msgstr "«%s» no és un nom de branca vàlid" +#: branch.c builtin/branch.c +msgid "See `man git check-ref-format`" +msgstr "Vegeu `man git check-ref-format`" + +#: branch.c #, c-format msgid "a branch named '%s' already exists" msgstr "ja existeix una branca amb nom «%s»" +#: branch.c #, c-format msgid "cannot force update the branch '%s' used by worktree at '%s'" msgstr "" "no es pot forçar l'actualització de la branca «%s» utilitzada per l'arbre de " "treball a «%s»" +#: branch.c #, c-format msgid "cannot set up tracking information; starting point '%s' is not a branch" msgstr "" "no es pot configurar la informació de seguiment; el punt inicial «%s» no és " "una branca" +#: branch.c #, c-format msgid "the requested upstream branch '%s' does not exist" msgstr "la branca font demanada «%s» no existeix" +#: branch.c msgid "" "\n" "If you are planning on basing your work on an upstream\n" @@ -1821,22 +2265,27 @@ msgstr "" "«git push -u» per a establir la configuració font\n" "mentre pugeu." +#: branch.c builtin/replace.c #, c-format msgid "not a valid object name: '%s'" msgstr "no és un nom d'objecte vàlid: «%s»" +#: branch.c #, c-format msgid "ambiguous object name: '%s'" msgstr "nom d'objecte ambigu: «%s»" +#: branch.c #, c-format msgid "not a valid branch point: '%s'" msgstr "no és un punt de ramificació vàlid: «%s»" +#: branch.c #, c-format msgid "submodule '%s': unable to find submodule" msgstr "submòdul «%s»: no es pot trobar el submòdul" +#: branch.c #, c-format msgid "" "You may try updating the submodules using 'git checkout --no-recurse-" @@ -1845,105 +2294,131 @@ msgstr "" "Podeu provar d'actualitzar els submòduls utilitzant «git checkout --no-" "recurse-submodules %s && git submodule update --init»" +#: branch.c #, c-format msgid "submodule '%s': cannot create branch '%s'" msgstr "submòdul «%s»: no es pot crear la branca: «%s»" +#: branch.c #, c-format msgid "'%s' is already used by worktree at '%s'" msgstr "«%s» ja s'utilitza en l'arbre de treball a «%s»" +#: builtin/add.c msgid "git add [<options>] [--] <pathspec>..." -msgstr "git add [<opcions>] [--] <especificació-de-camí>..." +msgstr "git add [<opcions>] [--] <especificació-camí>..." +#: builtin/add.c #, c-format msgid "cannot chmod %cx '%s'" msgstr "no es pot fer chmod %cx «%s»" +#: builtin/add.c msgid "Unstaged changes after refreshing the index:" msgstr "Canvis «unstaged» després d'actualitzar l'índex:" -msgid "" -"the add.interactive.useBuiltin setting has been removed!\n" -"See its entry in 'git help config' for details." -msgstr "" -"s'ha eliminat la configuració add.interactive.useBuiltin\n" -"Per a més detalls, vegeu la seva entrada a «git help config»." - +#: builtin/add.c msgid "could not read the index" msgstr "no s'ha pogut llegir l'índex" +#: builtin/add.c msgid "editing patch failed" msgstr "l'edició del pedaç ha fallat" +#: builtin/add.c read-cache.c #, c-format msgid "could not stat '%s'" msgstr "no s'ha pogut fer stat a «%s»" +#: builtin/add.c msgid "empty patch. aborted" msgstr "pedaç buit. interromput" +#: builtin/add.c #, c-format msgid "could not apply '%s'" msgstr "no s'ha pogut aplicar «%s»" +#: builtin/add.c msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Els camins següents s'ignoren per un dels vostres fitxers .gitignore:\n" +#: builtin/add.c builtin/clean.c builtin/fetch.c builtin/mv.c +#: builtin/prune-packed.c builtin/pull.c builtin/push.c builtin/remote.c +#: builtin/rm.c builtin/send-pack.c msgid "dry run" msgstr "fes una prova" +#: builtin/add.c builtin/check-ignore.c builtin/commit.c +#: builtin/count-objects.c builtin/fsck.c builtin/log.c builtin/mv.c +#: builtin/read-tree.c builtin/refs.c msgid "be verbose" msgstr "sigues detallat" +#: builtin/add.c msgid "interactive picking" msgstr "selecció interactiva" +#: builtin/add.c builtin/checkout.c builtin/reset.c msgid "select hunks interactively" msgstr "selecciona els trossos interactivament" +#: builtin/add.c msgid "edit current diff and apply" msgstr "edita la diferència actual i aplica-la" +#: builtin/add.c msgid "allow adding otherwise ignored files" msgstr "permet afegir fitxers que d'altra manera s'ignoren" +#: builtin/add.c msgid "update tracked files" msgstr "actualitza els fitxers seguits" +#: builtin/add.c msgid "renormalize EOL of tracked files (implies -u)" msgstr "torna a normalitzar EOL dels fitxers seguits (implica -u)" +#: builtin/add.c msgid "record only the fact that the path will be added later" msgstr "registra només el fet que el camí s'afegirà més tard" +#: builtin/add.c msgid "add changes from all tracked and untracked files" msgstr "afegeix els canvis de tots els fitxers seguits i no seguits" +#: builtin/add.c msgid "ignore paths removed in the working tree (same as --no-all)" msgstr "" "ignora els camins eliminats en l'arbre de treball (el mateix que --no-all)" +#: builtin/add.c msgid "don't add, only refresh the index" msgstr "no afegeixis, només actualitza l'índex" +#: builtin/add.c msgid "just skip files which cannot be added because of errors" msgstr "només omet els fitxers que no es poden afegir a causa d'errors" +#: builtin/add.c msgid "check if - even missing - files are ignored in dry run" msgstr "" "comprova si els fitxers, fins i tot els absents, s'ignoren en fer una prova" +#: builtin/add.c builtin/mv.c builtin/rm.c msgid "allow updating entries outside of the sparse-checkout cone" msgstr "permet actualitzar les entrades fora del con del «sparse-checkout»" +#: builtin/add.c builtin/update-index.c msgid "override the executable bit of the listed files" msgstr "sobreescriu el bit executable dels fitxers llistats" +#: builtin/add.c msgid "warn when adding an embedded repository" msgstr "avisa'm quan s'afegeixi un repositori incrustat" +#: builtin/add.c #, c-format msgid "" "You've added another git repository inside your current repository.\n" @@ -1974,161 +2449,197 @@ msgstr "" "\n" "Vegeu «git help submodule» per a més informació." +#: builtin/add.c #, c-format msgid "adding embedded git repository: %s" msgstr "s'està afegint un repositori incrustat: %s" -msgid "" -"Use -f if you really want to add them.\n" -"Turn this message off by running\n" -"\"git config advice.addIgnoredFile false\"" -msgstr "" -"Utilitzeu -f si realment voleu afegir-los.\n" -"Desactiveu aquest missatge executant\n" -"«git config advice.addIgnoredFile false»" +#: builtin/add.c +msgid "Use -f if you really want to add them." +msgstr "\"Useu -f si realment voleu afegir-los." +#: builtin/add.c msgid "adding files failed" msgstr "l'afegiment de fitxers ha fallat" +#: builtin/add.c #, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "el paràmetre --chmod «%s» ha de ser o -x o +x" +#: builtin/add.c builtin/checkout.c builtin/commit.c builtin/reset.c +#: builtin/rm.c builtin/stash.c #, c-format msgid "'%s' and pathspec arguments cannot be used together" msgstr "«%s» i l'especificació de camí no es poden usar juntes" +#: builtin/add.c #, c-format msgid "Nothing specified, nothing added.\n" msgstr "No s'ha especificat res, no s'ha afegit res.\n" -msgid "" -"Maybe you wanted to say 'git add .'?\n" -"Turn this message off by running\n" -"\"git config advice.addEmptyPathspec false\"" -msgstr "" -"Potser voleu dir «git add .»?\n" -"Desactiveu aquest missatge executant\n" -"«git config advice.addEmptyPathspec false»" +#: builtin/add.c +msgid "Maybe you wanted to say 'git add .'?" +msgstr "Que potser volíeu dir «git add.»?" +#: builtin/add.c builtin/check-ignore.c builtin/checkout.c builtin/clean.c +#: builtin/commit.c builtin/diff-tree.c builtin/grep.c builtin/mv.c +#: builtin/reset.c builtin/rm.c builtin/submodule--helper.c read-cache.c +#: rerere.c submodule.c msgid "index file corrupt" msgstr "fitxer d'índex malmès" +#: 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 "no s'ha pogut escriure un fitxer d'índex nou" +#: builtin/am.c builtin/mailinfo.c mailinfo.c #, c-format msgid "bad action '%s' for '%s'" msgstr "acció «%s» incorrecta per a «%s»" +#: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c +#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c +#: ls-refs.c parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" msgstr "valor no vàlid per a «%s»: «%s»" +#: builtin/am.c builtin/commit.c builtin/merge.c sequencer.c #, c-format msgid "could not read '%s'" msgstr "no s'ha pogut llegir «%s»" +#: builtin/am.c msgid "could not parse author script" msgstr "no s'ha pogut analitzar l'script d'autor" +#: builtin/am.c builtin/replace.c commit.c sequencer.c #, c-format msgid "could not parse %s" msgstr "no s'ha pogut analitzar %s" +#: builtin/am.c #, c-format msgid "'%s' was deleted by the applypatch-msg hook" msgstr "s'ha suprimit «%s» pel lligam applypatch-msg" +#: builtin/am.c #, c-format msgid "Malformed input line: '%s'." msgstr "Línia d'entrada mal formada: «%s»." +#: builtin/am.c #, c-format msgid "Failed to copy notes from '%s' to '%s'" msgstr "S'ha produït un error en copiar les notes de «%s» a «%s»" +#: builtin/am.c msgid "fseek failed" msgstr "fseek ha fallat" +#: builtin/am.c builtin/rebase.c sequencer.c wrapper.c #, c-format msgid "could not open '%s' for reading" msgstr "no s'ha pogut obrir «%s» per a lectura" +#: builtin/am.c builtin/rebase.c editor.c sequencer.c wrapper.c #, c-format msgid "could not open '%s' for writing" msgstr "no s'ha pogut obrir «%s» per a escriptura" +#: builtin/am.c #, c-format msgid "could not parse patch '%s'" msgstr "no s'ha pogut analitzar el pedaç «%s»" +#: builtin/am.c msgid "Only one StGIT patch series can be applied at once" msgstr "Només una sèrie de pedaços StGIT es pot aplicar a la vegada" +#: builtin/am.c msgid "invalid timestamp" msgstr "marca de temps no vàlida" +#: builtin/am.c msgid "invalid Date line" msgstr "línia Date no vàlida" +#: builtin/am.c msgid "invalid timezone offset" msgstr "desplaçament del fus horari no vàlid" +#: builtin/am.c msgid "Patch format detection failed." msgstr "La detecció de format de pedaç ha fallat." +#: builtin/am.c builtin/clone.c #, c-format msgid "failed to create directory '%s'" msgstr "s'ha produït un error en crear el directori «%s»" +#: builtin/am.c msgid "Failed to split patches." msgstr "S'ha produït un error en dividir els pedaços." +#: builtin/am.c #, c-format -msgid "When you have resolved this problem, run \"%s --continue\"." -msgstr "Quan hàgiu resolt aquest problema, executeu «%s --continue»." +msgid "When you have resolved this problem, run \"%s --continue\".\n" +msgstr "Quan hàgiu resolt aquest problema, executeu «%s --continue».\n" +#: builtin/am.c #, c-format -msgid "If you prefer to skip this patch, run \"%s --skip\" instead." -msgstr "Si preferiu ometre aquest pedaç, executeu «%s --skip» en lloc d'això." +msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n" +msgstr "" +"Si preferiu ometre aquest pedaç, executeu «%s --skip» en lloc d'això.\n" +#: builtin/am.c #, c-format -msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"." +msgid "" +"To record the empty patch as an empty commit, run \"%s --allow-empty\".\n" msgstr "" "Per a enregistrar un pedaç buit com a comissió buida, executeu «%s --allow-" -"empty»." +"empty».\n" +#: builtin/am.c #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "" "Per a restaurar la branca original i deixar d'apedaçar, executeu «%s --" "abort»." +#: builtin/am.c msgid "Patch sent with format=flowed; space at the end of lines might be lost." msgstr "" "Pedaç enviat amb format=flowed; es pot perdre l'espai al final de les línies." +#: builtin/am.c #, c-format msgid "missing author line in commit %s" msgstr "manca la línia d'autor en la comissió %s" +#: builtin/am.c #, c-format msgid "invalid ident line: %.*s" msgstr "línia d'identitat no vàlida: %.*s" +#: builtin/am.c builtin/checkout.c builtin/clone.c commit-graph.c #, c-format msgid "unable to parse commit %s" msgstr "no s'ha pogut analitzar la comissió %s" +#: builtin/am.c msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "" "Al repositori li manquen els blobs necessaris per a retrocedir a una fusió " "de 3 vies." +#: builtin/am.c msgid "Using index info to reconstruct a base tree..." msgstr "S'està usant la informació d'índex per a reconstruir un arbre base..." +#: builtin/am.c msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." @@ -2136,25 +2647,32 @@ msgstr "" "Heu editat el vostre pedaç a mà?\n" "No s'aplica als blobs recordats en el seu índex." +#: builtin/am.c msgid "Falling back to patching base and 3-way merge..." msgstr "S'està retrocedint a apedaçar la base i una fusió de 3 vies..." +#: builtin/am.c msgid "Failed to merge in the changes." msgstr "S'ha produït un error en fusionar els canvis." +#: builtin/am.c builtin/merge.c sequencer.c msgid "git write-tree failed to write a tree" msgstr "git write-tree ha fallat en escriure un arbre" +#: builtin/am.c msgid "applying to an empty history" msgstr "s'està aplicant a una història buida" +#: builtin/am.c builtin/commit.c builtin/merge.c builtin/replay.c sequencer.c msgid "failed to write commit object" msgstr "s'ha produït un error en escriure l'objecte de comissió" +#: builtin/am.c #, c-format msgid "cannot resume: %s does not exist." msgstr "no es pot reprendre: %s no existeix." +#: builtin/am.c msgid "Commit Body is:" msgstr "El cos de la comissió és:" @@ -2162,48 +2680,60 @@ msgstr "El cos de la comissió és:" #. in your translation. The program will only accept English #. input at this point. #. +#: builtin/am.c #, c-format msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " msgstr "" "Voleu aplicar-lo? [y]es/[n]o/[e]dita/[v]isualitza el pedaç/[a]ccepta'ls " "tots: " +#: builtin/am.c builtin/commit.c msgid "unable to write index file" msgstr "no s'ha pogut escriure el fitxer d'índex" +#: builtin/am.c #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Índex brut: no es poden aplicar pedaços (bruts: %s)" +#: builtin/am.c #, c-format msgid "Skipping: %.*s" msgstr "S'està ometent: %.*s" +#: builtin/am.c #, c-format msgid "Creating an empty commit: %.*s" msgstr "S'està creant una comissió buida: %.*s" +#: builtin/am.c msgid "Patch is empty." msgstr "El pedaç està buit." +#: builtin/am.c #, c-format msgid "Applying: %.*s" msgstr "S'està aplicant: %.*s" +#: builtin/am.c msgid "No changes -- Patch already applied." msgstr "Sense canvis -- El pedaç ja s'ha aplicat." +#: builtin/am.c #, c-format msgid "Patch failed at %s %.*s" msgstr "El pedaç ha fallat a %s %.*s" +#: builtin/am.c msgid "Use 'git am --show-current-patch=diff' to see the failed patch" msgstr "" "Useu «git am --show-current-patch=diff» per a veure el pedaç que ha fallat" +#: builtin/am.c msgid "No changes - recorded it as an empty commit." msgstr "No hi ha canvis - enregistrat com una comissió buida." +#: builtin/am.c msgid "" "No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" @@ -2213,6 +2743,7 @@ msgstr "" "Si no hi ha res per a fer «stage», probablement alguna altra cosa ja ha\n" "introduït els mateixos canvis; potser voleu ometre aquest pedaç." +#: builtin/am.c msgid "" "You still have unmerged paths in your index.\n" "You should 'git add' each file with resolved conflicts to mark them as " @@ -2225,13 +2756,16 @@ msgstr "" "Podeu executar «git rm» en un fitxer per a acceptar «suprimit per ells» pel " "fitxer." +#: builtin/am.c builtin/reset.c #, c-format msgid "Could not parse object '%s'." msgstr "No s'ha pogut analitzar l'objecte «%s»." +#: builtin/am.c msgid "failed to clean index" msgstr "s'ha produït un error en netejar l'índex" +#: builtin/am.c msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" @@ -2239,109 +2773,155 @@ msgstr "" "Sembla que heu mogut HEAD després de l'última fallada de «am».\n" "No s'està rebobinant a ORIG_HEAD" +#: builtin/am.c builtin/bisect.c builtin/tag.c worktree.c #, c-format msgid "failed to read '%s'" msgstr "s'ha produït un error en llegir «%s»" +#: builtin/am.c msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<opcions>] [(<bústia> | <directori-de-correu>)...]" +#: builtin/am.c msgid "git am [<options>] (--continue | --skip | --abort)" msgstr "git am [<opcions>] (--continue | --skip | --abort)" +#: builtin/am.c msgid "run interactively" msgstr "executa interactivament" +#: builtin/am.c msgid "bypass pre-applypatch and applypatch-msg hooks" msgstr "evita els lligams pre-applypatch i applypatch-msg" +#: builtin/am.c msgid "historical option -- no-op" msgstr "opció històrica -- no-op" +#: builtin/am.c msgid "allow fall back on 3way merging if needed" msgstr "permet retrocedir a una fusió de 3 vies si és necessari" +#: builtin/am.c builtin/init-db.c builtin/prune-packed.c builtin/repack.c +#: builtin/stash.c msgid "be quiet" msgstr "silenciós" +#: builtin/am.c msgid "add a Signed-off-by trailer to the commit message" msgstr "afegeix un «trailer» tipus «Signed-off-by» al missatge de comissió" +#: builtin/am.c msgid "recode into utf8 (default)" msgstr "recodifica en utf8 (per defecte)" +#: builtin/am.c msgid "pass -k flag to git-mailinfo" msgstr "passa l'indicador -k a git-mailinfo" +#: builtin/am.c msgid "pass -b flag to git-mailinfo" msgstr "passa l'indicador -b a git-mailinfo" +#: builtin/am.c msgid "pass -m flag to git-mailinfo" msgstr "passa l'indicador -m a git-mailinfo" +#: builtin/am.c msgid "pass --keep-cr flag to git-mailsplit for mbox format" msgstr "passa l'indicador --keep-cr a git-mailsplit per al format mbox" +#: builtin/am.c msgid "strip everything before a scissors line" msgstr "elimina tot abans d'una línia de tisores" +#: builtin/am.c msgid "pass it through git-mailinfo" msgstr "passa-ho a través del git-mailinfo" +#: builtin/am.c msgid "pass it through git-apply" msgstr "passa-ho a través de git-apply" +#: builtin/am.c builtin/commit.c builtin/fmt-merge-msg.c builtin/grep.c +#: builtin/merge.c builtin/pull.c builtin/rebase.c builtin/repack.c +#: builtin/show-branch.c builtin/show-ref.c builtin/tag.c parse-options.h msgid "n" msgstr "n" +#: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c +#: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c +#: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c +#: builtin/submodule--helper.c builtin/tag.c builtin/verify-tag.c msgid "format" msgstr "format" +#: builtin/am.c msgid "format the patch(es) are in" msgstr "el format en el qual estan els pedaços" +#: builtin/am.c msgid "override error message when patch failure occurs" msgstr "sobreescriu el missatge d'error si falla l'aplicació del pedaç" +#: builtin/am.c msgid "continue applying patches after resolving a conflict" msgstr "segueix aplicant pedaços després de resoldre un conflicte" +#: builtin/am.c msgid "synonyms for --continue" msgstr "sinònims de --continue" +#: builtin/am.c msgid "skip the current patch" msgstr "omet el pedaç actual" +#: builtin/am.c msgid "restore the original branch and abort the patching operation" msgstr "restaura la branca original i interromp l'operació d'apedaçament" +#: builtin/am.c msgid "abort the patching operation but keep HEAD where it is" msgstr "interromp l'operació d'apedaçament però manté HEAD on és" +#: builtin/am.c msgid "show the patch being applied" msgstr "mostra el pedaç que s'està aplicant" +#: builtin/am.c +msgid "try to apply current patch again" +msgstr "intenta aplicar el pedaç actual de nou" + +#: builtin/am.c msgid "record the empty patch as an empty commit" msgstr "registra el pedaç buit com una comissió buida" +#: builtin/am.c msgid "lie about committer date" msgstr "menteix sobre la data del comitent" +#: builtin/am.c msgid "use current timestamp for author date" msgstr "usa la marca de temps actual per a la data d'autor" +#: builtin/am.c builtin/commit-tree.c builtin/commit.c builtin/merge.c +#: builtin/pull.c builtin/rebase.c builtin/revert.c builtin/tag.c msgid "key-id" msgstr "ID de clau" +#: builtin/am.c builtin/rebase.c msgid "GPG-sign commits" msgstr "signa les comissions amb GPG" +#: builtin/am.c msgid "how to handle empty patches" msgstr "com gestionar les comissions buides" +#: builtin/am.c msgid "(internal use for git-rebase)" msgstr "(ús intern per a git-rebase)" +#: builtin/am.c msgid "" "The -b/--binary option has been a no-op for long time, and\n" "it will be removed. Please do not use it anymore." @@ -2349,15 +2929,18 @@ msgstr "" "Fa molt que l'opció -b/--binary no fa res, i\n" "s'eliminarà. No l'useu més." +#: builtin/am.c msgid "failed to read the index" msgstr "s'ha produït un error en llegir l'índex" +#: builtin/am.c #, c-format msgid "previous rebase directory %s still exists but mbox given." msgstr "" "un directori de «rebase» anterior %s encara existeix però s'ha donat una " "bústia." +#: builtin/am.c #, c-format msgid "" "Stray %s directory found.\n" @@ -2366,34 +2949,40 @@ msgstr "" "S'ha trobat un directori %s extraviat.\n" "Useu «git am --abort» per a eliminar-lo." +#: builtin/am.c msgid "Resolve operation not in progress, we are not resuming." msgstr "Una operació de resolució no està en curs; no reprenem." +#: builtin/am.c msgid "interactive mode requires patches on the command line" msgstr "el mode interactiu requereix pedaços a la línia d'ordres" +#: builtin/apply.c msgid "git apply [<options>] [<patch>...]" msgstr "git apply [<opcions>] [<pedaç>...]" +#: builtin/archive.c diagnose.c msgid "could not redirect output" msgstr "no s'ha pogut redirigir la sortida" -msgid "git archive: Remote with no URL" -msgstr "git archive: Remot sense URL" - +#: builtin/archive.c msgid "git archive: expected ACK/NAK, got a flush packet" msgstr "git archive: s'esperava ACK/NAK, s'ha rebut un paquet de buidatge" +#: builtin/archive.c #, c-format msgid "git archive: NACK %s" msgstr "git archive: %s NACK" +#: builtin/archive.c msgid "git archive: protocol error" msgstr "git archive: error de protocol" +#: builtin/archive.c msgid "git archive: expected a flush" msgstr "git archive: s'esperava una neteja" +#: builtin/bisect.c msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2401,56 +2990,71 @@ msgstr "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" +#: builtin/bisect.c msgid "git bisect (good|bad) [<rev>...]" -msgstr "git bisect (good|bad) [<rev>...]" +msgstr "git bisect (good|bad) [<revisió>...]" +#: builtin/bisect.c msgid "git bisect skip [(<rev>|<range>)...]" -msgstr "git bisect skip [(<rev>|<range>)...]" +msgstr "git bisect skip [(<revisió>|<rang>)...]" +#: builtin/bisect.c msgid "git bisect reset [<commit>]" msgstr "git bisect reset [<comissió>]" +#: builtin/bisect.c msgid "git bisect replay <logfile>" -msgstr "git bisect replay <logfile>" +msgstr "git bisect replay " +#: builtin/bisect.c msgid "git bisect run <cmd> [<arg>...]" -msgstr "git bisect run <cmd> [<arg>...]" +msgstr "git bisect run <ordre> [<arg>...]" +#: builtin/bisect.c #, c-format msgid "cannot open file '%s' in mode '%s'" msgstr "no es pot obrir el fitxer «%s» en mode «%s»" +#: builtin/bisect.c #, c-format msgid "could not write to file '%s'" msgstr "no s'ha pogut escriure el fitxer «%s»" +#: builtin/bisect.c #, c-format msgid "cannot open file '%s' for reading" msgstr "no es pot obrir «%s» per a lectura" +#: builtin/bisect.c #, c-format msgid "'%s' is not a valid term" msgstr "«%s» no és un terme vàlid" +#: builtin/bisect.c #, c-format msgid "can't use the builtin command '%s' as a term" msgstr "no es pot usar l'ordre interna «%s» com a terme" +#: builtin/bisect.c #, c-format msgid "can't change the meaning of the term '%s'" msgstr "no es pot canviar el significat del terme «%s»" +#: builtin/bisect.c msgid "please use two different terms" msgstr "useu dos termes diferents" +#: builtin/bisect.c #, c-format msgid "We are not bisecting.\n" msgstr "No estem bisecant.\n" +#: builtin/bisect.c #, c-format msgid "'%s' is not a valid commit" msgstr "«%s» no és una comissió vàlida" +#: builtin/bisect.c #, c-format msgid "" "could not check out original HEAD '%s'. Try 'git bisect reset <commit>'." @@ -2458,22 +3062,27 @@ msgstr "" "no s'ha pogut agafar la HEAD original «%s». Proveu «git bisect reset " "<comissió>»." +#: builtin/bisect.c #, c-format msgid "Bad bisect_write argument: %s" msgstr "Argument «bisect_write» incorrecte: %s" +#: builtin/bisect.c #, c-format msgid "couldn't get the oid of the rev '%s'" msgstr "no s'ha pogut obtenir l'oid de la revisió «%s»" +#: builtin/bisect.c #, c-format msgid "couldn't open the file '%s'" msgstr "no s'ha pogut obrir el fitxer «%s»" +#: builtin/bisect.c #, c-format msgid "Invalid command: you're currently in a %s/%s bisect" msgstr "Ordre no vàlida: esteu actualment en una bisecció %s/%s" +#: builtin/bisect.c #, c-format msgid "" "You need to give me at least one %s and %s revision.\n" @@ -2482,6 +3091,7 @@ msgstr "" "Heu de donar com a mínim un %s i una revisió %s.\n" "Podeu usar «git bisect %s» i «git bisect %s» per a això." +#: builtin/bisect.c #, c-format msgid "" "You need to start by \"git bisect start\".\n" @@ -2492,6 +3102,7 @@ msgstr "" "Heu de donar com a mínim un %s i una revisió %s.\n" "Podeu usar «git bisect %s» i «git bisect %s» per a això." +#: builtin/bisect.c #, c-format msgid "bisecting only with a %s commit" msgstr "bisecant amb només una comissió %s" @@ -2500,12 +3111,15 @@ msgstr "bisecant amb només una comissió %s" #. translation. The program will only accept English input #. at this point. #. +#: builtin/bisect.c msgid "Are you sure [Y/n]? " msgstr "N'esteu segur [Y/n]? " +#: builtin/bisect.c msgid "status: waiting for both good and bad commits\n" msgstr "estat: s'estan esperant les comissions bones i dolentes\n" +#: builtin/bisect.c #, c-format msgid "status: waiting for bad commit, %d good commit known\n" msgid_plural "status: waiting for bad commit, %d good commits known\n" @@ -2515,13 +3129,16 @@ msgstr[1] "" "estat: s'està esperant una comissió incorrecta, es coneixen %d comissions " "bones\n" +#: builtin/bisect.c msgid "status: waiting for good commit(s), bad commit known\n" msgstr "" "estat: s'està esperant comissions bones, es coneix una comissió incorrecta\n" +#: builtin/bisect.c msgid "no terms defined" msgstr "cap terme definit" +#: builtin/bisect.c #, c-format msgid "" "Your current terms are %s for the old state\n" @@ -2530,6 +3147,7 @@ msgstr "" "Els termes actuals són %s per a l'estat antic\n" "i %s per al nou estat.\n" +#: builtin/bisect.c #, c-format msgid "" "invalid argument %s for 'git bisect terms'.\n" @@ -2538,39 +3156,45 @@ msgstr "" "argument no vàlid %s per a «git bisect terms».\n" "Les opcions admeses són: --term-good|--term-old i --term-bad|--term-new." -msgid "revision walk setup failed\n" -msgstr "la configuració del recorregut de revisions ha fallat\n" - +#: builtin/bisect.c #, c-format msgid "could not open '%s' for appending" msgstr "no s'ha pogut obrir «%s» per a afegir-hi" +#: builtin/bisect.c msgid "'' is not a valid term" msgstr "«%s» no és un terme vàlid" +#: builtin/bisect.c #, c-format msgid "unrecognized option: '%s'" msgstr "opció no reconeguda: «%s»" +#: builtin/bisect.c #, c-format msgid "'%s' does not appear to be a valid revision" msgstr "«%s» no sembla ser una revisió vàlida" +#: builtin/bisect.c msgid "bad HEAD - I need a HEAD" msgstr "HEAD incorrecte - cal una HEAD" +#: builtin/bisect.c #, c-format msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'." msgstr "" "l'agafament de «%s» ha fallat. Proveu «git bisect start <branca-vàlida>»." +#: builtin/bisect.c msgid "bad HEAD - strange symbolic ref" msgstr "HEAD incorrecte - referència simbòlica estranya" +#: builtin/bisect.c #, c-format msgid "invalid ref: '%s'" msgstr "referència no és vàlida: «%s»" +#: builtin/bisect.c msgid "You need to start by \"git bisect start\"\n" msgstr "Cal començar per «git bisect start»\n" @@ -2578,215 +3202,278 @@ msgstr "Cal començar per «git bisect start»\n" #. translation. The program will only accept English input #. at this point. #. +#: builtin/bisect.c msgid "Do you want me to do it for you [Y/n]? " msgstr "Voleu que ho faci per vostè [Y/n]? " +#: builtin/bisect.c msgid "Please call `--bisect-state` with at least one argument" msgstr "Executeu «--bisect-state» amb almenys un argument" +#: builtin/bisect.c #, c-format msgid "'git bisect %s' can take only one argument." msgstr "«git bisect %s» només pot acceptar un argument." +#: builtin/bisect.c #, c-format msgid "Bad rev input: %s" msgstr "Entrada amb revisió errònia: %s" +#: builtin/bisect.c #, c-format msgid "Bad rev input (not a commit): %s" msgstr "Entrada de revisió errònia (no és una comissió): %s" +#: builtin/bisect.c msgid "We are not bisecting." msgstr "No estem bisecant." +#: builtin/bisect.c #, c-format msgid "'%s'?? what are you talking about?" msgstr "«%s»? Què voleu dir?" +#: builtin/bisect.c #, c-format msgid "cannot read file '%s' for replaying" msgstr "no es pot llegir «%s» per a reproducció" +#: builtin/bisect.c #, c-format msgid "running %s\n" msgstr "s'està executant %s\n" +#: builtin/bisect.c msgid "bisect run failed: no command provided." msgstr "ha fallat l'execució de bisect: no s'ha proporcionat cap ordre." +#: builtin/bisect.c #, c-format msgid "unable to verify %s on good revision" msgstr "no s'ha pogut verificar «%s» en una bona revisió" +#: builtin/bisect.c #, c-format msgid "bogus exit code %d for good revision" msgstr "codi d'error de sortida %d per a una bona revisió" +#: builtin/bisect.c #, c-format msgid "bisect run failed: exit code %d from %s is < 0 or >= 128" msgstr "" "l'execució de la de bisecció ha fallat: codi de sortida %d de %s és < 0 o >= " "128" +#: builtin/bisect.c #, c-format msgid "cannot open file '%s' for writing" msgstr "no es pot obrir «%s» per a escriptura" +#: builtin/bisect.c msgid "bisect run cannot continue any more" msgstr "l'execució de la bisecció no pot continuar més" +#: builtin/bisect.c msgid "bisect run success" msgstr "execució de bisecció amb èxit" +#: builtin/bisect.c msgid "bisect found first bad commit" msgstr "la bisecció ha trobat una primera comissió errònia" +#: builtin/bisect.c #, c-format msgid "bisect run failed: 'git bisect %s' exited with error code %d" msgstr "" "ha fallat l'execució del bisect: «git bisect %s» ha sortit amb el codi " "d'error %d" +#: builtin/bisect.c #, c-format msgid "'%s' requires either no argument or a commit" msgstr "«%s» no requereix cap argument ni comissió" +#: builtin/bisect.c #, c-format msgid "'%s' requires 0 or 1 argument" msgstr "%s requereix 0 o 1 arguments" +#: builtin/bisect.c #, c-format msgid "'%s' requires 0 arguments" msgstr "«%s» requereix 0 arguments" +#: builtin/bisect.c msgid "no logfile given" msgstr "no s'ha donat cap fitxer de registre" +#: builtin/bisect.c #, c-format msgid "'%s' failed: no command provided." msgstr "«%s» ha fallat: no s'ha proporcionat cap ordre." +#: builtin/bisect.c msgid "need a command" msgstr "cal una subordre" +#: builtin/bisect.c builtin/cat-file.c #, c-format msgid "unknown command: '%s'" msgstr "ordre desconeguda: «%s»" +#: builtin/blame.c msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>" -msgstr "git blame [<opcions>] [<opcions-de-revisió>] [<revisió>] [--] fitxer" +msgstr "git blame [<opcions>] [<opcions-revisió>] [<revisió>] [--] fitxer" +#: builtin/blame.c msgid "git annotate [<options>] [<rev-opts>] [<rev>] [--] <file>" -msgstr "git annotate [<opcions>] [<rev-opts>] [<rev>] [--] <fitxer>" +msgstr "git annotate [<opcions>] [<opcions-revisió>] [<rev>] [--] <fitxer>" +#: builtin/blame.c msgid "<rev-opts> are documented in git-rev-list(1)" -msgstr "es documenten les <opcions-de-revisió> en git-rev-list(1)" +msgstr "es documenten les <opcions-revisió> en git-rev-list(1)" +#: builtin/blame.c #, c-format msgid "expecting a color: %s" msgstr "s'esperava un color: %s" +#: builtin/blame.c msgid "must end with a color" msgstr "ha d'acabar amb un color" +#: builtin/blame.c #, c-format msgid "cannot find revision %s to ignore" msgstr "no s'ha pogut trobar la revisió %s a ignorar" +#: builtin/blame.c msgid "show blame entries as we find them, incrementally" msgstr "mostra les entrades «blame» mentre les trobem, incrementalment" +#: builtin/blame.c msgid "do not show object names of boundary commits (Default: off)" msgstr "" "no mostris els noms d'objectes de les comissions de frontera (per defecte: " "desactivat)" +#: builtin/blame.c msgid "do not treat root commits as boundaries (Default: off)" msgstr "" "no tractis les comissions arrel com de frontera (per defecte: desactivat)" +#: builtin/blame.c msgid "show work cost statistics" msgstr "mostra les estadístiques del cost de treball" +#: builtin/blame.c builtin/checkout.c builtin/clone.c builtin/commit-graph.c +#: builtin/fetch.c builtin/merge.c builtin/multi-pack-index.c builtin/pull.c +#: builtin/push.c builtin/remote.c builtin/send-pack.c msgid "force progress reporting" msgstr "força l'informe de progrés" +#: builtin/blame.c msgid "show output score for blame entries" msgstr "mostra la puntuació de sortida de les entrades «blame»" +#: builtin/blame.c msgid "show original filename (Default: auto)" msgstr "mostra el nom de fitxer original (per defecte: automàtic)" +#: builtin/blame.c msgid "show original linenumber (Default: off)" msgstr "mostra el número de línia original (per defecte: desactivat)" +#: builtin/blame.c msgid "show in a format designed for machine consumption" msgstr "presenta en un format dissenyat per a ser consumit per una màquina" +#: builtin/blame.c msgid "show porcelain format with per-line commit information" msgstr "mostra en format de porcellana amb informació de comissió per línia" +#: builtin/blame.c msgid "use the same output mode as git-annotate (Default: off)" msgstr "" "usa el mateix mode de sortida que git-annotate (per defecte: desactivat)" +#: builtin/blame.c msgid "show raw timestamp (Default: off)" msgstr "mostra la marca de temps en cru (per defecte: desactivat)" +#: builtin/blame.c msgid "show long commit SHA1 (Default: off)" msgstr "mostra l'SHA1 de la comissió en format llarg (per defecte: desactivat)" +#: builtin/blame.c msgid "suppress author name and timestamp (Default: off)" msgstr "omet el nom d'autor i la marca de temps (per defecte: desactivat)" +#: builtin/blame.c msgid "show author email instead of name (Default: off)" msgstr "" "mostra el correu electrònic de l'autor en comptes del nom (per defecte: " "desactivat)" +#: builtin/blame.c msgid "ignore whitespace differences" msgstr "ignora les diferències d'espai en blanc" +#: builtin/blame.c builtin/log.c msgid "rev" msgstr "rev" +#: builtin/blame.c msgid "ignore <rev> when blaming" -msgstr "ignora <rev> en fer «blame»" +msgstr "ignora ñ- en fer «blame»" +#: builtin/blame.c msgid "ignore revisions from <file>" msgstr "ignora les revisions de <fitxer>" +#: builtin/blame.c msgid "color redundant metadata from previous line differently" msgstr "" "acoloreix les metadades redundants de la línia anterior de manera diferent" +#: builtin/blame.c msgid "color lines by age" msgstr "acoloreix les línies per antiguitat" +#: builtin/blame.c msgid "spend extra cycles to find better match" msgstr "gasta cicles extres per a trobar una coincidència millor" +#: builtin/blame.c msgid "use revisions from <file> instead of calling git-rev-list" msgstr "usa les revisions de <fitxer> en lloc d'invocar git-rev-list" +#: builtin/blame.c msgid "use <file>'s contents as the final image" msgstr "usa els continguts de <fitxer> com a la imatge final" +#: builtin/blame.c msgid "score" msgstr "puntuació" +#: builtin/blame.c msgid "find line copies within and across files" msgstr "troba còpies de línia dins i a través dels fitxers" +#: builtin/blame.c msgid "find line movements within and across files" msgstr "troba moviments de línia dins i a través dels fitxers" +#: builtin/blame.c msgid "range" msgstr "rang" +#: builtin/blame.c msgid "process only line range <start>,<end> or function :<funcname>" -msgstr "processa només el rang <start>,<end> o la funció :<funcname>" +msgstr "processa només el rang <inici>,<final> o la funció :<nom-funció>" +#: builtin/blame.c msgid "--progress can't be used with --incremental or porcelain formats" msgstr "" "no es pot usar --progress amb els formats --incremental o de porcellana" @@ -2799,21 +3486,26 @@ msgstr "" #. your language may need more or fewer display #. columns. #. +#: builtin/blame.c msgid "4 years, 11 months ago" msgstr "fa 4 anys i 11 mesos" +#: builtin/blame.c #, c-format msgid "file %s has only %lu line" msgid_plural "file %s has only %lu lines" msgstr[0] "el fitxer %s té només %lu línia" msgstr[1] "el fitxer %s té només %lu línies" +#: builtin/blame.c msgid "Blaming lines" msgstr "S'està fent un «blame»" +#: builtin/branch.c msgid "git branch [<options>] [-r | -a] [--merged] [--no-merged]" msgstr "git branch [<opcions>] [-r | -a] [--merged | --no-merged]" +#: builtin/branch.c msgid "" "git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-" "point>]" @@ -2821,24 +3513,31 @@ msgstr "" "git branch [<opcions>] [-f] [--recurse-submodules] <branch-name> [<start-" "point>]" +#: builtin/branch.c msgid "git branch [<options>] [-l] [<pattern>...]" msgstr "git branch [<opcions>] [-l] [<patró>...]" +#: builtin/branch.c msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..." msgstr "git branch [<opcions>] [-r] (-d | -D) <nom-de-branca>..." +#: builtin/branch.c msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>" msgstr "git branch [<opcions>] (-m | -M) [<branca-antiga>] <branca-nova>" +#: builtin/branch.c msgid "git branch [<options>] (-c | -C) [<old-branch>] <new-branch>" msgstr "git branch [<opcions>] (-c | -C) [<branca-antiga>] <branca-nova>" +#: builtin/branch.c msgid "git branch [<options>] [-r | -a] [--points-at]" msgstr "git branch [<opcions>] [-r | -a] [--points-at]" +#: builtin/branch.c msgid "git branch [<options>] [-r | -a] [--format]" msgstr "git branch [<opcions>] [-r | -a] [--format]" +#: builtin/branch.c #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -2847,6 +3546,7 @@ msgstr "" "s'està suprimint la branca «%s» que s'ha fusionat a\n" " «%s», però encara no s'ha fusionat a HEAD" +#: builtin/branch.c #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -2855,33 +3555,41 @@ msgstr "" "no s'està suprimint la branca «%s» que encara no s'ha fusionat a\n" " «%s», encara que s'hagi fusionat a HEAD" +#: builtin/branch.c #, c-format msgid "couldn't look up commit object for '%s'" msgstr "no s'ha pogut cercar l'objecte de comissió per a «%s»" +#: builtin/branch.c #, c-format msgid "the branch '%s' is not fully merged" msgstr "la branca «%s» no està completament fusionada" +#: builtin/branch.c #, 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»" +#: builtin/branch.c msgid "update of config-file failed" msgstr "ha fallat l'actualització del fitxer de configuració" +#: builtin/branch.c msgid "cannot use -a with -d" msgstr "no es pot usar -a amb -d" +#: builtin/branch.c #, c-format 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»" +#: builtin/branch.c #, c-format msgid "remote-tracking branch '%s' not found" msgstr "no s'ha trobat la branca de seguiment remot «%s»" +#: builtin/branch.c #, c-format msgid "" "branch '%s' not found.\n" @@ -2890,198 +3598,257 @@ msgstr "" "no s'ha trobat la branca «%s».\n" "Us heu oblidat de --remote?" +#: builtin/branch.c #, c-format msgid "branch '%s' not found" msgstr "no s'ha trobat la branca «%s»" +#: builtin/branch.c #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" msgstr "S'ha suprimit la branca amb seguiment remot %s (era %s).\n" +#: builtin/branch.c #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "S'ha suprimit la branca %s (era %s).\n" +#: builtin/branch.c builtin/tag.c msgid "unable to parse format string" msgstr "no s'ha pogut analitzar la cadena de format" +#: builtin/branch.c msgid "could not resolve HEAD" msgstr "no s'ha pogut resoldre HEAD" +#: builtin/branch.c #, c-format msgid "HEAD (%s) points outside of refs/heads/" msgstr "HEAD (%s) apunta fora de refs/heads/" +#: builtin/branch.c #, c-format msgid "branch %s is being rebased at %s" msgstr "a la branca %s se li està fent a «rebase» a %s" +#: builtin/branch.c #, c-format msgid "branch %s is being bisected at %s" msgstr "la branca %s s'està bisecant a %s" +#: builtin/branch.c #, c-format msgid "HEAD of working tree %s is not updated" msgstr "HEAD de l'arbre de treball %s no està actualitzat" +#: builtin/branch.c #, c-format msgid "invalid branch name: '%s'" msgstr "el nom de la branca no és vàlid: «%s»" +#: builtin/branch.c #, c-format msgid "no commit on branch '%s' yet" msgstr "encara no hi ha cap comissió a la branca «%s»" +#: builtin/branch.c #, c-format msgid "no branch named '%s'" msgstr "no hi ha cap branca anomenada «%s»" +#: builtin/branch.c msgid "branch rename failed" msgstr "ha fallat el canvi de nom de la branca" +#: builtin/branch.c msgid "branch copy failed" msgstr "ha fallat la còpia de la branca" +#: builtin/branch.c #, c-format msgid "created a copy of a misnamed branch '%s'" msgstr "s'ha creat una còpia d'una branca mal anomenada «%s»" +#: builtin/branch.c #, c-format msgid "renamed a misnamed branch '%s' away" msgstr "s'ha canviat el nom d'una branca «%s» mal anomenada" +#: builtin/branch.c #, 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 s'ha actualitzat" +#: builtin/branch.c msgid "branch is renamed, but update of config-file failed" msgstr "" "s'ha canviat el nom de la branca, però ha fallat l'actualització del fitxer " "de configuració" +#: builtin/branch.c msgid "branch is copied, but update of config-file failed" msgstr "" "s'ha copiat la branca, però ha fallat l'actualització del fitxer de " "configuració" +#: builtin/branch.c #, c-format msgid "" "Please edit the description for the branch\n" " %s\n" -"Lines starting with '%c' will be stripped.\n" +"Lines starting with '%s' will be stripped.\n" msgstr "" "Editeu la descripció de la branca\n" " %s\n" -"S'eliminaran les línies que comencin amb «%c».\n" +"S'eliminaran les línies que comencin amb «%s».\n" +"\"\n" +#: builtin/branch.c msgid "Generic options" msgstr "Opcions genèriques" +#: builtin/branch.c msgid "show hash and subject, give twice for upstream branch" msgstr "mostra el hash i l'assumpte, useu-lo dues vegades per a la branca font" +#: builtin/branch.c msgid "suppress informational messages" msgstr "omet els missatges informatius" +#: builtin/branch.c builtin/checkout.c builtin/submodule--helper.c msgid "set branch tracking configuration" msgstr "estableix la configuració del seguiment de la branca" +#: builtin/branch.c msgid "do not use" msgstr "no usar" +#: builtin/branch.c msgid "upstream" msgstr "font" +#: builtin/branch.c msgid "change the upstream info" msgstr "canvia la informació de font" +#: builtin/branch.c msgid "unset the upstream info" msgstr "treu la informació de la font" +#: builtin/branch.c msgid "use colored output" msgstr "usa sortida amb colors" +#: builtin/branch.c msgid "act on remote-tracking branches" msgstr "actua en branques amb seguiment remot" +#: builtin/branch.c msgid "print only branches that contain the commit" msgstr "imprimeix només les branques que continguin la comissió" +#: builtin/branch.c msgid "print only branches that don't contain the commit" msgstr "imprimeix només les branques que no continguin la comissió" +#: builtin/branch.c msgid "Specific git-branch actions:" msgstr "Accions de git-branch específiques:" +#: builtin/branch.c msgid "list both remote-tracking and local branches" msgstr "llista les branques amb seguiment remot i les locals" +#: builtin/branch.c msgid "delete fully merged branch" msgstr "suprimeix la branca si està completament fusionada" +#: builtin/branch.c msgid "delete branch (even if not merged)" msgstr "suprimeix la branca (encara que no estigui fusionada)" +#: builtin/branch.c msgid "move/rename a branch and its reflog" -msgstr "mou/canvia de nom una branca i el seu registre de referència" +msgstr "mou/canvia de nom una branca i el seu registre de referències" +#: builtin/branch.c msgid "move/rename a branch, even if target exists" msgstr "mou/canvia de nom una branca, encara que el destí existeixi" +#: builtin/branch.c builtin/for-each-ref.c builtin/tag.c msgid "do not output a newline after empty formatted refs" msgstr "no emetis cap línia nova després de refs amb format buit" +#: builtin/branch.c msgid "copy a branch and its reflog" -msgstr "copia una branca i el seu registre de referència" +msgstr "copia una branca i el seu registre de referències" +#: builtin/branch.c msgid "copy a branch, even if target exists" msgstr "copia una branca, encara que el destí existeixi" +#: builtin/branch.c msgid "list branch names" msgstr "llista els noms de branca" +#: builtin/branch.c msgid "show current branch name" msgstr "mostra el nom de la branca actual" +#: builtin/branch.c builtin/submodule--helper.c msgid "create the branch's reflog" -msgstr "crea el registre de referència de la branca" +msgstr "crea el registre de referències de la branca" +#: builtin/branch.c msgid "edit the description for the branch" msgstr "edita la descripció de la branca" +#: builtin/branch.c msgid "force creation, move/rename, deletion" msgstr "força creació, moviment/canvi de nom, supressió" +#: builtin/branch.c msgid "print only branches that are merged" msgstr "imprimeix només les branques que s'han fusionat" +#: builtin/branch.c msgid "print only branches that are not merged" msgstr "imprimeix només les branques que no s'han fusionat" +#: builtin/branch.c msgid "list branches in columns" msgstr "llista les branques en columnes" +#: builtin/branch.c builtin/for-each-ref.c builtin/notes.c builtin/tag.c msgid "object" msgstr "objecte" +#: builtin/branch.c msgid "print only branches of the object" msgstr "imprimeix només les branques de l'objecte" +#: builtin/branch.c builtin/for-each-ref.c builtin/tag.c msgid "sorting and filtering are case insensitive" msgstr "ordenació i filtratge distingeixen entre majúscules i minúscules" +#: builtin/branch.c builtin/ls-files.c msgid "recurse through submodules" msgstr "inclou recursivament els submòduls" +#: builtin/branch.c builtin/for-each-ref.c builtin/ls-files.c builtin/ls-tree.c +#: builtin/tag.c builtin/verify-tag.c msgid "format to use for the output" msgstr "format a usar en la sortida" +#: builtin/branch.c msgid "failed to resolve HEAD as a valid ref" msgstr "no s'ha pogut resoldre HEAD com a referència vàlida" +#: builtin/branch.c builtin/clone.c msgid "HEAD not found below refs/heads!" msgstr "HEAD no trobat sota refs/heads!" +#: builtin/branch.c msgid "" "branch with --recurse-submodules can only be used if submodule." "propagateBranches is enabled" @@ -3089,58 +3856,74 @@ msgstr "" "la branca amb --recurse-submodules només es pot utilitzar si submodule." "propagateBranches està habilitat" +#: builtin/branch.c msgid "--recurse-submodules can only be used to create branches" msgstr "--recurse-submodules només es pot utilitzar per a crear branques" +#: builtin/branch.c msgid "branch name required" msgstr "cal el nom de branca" +#: builtin/branch.c msgid "cannot give description to detached HEAD" msgstr "no s'ha pogut donar la descripció al HEAD separat" +#: builtin/branch.c msgid "cannot edit description of more than one branch" msgstr "no es pot editar la descripció de més d'una branca" +#: builtin/branch.c msgid "cannot copy the current branch while not on any" msgstr "no es pot copiar la branca actual mentre no pertanyi a cap" +#: builtin/branch.c 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" +#: builtin/branch.c msgid "too many branches for a copy operation" msgstr "hi ha massa branques per a una operació de còpia" +#: builtin/branch.c msgid "too many arguments for a rename operation" msgstr "hi ha massa arguments per a una operació de canvi de nom" +#: builtin/branch.c msgid "too many arguments to set new upstream" msgstr "hi ha massa arguments per a establir una nova font" +#: builtin/branch.c #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch" msgstr "" "no s'ha pogut configurar la font de HEAD a %s quan no apunta a cap branca" +#: builtin/branch.c #, c-format msgid "no such branch '%s'" msgstr "no existeix la branca «%s»" +#: builtin/branch.c #, c-format msgid "branch '%s' does not exist" msgstr "la branca «%s» no existeix" +#: builtin/branch.c msgid "too many arguments to unset upstream" msgstr "hi ha massa arguments per a desassignar la font" +#: builtin/branch.c 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" +#: builtin/branch.c #, c-format msgid "branch '%s' has no upstream information" msgstr "la branca «%s» no té informació de la font" +#: builtin/branch.c msgid "" "the -a, and -r, options to 'git branch' do not take a branch name.\n" "Did you mean to use: -a|-r --list <pattern>?" @@ -3148,6 +3931,7 @@ msgstr "" "les opcions -a, i -r, a «git branch» no prenen un nom de branca.\n" "Volíeu utilitzar: -a|-r --list <patró>?" +#: builtin/branch.c msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " "'--set-upstream-to' instead" @@ -3155,30 +3939,39 @@ msgstr "" "l'opció «--set-upstream» ja no és admesa. Utilitzeu en comptes «--track» o " "«--set-upstream-to»" +#: builtin/bugreport.c msgid "git version:\n" msgstr "versió de git:\n" +#: builtin/bugreport.c #, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "uname() ha fallat amb l'error «%s» (%d)\n" +#: builtin/bugreport.c msgid "compiler info: " msgstr "informació del compilador: " +#: builtin/bugreport.c msgid "libc info: " msgstr "informació de la libc: " +#: builtin/bugreport.c msgid "not run from a git repository - no hooks to show\n" msgstr "" "no s'està executant en un repositori de git - no hi ha lligams a mostrar\n" +#: builtin/bugreport.c msgid "" -"git bugreport [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n" +"git bugreport [(-o | --output-directory) <path>]\n" +" [(-s | --suffix) <format> | --no-suffix]\n" " [--diagnose[=<mode>]]" msgstr "" -"git bugreport [(-o | --output-directory) <camí>] [(-s | --suffix) <format>]\n" +"git bugreport [(-o | --output-directory) <path>]\n" +" [(-s | --suffix) <format> | --no-suffix]\n" " [--diagnose[=<mode>]]" +#: builtin/bugreport.c msgid "" "Thank you for filling out a Git bug report!\n" "Please answer the following questions to help us understand your issue.\n" @@ -3212,46 +4005,59 @@ msgstr "" "Reviseu la resta de l'informe d'error de sota.\n" "Podeu eliminar qualsevol línia que vulgueu.\n" +#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c +#: parse-options.h msgid "mode" msgstr "mode" +#: builtin/bugreport.c msgid "" "create an additional zip archive of detailed diagnostics (default 'stats')" msgstr "" "crea un arxiu zip addicional amb diagnòstics detallats (per defecte «stats»)" +#: builtin/bugreport.c msgid "specify a destination for the bugreport file(s)" msgstr "especifiqueu una destinació per al fitxer de l'informe d'error" +#: builtin/bugreport.c msgid "specify a strftime format suffix for the filename(s)" msgstr "especifiqueu un sufix en format strftime per al nom de fitxer" +#: builtin/bugreport.c #, c-format msgid "unknown argument `%s'" msgstr "argument desconegut «%s»" +#: builtin/bugreport.c builtin/diagnose.c #, c-format msgid "could not create leading directories for '%s'" msgstr "no s'han pogut crear els directoris principals de «%s»" +#: builtin/bugreport.c builtin/diagnose.c #, c-format msgid "unable to create diagnostics archive %s" msgstr "no s'ha pogut crear l'arxiu de diagnòstic %s" +#: builtin/bugreport.c msgid "System Info" msgstr "Informació del sistema" +#: builtin/bugreport.c msgid "Enabled Hooks" msgstr "Habilita els lligams" +#: builtin/bugreport.c #, c-format msgid "unable to write to %s" msgstr "no s'ha pogut escriure a %s" +#: builtin/bugreport.c #, c-format msgid "Created new report at '%s'.\n" msgstr "S'ha creat un nou informe a «%s».\n" +#: builtin/bundle.c msgid "" "git bundle create [-q | --quiet | --progress]\n" " [--version=<version>] <file> <git-rev-list-args>" @@ -3259,83 +4065,112 @@ msgstr "" "git bundle create [-q | --quiet | --progress]\n" " [--version=<versió>] <fitxer> <git-rev-list-args>" +#: builtin/bundle.c msgid "git bundle verify [-q | --quiet] <file>" msgstr "git bundle verify [-q | --quiet] <fitxer>" +#: builtin/bundle.c msgid "git bundle list-heads <file> [<refname>...]" -msgstr "git bundle list-heads <fitxer> [<refname>...]" +msgstr "git bundle list-heads <fitxer> [<nom-referència>...]" +#: builtin/bundle.c msgid "git bundle unbundle [--progress] <file> [<refname>...]" -msgstr "git bundle unbundle [--progress] <fitxer> [<refname>...]" +msgstr "git bundle unbundle [--progress] <fitxer> [<nom-referència>...]" +#: builtin/bundle.c msgid "need a <file> argument" msgstr "necessita un argument <fitxer>" +#: builtin/bundle.c builtin/pack-objects.c msgid "do not show progress meter" msgstr "no mostris l'indicador de progrés" +#: builtin/bundle.c builtin/pack-objects.c msgid "show progress meter" msgstr "mostra l'indicador de progrés" +#: builtin/bundle.c msgid "historical; same as --progress" msgstr "històric; el mateix que --progress" +#: builtin/bundle.c msgid "historical; does nothing" msgstr "històric; no fa res" +#: builtin/bundle.c msgid "specify bundle format version" msgstr "especifica la versió del format del farcell" +#: builtin/bundle.c msgid "Need a repository to create a bundle." msgstr "Cal un repositori per a crear un farcell." +#: builtin/bundle.c msgid "do not show bundle details" msgstr "no mostris els detalls del farcell" +#: builtin/bundle.c bundle.c +msgid "need a repository to verify a bundle" +msgstr "cal un repositori per a verificar un farcell" + +#: builtin/bundle.c #, c-format msgid "%s is okay\n" msgstr "%s està bé\n" +#: builtin/bundle.c msgid "Need a repository to unbundle." msgstr "Cal un repositori per a desfer un farcell." +#: builtin/bundle.c msgid "Unbundling objects" msgstr "S'estan desagrupant objectes" +#: builtin/cat-file.c merge-recursive.c #, c-format msgid "cannot read object %s '%s'" msgstr "no es pot llegir l'objecte %s «%s»" +#: builtin/cat-file.c msgid "flush is only for --buffer mode" msgstr "flush només és per al mode --buffer" +#: builtin/cat-file.c msgid "empty command in input" msgstr "ordre buida en l'entrada" +#: builtin/cat-file.c #, c-format msgid "whitespace before command: '%s'" msgstr "espai en blanc abans de l'ordre: «%s»" +#: builtin/cat-file.c #, c-format msgid "%s requires arguments" msgstr "%s requereix arguments" +#: builtin/cat-file.c #, c-format msgid "%s takes no arguments" -msgstr "%s no accepta cap valor" +msgstr "%s no accepta arguments" +#: builtin/cat-file.c msgid "only one batch option may be specified" msgstr "només es pot especificar una opció per lots" +#: builtin/cat-file.c msgid "git cat-file <type> <object>" msgstr "git cat-file <tipus> <objecte>" +#: builtin/cat-file.c msgid "git cat-file (-e | -p) <object>" msgstr "git cat-file (-e | -p) <objecte>" +#: builtin/cat-file.c msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objecte>" +#: builtin/cat-file.c msgid "" "git cat-file (--textconv | --filters)\n" " [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" @@ -3343,6 +4178,7 @@ 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" @@ -3354,114 +4190,147 @@ msgstr "" " [--buffer] [--follow-symlinks] [--unordered]\n" " [--textconv | --filters] [-Z]" +#: builtin/cat-file.c msgid "Check object existence or emit object contents" msgstr "Comprova l'existència de l'objecte o emet el contingut de l'objecte" +#: builtin/cat-file.c msgid "check if <object> exists" msgstr "comprova si <objecte> existeix" +#: builtin/cat-file.c msgid "pretty-print <object> content" msgstr "impressió embellida del contingut de l'<objecte>" +#: builtin/cat-file.c msgid "Emit [broken] object attributes" msgstr "Emet els atributs [broken] de l'objecte" +#: builtin/cat-file.c msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)" msgstr "" "mostra el tipus d'objecte (un dels següents: «blob», «tree», «commit», " "«tag», ...)" +#: builtin/cat-file.c msgid "show object size" msgstr "mostra la mida de l'objecte" +#: builtin/cat-file.c msgid "allow -s and -t to work with broken/corrupt objects" msgstr "permet que -s i -t funcionin amb objectes trencats/malmesos" +#: builtin/cat-file.c builtin/log.c msgid "use mail map file" msgstr "usa el fitxer de mapa de correu" +#: builtin/cat-file.c msgid "Batch objects requested on stdin (or --batch-all-objects)" msgstr "Objectes de lots sol·licitats a stdin (o --batch-all-objects)" +#: builtin/cat-file.c msgid "show full <object> or <rev> contents" msgstr "mostra el contingut complet de <objecte> o <rev>" +#: builtin/cat-file.c msgid "like --batch, but don't emit <contents>" msgstr "com a --batch, però no emetis <contents>" +#: builtin/cat-file.c msgid "stdin is NUL-terminated" msgstr "l'entrada és acabada amb NUL" +#: builtin/cat-file.c msgid "stdin and stdout is NUL-terminated" msgstr "stdin i stdout estan terminats amb NUL" +#: builtin/cat-file.c msgid "read commands from stdin" msgstr "llegeix les ordres de stdin" +#: builtin/cat-file.c msgid "with --batch[-check]: ignores stdin, batches all known objects" msgstr "" "amb --batch[-check]: ignora stdin, posa en lots tots els objectes coneguts" +#: builtin/cat-file.c msgid "Change or optimize batch output" msgstr "Canvia o optimitza la sortida per lots" +#: builtin/cat-file.c msgid "buffer --batch output" msgstr "posa la sortida de --batch en memòria intermèdia" +#: builtin/cat-file.c msgid "follow in-tree symlinks" msgstr "segueix els enllaços simbòlics en l'arbre" +#: builtin/cat-file.c msgid "do not order objects before emitting them" msgstr "no ordenis els objectes abans d'emetre'ls" +#: builtin/cat-file.c msgid "" "Emit object (blob or tree) with conversion or filter (stand-alone, or with " "batch)" msgstr "" "Emet l'objecte (blob o arbre) amb conversió o filtre (stand-alone, o amb lot)" +#: builtin/cat-file.c msgid "run textconv on object's content" msgstr "executar textconv al contingut de l'objecte" +#: builtin/cat-file.c msgid "run filters on object's content" msgstr "executa els filtres al contingut de l'objecte" +#: builtin/cat-file.c msgid "blob|tree" msgstr "blob|tree" +#: builtin/cat-file.c msgid "use a <path> for (--textconv | --filters); Not with 'batch'" msgstr "useu un <camí> per a (--textconv | --filters); no amb «batch»" +#: builtin/cat-file.c #, c-format msgid "'%s=<%s>' needs '%s' or '%s'" msgstr "«%s=<%s>» necessita «%s» o «%s»" +#: builtin/cat-file.c msgid "path|tree-ish" msgstr "path|tree-ish" +#: builtin/cat-file.c #, c-format msgid "'%s' requires a batch mode" msgstr "«%s» requereix un mode batch" +#: builtin/cat-file.c #, c-format msgid "'-%c' is incompatible with batch mode" msgstr "«-%c» és incompatible amb el model batch" +#: builtin/cat-file.c msgid "batch modes take no arguments" msgstr "el mode batch no accepta cap argument" +#: builtin/cat-file.c #, c-format msgid "<rev> required with '%s'" msgstr "<rev> requerida amb «%s»" +#: builtin/cat-file.c #, c-format msgid "<object> required with '-%c'" msgstr "<objecte> requerit amb «-%c»" +#: builtin/cat-file.c #, c-format msgid "only two arguments allowed in <type> <object> mode, not %d" msgstr "només es permeten dos arguments en el mode <tipus> <objecte>, no %d" +#: builtin/check-attr.c msgid "" "git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] " "<pathname>..." @@ -3469,198 +4338,269 @@ msgstr "" "git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] " "<pathname>..." +#: builtin/check-attr.c msgid "" "git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]" msgstr "" "git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]" +#: builtin/check-attr.c msgid "report all attributes set on file" msgstr "informa de tots els atributs establerts en el fitxer" +#: builtin/check-attr.c msgid "use .gitattributes only from the index" msgstr "usa .gitattributes només des de l'índex" +#: builtin/check-attr.c builtin/check-ignore.c builtin/hash-object.c msgid "read file names from stdin" msgstr "llegeix els noms de fitxer de stdin" +#: builtin/check-attr.c builtin/check-ignore.c msgid "terminate input and output records by a NUL character" msgstr "acaba els registres d'entrada i de sortida amb un caràcter NUL" +#: builtin/check-attr.c msgid "<tree-ish>" msgstr "<tree-ish>" +#: builtin/check-attr.c msgid "which tree-ish to check attributes at" msgstr "a quin tree-ish s'han de comprovar els atributs" +#: builtin/check-ignore.c builtin/checkout.c builtin/gc.c builtin/worktree.c msgid "suppress progress reporting" msgstr "omet els informes de progrés" +#: builtin/check-ignore.c msgid "show non-matching input paths" msgstr "mostra els camins d'entrada que no coincideixin" +#: builtin/check-ignore.c msgid "ignore index when checking" msgstr "ignora l'índex en comprovar" +#: builtin/check-ignore.c msgid "cannot specify pathnames with --stdin" msgstr "no es poden especificar noms de camí amb --stdin" +#: builtin/check-ignore.c msgid "-z only makes sense with --stdin" msgstr "-z només té sentit amb --stdin" +#: builtin/check-ignore.c msgid "no path specified" msgstr "cap camí especificat" +#: builtin/check-ignore.c msgid "--quiet is only valid with a single pathname" msgstr "--quiet només és vàlid amb un sol nom de camí" +#: builtin/check-ignore.c msgid "cannot have both --quiet and --verbose" msgstr "no es poden especificar --quiet i --verbose alhora" +#: builtin/check-ignore.c msgid "--non-matching is only valid with --verbose" msgstr "--non-matching és vàlid només amb --verbose" +#: builtin/check-mailmap.c msgid "git check-mailmap [<options>] <contact>..." msgstr "git check-mailmap [<opcions>] <contacte>..." +#: builtin/check-mailmap.c msgid "also read contacts from stdin" msgstr "també llegeix els contactes des de stdin" -#, c-format -msgid "unable to parse contact: %s" -msgstr "no s'ha pogut analitzar el contacte: %s" +# no traduïsc mailmap +#: builtin/check-mailmap.c +msgid "read additional mailmap entries from file" +msgstr "llegeix les entrades mailmap addicionals del fitxer" + +#: builtin/check-mailmap.c +msgid "blob" +msgstr "blob" +#: builtin/check-mailmap.c +msgid "read additional mailmap entries from blob" +msgstr "llegeix entrades mailmap addicionals del blob" + +#: builtin/check-mailmap.c msgid "no contacts specified" msgstr "no hi ha contactes especificats" +#: builtin/checkout--worker.c msgid "git checkout--worker [<options>]" msgstr "git checkout--worker [<opcions>]" +#: builtin/checkout--worker.c builtin/checkout-index.c builtin/column.c +#: builtin/submodule--helper.c builtin/worktree.c msgid "string" msgstr "cadena" +#: builtin/checkout--worker.c builtin/checkout-index.c msgid "when creating files, prepend <string>" msgstr "en crear fitxers, anteposa <cadena>" +#: builtin/checkout-index.c msgid "git checkout-index [<options>] [--] [<file>...]" msgstr "git checkout-index [<opcions>] [--] [<fitxer>...]" +#: builtin/checkout-index.c msgid "stage should be between 1 and 3 or all" msgstr "«stage» ha de ser entre 1 i 3 o all" +#: builtin/checkout-index.c msgid "check out all files in the index" msgstr "agafa tots els fitxers en l'índex" +#: builtin/checkout-index.c msgid "do not skip files with skip-worktree set" msgstr "no ometis els fitxers amb skip-worktree establert" +#: builtin/checkout-index.c msgid "force overwrite of existing files" msgstr "força la sobreescriptura de fitxers existents" +#: builtin/checkout-index.c msgid "no warning for existing files and files not in index" msgstr "" "cap advertència per a fitxers existents i fitxers que no siguin a l'índex" +#: builtin/checkout-index.c msgid "don't checkout new files" msgstr "no agafis fitxers nous" +#: builtin/checkout-index.c msgid "update stat information in the index file" msgstr "actualitza la informació d'estadístiques en el fitxer d'índex" +#: builtin/checkout-index.c msgid "read list of paths from the standard input" msgstr "llegeix la llista de camins des de l'entrada estàndard" +#: builtin/checkout-index.c msgid "write the content to temporary files" msgstr "escriu el contingut a fitxers temporals" +#: builtin/checkout-index.c msgid "copy out the files from named stage" msgstr "copia els fitxers des de «stage» amb nom" +#: builtin/checkout.c msgid "git checkout [<options>] <branch>" msgstr "git checkout [<opcions>] <branca>" +#: builtin/checkout.c msgid "git checkout [<options>] [<branch>] -- <file>..." msgstr "git checkout [<opcions>] [<branca>] -- <fitxer>..." +#: builtin/checkout.c msgid "git switch [<options>] [<branch>]" msgstr "git switch [<opcions>] [<branca>]" +#: builtin/checkout.c msgid "git restore [<options>] [--source=<branch>] <file>..." msgstr "git restore [<opcions>] [--source=<branca>] <fitxer>..." +#: builtin/checkout.c #, c-format msgid "path '%s' does not have our version" msgstr "el camí «%s» no té la nostra versió" +#: builtin/checkout.c #, c-format msgid "path '%s' does not have their version" msgstr "el camí «%s» no té la seva versió" +#: builtin/checkout.c #, c-format msgid "path '%s' does not have all necessary versions" msgstr "el camí «%s» no té totes les versions necessàries" +#: builtin/checkout.c #, c-format msgid "path '%s' does not have necessary versions" msgstr "el camí «%s» no té les versions necessàries" +#: builtin/checkout.c #, c-format msgid "path '%s': cannot merge" msgstr "camí «%s»: no es pot fusionar" +#: builtin/checkout.c #, c-format msgid "Unable to add merge result for '%s'" msgstr "No s'ha pogut afegir el resultat de fusió per a «%s»" +#: builtin/checkout.c #, c-format msgid "Recreated %d merge conflict" msgid_plural "Recreated %d merge conflicts" msgstr[0] "Recreat un conflicte de fusió" msgstr[1] "Recreats %d conflictes de fusió" +#: builtin/checkout.c #, c-format msgid "Updated %d path from %s" msgid_plural "Updated %d paths from %s" -msgstr[0] "S'ha actualitzat %d camí des de %s" -msgstr[1] "S'han actualitzat %d camins des de %s" +msgstr[0] "S'ha actualitzat %d camí a partir de %s" +msgstr[1] "S'han actualitzat %d camins a partir de %s" +#: builtin/checkout.c #, c-format msgid "Updated %d path from the index" msgid_plural "Updated %d paths from the index" -msgstr[0] "S'ha actualitzat un camí des de l'índex" -msgstr[1] "S'ha actualitzat %d camins des de l'índex" +msgstr[0] "S'ha actualitzat %d camí a partir de l'índex" +msgstr[1] "S'han actualitzat %d camins a partir de l'índex" +#: builtin/checkout.c #, c-format msgid "'%s' cannot be used with updating paths" msgstr "«%s» no es pot usar amb actualització de camins" +#: builtin/checkout.c #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "" "No es poden actualitzar els camins i canviar a la branca «%s» a la vegada." +#: builtin/checkout.c #, c-format msgid "neither '%s' or '%s' is specified" msgstr "no s'ha especificat ni «%s» ni «%s»" +#: builtin/checkout.c #, c-format msgid "'%s' must be used when '%s' is not specified" msgstr "«%s» s'ha d'utilitzar quan no s'especifica «%s»" +#: builtin/checkout.c #, c-format msgid "'%s' or '%s' cannot be used with %s" msgstr "«%s» o «%s» no poden utilitzar-se amb %s" +#: builtin/checkout.c #, 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" +#: builtin/checkout.c #, c-format msgid "path '%s' is unmerged" msgstr "el camí «%s» està sense fusionar" +#: builtin/checkout.c builtin/grep.c builtin/merge-tree.c builtin/reset.c +#: merge-ort.c reset.c sequencer.c tree-walk.c +#, c-format +msgid "unable to read tree (%s)" +msgstr "no s'ha pogut llegir l'arbre (%s)" + +#: builtin/checkout.c msgid "you need to resolve your current index first" msgstr "heu de primer resoldre el vostre índex actual" +#: builtin/checkout.c #, c-format msgid "" "cannot continue with staged changes in the following files:\n" @@ -3669,40 +4609,50 @@ msgstr "" "no es pot continuar amb els canvis «staged» als fitxers següents:\n" "%s" +#: builtin/checkout.c #, c-format msgid "Can not do reflog for '%s': %s\n" -msgstr "No es pot fer reflog per a «%s»: %s\n" +msgstr "No es pot fer «reflog» per a «%s»: %s\n" +#: builtin/checkout.c msgid "HEAD is now at" msgstr "HEAD ara és a" +#: builtin/checkout.c builtin/clone.c msgid "unable to update HEAD" msgstr "no s'ha pogut actualitzar HEAD" +#: builtin/checkout.c #, c-format msgid "Reset branch '%s'\n" msgstr "Restableix la branca «%s»\n" +#: builtin/checkout.c #, c-format msgid "Already on '%s'\n" msgstr "Ja esteu en «%s»\n" +#: builtin/checkout.c #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "S'ha canviat i restablert a la branca «%s»\n" +#: builtin/checkout.c #, c-format msgid "Switched to a new branch '%s'\n" msgstr "S'ha canviat a la branca nova «%s»\n" +#: builtin/checkout.c #, c-format msgid "Switched to branch '%s'\n" msgstr "S'ha canviat a la branca «%s»\n" +#: builtin/checkout.c #, c-format msgid " ... and %d more.\n" msgstr " ... i %d més.\n" +#: builtin/checkout.c #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -3725,6 +4675,7 @@ msgstr[1] "" "\n" "%s\n" +#: builtin/checkout.c #, c-format msgid "" "If you want to keep it by creating a new branch, this may be a good time\n" @@ -3751,15 +4702,19 @@ msgstr[1] "" " git branch <nom-de-branca-nova> %s\n" "\n" +#: builtin/checkout.c msgid "internal error in revision walk" msgstr "error intern en el passeig per revisions" +#: builtin/checkout.c msgid "Previous HEAD position was" msgstr "La posició de HEAD anterior era" +#: builtin/checkout.c msgid "You are on a branch yet to be born" msgstr "Sou en una branca que encara ha de néixer" +#: builtin/checkout.c #, c-format msgid "" "'%s' could be both a local file and a tracking branch.\n" @@ -3768,6 +4723,7 @@ msgstr "" "«%s» podria ser tant un fitxer local com una branca de seguiment.\n" "Useu -- (i opcionalment --no-guess) per a desambiguar-ho" +#: builtin/checkout.c msgid "" "If you meant to check out a remote tracking branch on, e.g. 'origin',\n" "you can do so by fully qualifying the name with the --track option:\n" @@ -3787,47 +4743,58 @@ msgstr "" "remota, p. ex. «origin» al remot, considereu configurar l'opció\n" "checkout.defaultRemote=origin en la vostra configuració." +#: builtin/checkout.c #, c-format msgid "'%s' matched multiple (%d) remote tracking branches" msgstr "«%s» coincideixen múltiples (%d) branques de seguiment remotes" +#: builtin/checkout.c msgid "only one reference expected" msgstr "només s'esperava una referència" +#: builtin/checkout.c #, c-format msgid "only one reference expected, %d given." msgstr "s'esperava només una referència, s'han donat %d." +#: builtin/checkout.c builtin/worktree.c #, c-format msgid "invalid reference: %s" msgstr "referència no vàlida: %s" +#: builtin/checkout.c #, c-format msgid "reference is not a tree: %s" msgstr "la referència no és un arbre: %s" +#: builtin/checkout.c #, c-format msgid "a branch is expected, got tag '%s'" msgstr "s'espera una branca, s'ha obtingut l'etiqueta «%s»" +#: builtin/checkout.c #, c-format msgid "a branch is expected, got remote branch '%s'" msgstr "s'espera una branca, s'ha obtingut la branca remota «%s»" +#: builtin/checkout.c #, c-format msgid "a branch is expected, got '%s'" msgstr "s'espera una branca, s'ha obtingut «%s»" +#: builtin/checkout.c #, c-format msgid "a branch is expected, got commit '%s'" msgstr "s'espera una branca, s'ha obtingut la comissió «%s»" +#: builtin/checkout.c msgid "" "If you want to detach HEAD at the commit, try again with the --detach option." msgstr "" "Si voleu desacoblar HEAD a la comissió, torneu-ho a provar amb l'opció --" "detach." +#: builtin/checkout.c msgid "" "cannot switch branch while merging\n" "Consider \"git merge --quit\" or \"git worktree add\"." @@ -3835,6 +4802,7 @@ msgstr "" "no es pot canviar de branca mentre es fusiona\n" "Considereu usar «git merge --quit» o «git worktree add»." +#: builtin/checkout.c msgid "" "cannot switch branch in the middle of an am session\n" "Consider \"git am --quit\" or \"git worktree add\"." @@ -3842,6 +4810,7 @@ msgstr "" "no es pot canviar de branca en mig d'una sessió «am»\n" "Considereu usar «git am --quit» o «git worktree add»." +#: builtin/checkout.c msgid "" "cannot switch branch while rebasing\n" "Consider \"git rebase --quit\" or \"git worktree add\"." @@ -3849,6 +4818,7 @@ msgstr "" "no es pot canviar de branca mentre es fa «rebase»\n" "Considereu usar «git rebase --quit» o «git worktree add»." +#: builtin/checkout.c msgid "" "cannot switch branch while cherry-picking\n" "Consider \"git cherry-pick --quit\" or \"git worktree add\"." @@ -3856,6 +4826,7 @@ msgstr "" "no es pot canviar de branca mentre es fa «cherry-pick»\n" "Considereu usar «git cherry-pick --quit» o «git worktree add»." +#: builtin/checkout.c msgid "" "cannot switch branch while reverting\n" "Consider \"git revert --quit\" or \"git worktree add\"." @@ -3863,95 +4834,133 @@ msgstr "" "no es pot canviar de branca mentre s'està revertint\n" "Considereu «git revert --quit» o «git worktree add»." +#: builtin/checkout.c msgid "you are switching branch while bisecting" msgstr "s'està canviant la branca mentre es fa una bisecció" +#: builtin/checkout.c msgid "paths cannot be used with switching branches" msgstr "els camins no es poden usar amb canvi de branca" +#: builtin/checkout.c #, c-format msgid "'%s' cannot be used with switching branches" msgstr "«%s» no es pot usar amb canvi de branca" +# és com si faltara un objecte directe per a agafar +#: builtin/checkout.c +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "«%s» necessita els camins per a agafar" + +#: builtin/checkout.c #, c-format msgid "'%s' cannot be used with '%s'" msgstr "«%s» no es pot usar amb «%s»" +#: builtin/checkout.c #, c-format msgid "'%s' cannot take <start-point>" msgstr "«%s» no pot prendre <start-point>" +#: builtin/checkout.c #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "No es pot canviar la branca a la no comissió «%s»" +#: builtin/checkout.c msgid "missing branch or commit argument" msgstr "manca branca o argument de comissió" +#: builtin/checkout.c +#, c-format +msgid "unknown conflict style '%s'" +msgstr "estil de conflicte desconegut «%s»" + +#: builtin/checkout.c msgid "perform a 3-way merge with the new branch" msgstr "realitza una fusió de 3 vies amb la branca nova" +#: builtin/checkout.c builtin/log.c parse-options.h msgid "style" msgstr "estil" +#: builtin/checkout.c msgid "conflict style (merge, diff3, or zdiff3)" msgstr "estil de conflicte (merge, diff3, o zdiff3)" +#: builtin/checkout.c builtin/worktree.c msgid "detach HEAD at named commit" msgstr "separa HEAD a la comissió anomenada" +#: builtin/checkout.c msgid "force checkout (throw away local modifications)" msgstr "agafa a la força (descarta qualsevol modificació local)" +#: builtin/checkout.c msgid "new-branch" msgstr "branca-nova" +#: builtin/checkout.c msgid "new unborn branch" msgstr "branca no nascuda nova" +#: builtin/checkout.c builtin/merge.c msgid "update ignored files (default)" msgstr "actualitza els fitxers ignorats (per defecte)" +#: builtin/checkout.c msgid "do not check if another worktree is holding the given ref" msgstr "no comprovis si un altre arbre de treball té la referència donada" +#: builtin/checkout.c msgid "checkout our version for unmerged files" msgstr "agafa la versió nostra dels fitxers sense fusionar" +#: builtin/checkout.c msgid "checkout their version for unmerged files" msgstr "agafa la versió seva dels fitxers sense fusionar" +#: builtin/checkout.c msgid "do not limit pathspecs to sparse entries only" msgstr "no limitis les especificacions de camí només a entrades disperses" +#: builtin/checkout.c #, c-format msgid "options '-%c', '-%c', and '%s' cannot be used together" msgstr "les opcions «-%c», «-%c», i «%s» no es poden usar juntes" +#: builtin/checkout.c msgid "--track needs a branch name" msgstr "--track necessita un nom de branca" +#: builtin/checkout.c #, c-format msgid "missing branch name; try -%c" msgstr "falta el nom de la branca; proveu -%c" +#: builtin/checkout.c #, c-format msgid "could not resolve %s" msgstr "no es pot resoldre %s" +#: builtin/checkout.c msgid "invalid path specification" msgstr "especificació de camí no vàlida" +#: builtin/checkout.c #, c-format msgid "'%s' is not a commit and a branch '%s' cannot be created from it" msgstr "" "«%s» no és una comissió i la branca «%s» no es pot crear a partir d'aquesta " "comissió" +#: builtin/checkout.c #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout: --detach no accepta un argument de camí «%s»" +#: builtin/checkout.c msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -3959,54 +4968,72 @@ msgstr "" "git checkout: --ours/--theirs, --force i --merge són incompatibles en\n" "agafar de l'índex." +#: builtin/checkout.c msgid "you must specify path(s) to restore" msgstr "heu d'especificar el camí o camins a restaurar" +#: builtin/checkout.c builtin/clone.c builtin/remote.c builtin/replay.c +#: builtin/submodule--helper.c builtin/worktree.c msgid "branch" msgstr "branca" +#: builtin/checkout.c msgid "create and checkout a new branch" msgstr "crea i agafa una branca nova" +#: builtin/checkout.c msgid "create/reset and checkout a branch" msgstr "crea/restableix i agafa una branca" +#: builtin/checkout.c msgid "create reflog for new branch" -msgstr "crea un registre de referència per a la branca nova" +msgstr "crea un registre de referències per a la branca nova" +#: builtin/checkout.c msgid "second guess 'git checkout <no-such-branch>' (default)" msgstr "segona deducció «git checkout <no-such-branch>» (per defecte)" +#: builtin/checkout.c msgid "use overlay mode (default)" msgstr "utilitza el mode de superposició (per defecte)" +#: builtin/checkout.c msgid "create and switch to a new branch" msgstr "crea i canvia a una branca nova" +#: builtin/checkout.c msgid "create/reset and switch to a branch" msgstr "crea/restableix i canvia a una branca" +#: builtin/checkout.c msgid "second guess 'git switch <no-such-branch>'" msgstr "segona deducció «git switch <no-such-branch>»" +#: builtin/checkout.c msgid "throw away local modifications" msgstr "descarta les modificacions locals" +#: builtin/checkout.c msgid "which tree-ish to checkout from" msgstr "des de quin arbre agafar" +#: builtin/checkout.c msgid "restore the index" msgstr "restaura l'índex" +#: builtin/checkout.c msgid "restore the working tree (default)" msgstr "restaura l'arbre de treball (per defecte)" +#: builtin/checkout.c msgid "ignore unmerged entries" msgstr "ignora les entrades sense fusionar" +#: builtin/checkout.c msgid "use overlay mode" msgstr "utilitza el mode de superposició" +#: builtin/clean.c msgid "" "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] " "[<pathspec>...]" @@ -4014,36 +5041,45 @@ msgstr "" "git clean [-d] [-f] [-i] [-n] [-q] [-e <patró>] [-x | -X] [--] " "[<pathspec>...]" +#: builtin/clean.c #, c-format msgid "Removing %s\n" msgstr "S'està eliminant %s\n" +#: builtin/clean.c #, c-format msgid "Would remove %s\n" msgstr "Eliminaria %s\n" +#: builtin/clean.c #, c-format msgid "Skipping repository %s\n" msgstr "S'està ometent el repositori %s\n" +#: builtin/clean.c #, c-format msgid "Would skip repository %s\n" msgstr "Ometria el repositori %s\n" +#: builtin/clean.c midx.c #, c-format msgid "failed to remove %s" msgstr "s'ha produït un error en eliminar %s" +#: builtin/clean.c #, c-format msgid "could not lstat %s\n" msgstr "no s'ha pogut fer lstat %s\n" +#: builtin/clean.c msgid "Refusing to remove current working directory\n" msgstr "S'ha rebutjat suprimir el directori de treball actual\n" +#: builtin/clean.c msgid "Would refuse to remove current working directory\n" msgstr "Es rebutjarà eliminar el directori de treball actual\n" +#: builtin/clean.c #, c-format msgid "" "Prompt help:\n" @@ -4056,6 +5092,7 @@ msgstr "" "foo - selecciona un ítem basat en un prefix únic\n" " - (buit) no seleccionis res\n" +#: builtin/clean.c #, c-format msgid "" "Prompt help:\n" @@ -4076,26 +5113,32 @@ msgstr "" "* - tria tots els ítems\n" " - (buit) finalitza la selecció\n" +#: builtin/clean.c #, c-format msgid "Huh (%s)?\n" msgstr "Perdó (%s)?\n" +#: builtin/clean.c #, c-format msgid "Input ignore patterns>> " msgstr "Introduïu els patrons a ignorar>> " +#: builtin/clean.c #, c-format msgid "WARNING: Cannot find items matched by: %s" msgstr "ADVERTÈNCIA: No es poden trobar ítems que coincideixin amb: %s" +#: builtin/clean.c msgid "Select items to delete" msgstr "Selecciona els ítems a suprimir" #. TRANSLATORS: Make sure to keep [y/N] as is +#: builtin/clean.c #, c-format msgid "Remove %s [y/N]? " msgstr "Voleu eliminar %s [y/N]? " +#: builtin/clean.c msgid "" "clean - start cleaning\n" "filter by pattern - exclude items from deletion\n" @@ -4113,216 +5156,286 @@ msgstr "" "help - aquesta pantalla\n" "? - ajuda de selecció manual" +#: builtin/clean.c msgid "Would remove the following item:" msgid_plural "Would remove the following items:" msgstr[0] "Eliminaria l'ítem següent:" msgstr[1] "Eliminaria els ítems següents:" +#: builtin/clean.c msgid "No more files to clean, exiting." msgstr "No hi ha més fitxers a netejar; s'està sortint." +#: builtin/clean.c msgid "do not print names of files removed" msgstr "no imprimeixis els noms dels fitxers eliminats" +#: builtin/clean.c msgid "force" msgstr "força" +#: builtin/clean.c msgid "interactive cleaning" msgstr "neteja interactiva" +#: builtin/clean.c msgid "remove whole directories" msgstr "elimina directoris sencers" +#: builtin/clean.c builtin/config.c builtin/describe.c builtin/grep.c +#: builtin/log.c builtin/ls-files.c builtin/name-rev.c builtin/pack-refs.c +#: builtin/show-ref.c ref-filter.h msgid "pattern" msgstr "patró" +#: builtin/clean.c msgid "add <pattern> to ignore rules" msgstr "afegiu <patró> per a ignorar les regles" +#: builtin/clean.c msgid "remove ignored files, too" msgstr "elimina els fitxers ignorats, també" +#: builtin/clean.c msgid "remove only ignored files" msgstr "elimina només els fitxers ignorats" -msgid "" -"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to " -"clean" -msgstr "" -"clean.requireForce està establerta en cert i ni -i, -n ni -f s'han indicat; " -"refusant netejar" - -msgid "" -"clean.requireForce defaults to true and neither -i, -n, nor -f given; " -"refusing to clean" +#: builtin/clean.c +msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "" -"clean.requireForce és per defecte cert i ni -i, -n ni -f s'han indicat; " -"refusant netejar" +"clean.requireForce està establert a cert i no s'ha indicat -f : es rebutja " +"netejar" +#: builtin/clone.c msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<opcions>] [--] <repositori> [<directori>]" +#: builtin/clone.c msgid "don't clone shallow repository" msgstr "no clonis un repositori superficial" +#: builtin/clone.c msgid "don't create a checkout" msgstr "no facis cap agafament" +#: builtin/clone.c builtin/init-db.c msgid "create a bare repository" msgstr "crea un repositori nu" -msgid "create a mirror repository (implies bare)" -msgstr "crea un repositori mirall (implica bare)" +#: builtin/clone.c +msgid "create a mirror repository (implies --bare)" +msgstr "crear un repositori mirall (implica --bare)" +#: builtin/clone.c msgid "to clone from a local repository" msgstr "per a clonar des d'un repositori local" +#: builtin/clone.c msgid "don't use local hardlinks, always copy" msgstr "no usis enllaços durs locals, sempre copia" +#: builtin/clone.c msgid "setup as shared repository" msgstr "configura com a repositori compartit" +#: builtin/clone.c msgid "pathspec" msgstr "especificació de camí" +#: builtin/clone.c msgid "initialize submodules in the clone" msgstr "inicialitza els submòduls en el clon" +#: builtin/clone.c msgid "number of submodules cloned in parallel" msgstr "nombre de submòduls clonats en paral·lel" +#: builtin/clone.c builtin/init-db.c msgid "template-directory" msgstr "directori-de-plantilla" +#: builtin/clone.c builtin/init-db.c msgid "directory from which templates will be used" msgstr "directori des del qual s'usaran les plantilles" +#: builtin/clone.c builtin/submodule--helper.c msgid "reference repository" msgstr "repositori de referència" +#: builtin/clone.c builtin/submodule--helper.c msgid "use --reference only while cloning" msgstr "usa --reference només en clonar" +#: builtin/clone.c builtin/column.c builtin/fmt-merge-msg.c builtin/init-db.c +#: builtin/merge-file.c builtin/merge.c builtin/pack-objects.c builtin/repack.c +#: builtin/submodule--helper.c t/helper/test-simple-ipc.c msgid "name" msgstr "nom" +#: builtin/clone.c msgid "use <name> instead of 'origin' to track upstream" msgstr "usa <nom> en lloc d'«origin» per a seguir la font" +#: builtin/clone.c msgid "checkout <branch> instead of the remote's HEAD" msgstr "agafa <branca> en lloc de la HEAD del remot" +#: builtin/clone.c msgid "path to git-upload-pack on the remote" msgstr "camí a git-upload-pack en el remot" +#: builtin/clone.c builtin/fetch.c builtin/pull.c msgid "depth" msgstr "profunditat" +#: builtin/clone.c msgid "create a shallow clone of that depth" msgstr "crea un clon superficial d'aquesta profunditat" +#: builtin/clone.c msgid "create a shallow clone since a specific time" msgstr "crea un clon superficial des d'una data específica" +#: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c +#: builtin/replay.c msgid "revision" msgstr "revisió" +#: builtin/clone.c builtin/fetch.c builtin/pull.c msgid "deepen history of shallow clone, excluding rev" msgstr "aprofundeix la història d'un clon superficial, excloent una revisió" +#: builtin/clone.c builtin/submodule--helper.c msgid "clone only one branch, HEAD or --branch" msgstr "clona només una branca, HEAD o --branch" +#: builtin/clone.c msgid "don't clone any tags, and make later fetches not to follow them" msgstr "" "no cloneu cap etiqueta, i feu que els «fetch» següents no les segueixin" +#: builtin/clone.c msgid "any cloned submodules will be shallow" msgstr "qualsevol submòdul clonat serà superficial" +#: builtin/clone.c builtin/init-db.c msgid "gitdir" msgstr "directori de git" +#: builtin/clone.c builtin/init-db.c msgid "separate git dir from working tree" msgstr "separa el directori de git de l'arbre de treball" +#: builtin/clone.c builtin/init-db.c builtin/submodule--helper.c msgid "specify the reference format to use" msgstr "especifiqueu el format de referència a usar" +#: builtin/clone.c msgid "key=value" msgstr "clau=valor" +#: builtin/clone.c msgid "set config inside the new repository" msgstr "estableix la configuració dins del repositori nou" +#: builtin/clone.c builtin/fetch.c builtin/ls-remote.c builtin/pull.c +#: builtin/push.c builtin/send-pack.c msgid "server-specific" msgstr "específic al servidor" +#: builtin/clone.c builtin/fetch.c builtin/ls-remote.c builtin/pull.c +#: builtin/push.c builtin/send-pack.c msgid "option to transmit" msgstr "opció a transmetre" +#: builtin/clone.c msgid "apply partial clone filters to submodules" msgstr "aplica els filtres de clonatge parcial als submòduls" +#: builtin/clone.c msgid "any cloned submodules will use their remote-tracking branch" msgstr "qualsevol submòdul clonat utilitzarà la seva branca de seguiment remot" +#: builtin/clone.c msgid "initialize sparse-checkout file to include only files at root" msgstr "" "inicialitza el fitxer «sparse-checkout» per a incloure només els fitxers a " "l'arrel" +#: builtin/clone.c msgid "uri" msgstr "uri" +#: builtin/clone.c msgid "a URI for downloading bundles before fetching from origin remote" msgstr "un URI per a baixar paquets abans d'obtenir des del remot origen" +#: builtin/clone.c #, c-format msgid "info: Could not add alternate for '%s': %s\n" msgstr "info: No s'ha pogut afegir un alternatiu per a «%s»: %s\n" +#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c #, c-format msgid "failed to stat '%s'" msgstr "s'ha produït un error en fer stat a «%s»" +#: builtin/clone.c #, c-format msgid "%s exists and is not a directory" msgstr "%s existeix i no és directori" +#: builtin/clone.c #, c-format msgid "'%s' is a symlink, refusing to clone with --local" msgstr "«%s» és un enllaç simbòlic, es rebutja clonar amb --local" +#: builtin/clone.c #, c-format msgid "failed to start iterator over '%s'" msgstr "no s'ha pogut iniciar l'iterador sobre «%s»" +#: builtin/clone.c #, c-format msgid "symlink '%s' exists, refusing to clone with --local" msgstr "l'enllaç simbòlic «%s» existeix, es rebutja a clonar amb --local" +#: builtin/clone.c compat/precompose_utf8.c #, c-format msgid "failed to unlink '%s'" msgstr "s'ha produït un error en desenllaçar «%s»" +#: builtin/clone.c +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "no es pot comprovar l'enllaç físic en «%s»" + +#: builtin/clone.c +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "l'enllaç físic és diferent de la font en «%s»" + +#: builtin/clone.c #, c-format msgid "failed to create link '%s'" msgstr "s'ha produït un error en crear l'enllaç «%s»" +#: builtin/clone.c #, c-format msgid "failed to copy file to '%s'" msgstr "s'ha produït un error en copiar el fitxer a «%s»" +#: builtin/clone.c refs/files-backend.c #, c-format msgid "failed to iterate over '%s'" msgstr "no s'ha pogut iterar sobre «%s»" +#: builtin/clone.c #, c-format msgid "done.\n" msgstr "fet.\n" +#: builtin/clone.c msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -4332,83 +5445,106 @@ msgstr "" "Podeu inspeccionar el que s'ha agafat amb «git status»\n" "i tornar-ho a provar amb «git restore --source=HEAD :/»\n" +#: builtin/clone.c #, c-format msgid "Could not find remote branch %s to clone." msgstr "No s'ha pogut trobar la branca remota %s per a clonar." +#: builtin/clone.c fetch-pack.c msgid "remote did not send all necessary objects" msgstr "el remot no ha enviat tots els objectes necessaris" +#: builtin/clone.c #, c-format msgid "unable to update %s" msgstr "no s'ha pogut actualitzar %s" +#: builtin/clone.c msgid "failed to initialize sparse-checkout" msgstr "no s'ha pogut inicialitzar «sparse-checkout»" +#: builtin/clone.c msgid "remote HEAD refers to nonexistent ref, unable to checkout" msgstr "" -"la HEAD remot es refereix a una referència que no existeix, no s'ha pogut " +"el HEAD remot es refereix a una referència que no existeix, no s'ha pogut " "agafar" +#: builtin/clone.c msgid "unable to checkout working tree" msgstr "no s'ha pogut agafar l'arbre de treball" +#: builtin/clone.c msgid "unable to write parameters to config file" msgstr "no s'han pogut escriure els paràmetres al fitxer de configuració" +#: builtin/clone.c msgid "cannot repack to clean up" msgstr "no es pot reempaquetar per a netejar" +#: builtin/clone.c msgid "cannot unlink temporary alternates file" msgstr "no es pot desenllaçar el fitxer d'alternatives temporal" +#: builtin/clone.c msgid "Too many arguments." msgstr "Hi ha massa arguments." +#: builtin/clone.c scalar.c msgid "You must specify a repository to clone." msgstr "Heu d'especificar un repositori per a clonar." +#: builtin/clone.c builtin/init-db.c builtin/refs.c builtin/submodule--helper.c +#: setup.c #, c-format msgid "unknown ref storage format '%s'" msgstr "el format d'emmagatzematge de referència «%s» és desconegut" +#: builtin/clone.c #, c-format msgid "repository '%s' does not exist" msgstr "el repositori «%s» no existeix" +#: builtin/clone.c builtin/fetch.c #, c-format msgid "depth %s is not a positive number" msgstr "la profunditat %s no és un nombre positiu" +#: builtin/clone.c #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "el camí destí «%s» ja existeix i no és un directori buit." +#: builtin/clone.c #, c-format msgid "repository path '%s' already exists and is not an empty directory." msgstr "el camí destí «%s» ja existeix i no és un directori buit." +#: builtin/clone.c #, c-format msgid "working tree '%s' already exists." msgstr "l'arbre de treball «%s» ja existeix." +#: builtin/clone.c builtin/difftool.c builtin/log.c builtin/worktree.c #, c-format msgid "could not create leading directories of '%s'" msgstr "no s'han pogut crear els directoris inicials de «%s»" +#: builtin/clone.c #, c-format msgid "could not create work tree dir '%s'" msgstr "no s'ha pogut crear el directori d'arbre de treball «%s»" +#: builtin/clone.c #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "S'està clonant al repositori nu «%s»...\n" +#: builtin/clone.c #, c-format msgid "Cloning into '%s'...\n" msgstr "S'està clonant a «%s»...\n" +#: builtin/clone.c msgid "" "clone --recursive is not compatible with both --reference and --reference-if-" "able" @@ -4416,85 +5552,115 @@ msgstr "" "clone --recursive no és compatible amb ambdós --reference i --reference-if-" "able" +#: builtin/clone.c builtin/remote.c #, c-format msgid "'%s' is not a valid remote name" msgstr "«%s» no és un nom de remot vàlid" +#: builtin/clone.c msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth s'ignora en els clons locals; useu file:// en lloc d'això." +#: builtin/clone.c msgid "--shallow-since is ignored in local clones; use file:// instead." msgstr "" "--shallow-since s'ignora en els clons locals; useu file:// en lloc d'això." +#: builtin/clone.c msgid "--shallow-exclude is ignored in local clones; use file:// instead." msgstr "" "--shallow-exclude s'ignora en els clons locals; useu file:// en lloc d'això." +#: builtin/clone.c msgid "--filter is ignored in local clones; use file:// instead." msgstr "--filter s'ignora en els clons locals; useu file:// en lloc d'això." +#: builtin/clone.c fetch-pack.c msgid "source repository is shallow, reject to clone." msgstr "el repositori font és superficial, es rebutja clonar-ho." +#: builtin/clone.c msgid "source repository is shallow, ignoring --local" msgstr "el repositori font és superficial, s'està ignorant --local" +#: builtin/clone.c msgid "--local is ignored" msgstr "--local s'ignora" +#: builtin/clone.c msgid "cannot clone from filtered bundle" msgstr "no es pot clonar des del farell filtrat" +#: builtin/clone.c msgid "failed to initialize the repo, skipping bundle URI" msgstr "no s'ha pogut inicialitzar el repositori, s'omet l'URI del paquet" +#: builtin/clone.c #, c-format msgid "failed to fetch objects from bundle URI '%s'" msgstr "no s'han pogut obtenir els objectes de l'URI del paquet «%s»" +#: builtin/clone.c msgid "failed to fetch advertised bundles" msgstr "no s'han pogut obtenir els paquets anunciats" +#: builtin/clone.c msgid "remote transport reported error" msgstr "el transport remot ha informat d'un error" +#: builtin/clone.c #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "La branca remota %s no es troba en la font %s" +#: builtin/clone.c msgid "You appear to have cloned an empty repository." msgstr "Sembla que heu clonat un repositori buit." +#: builtin/column.c msgid "git column [<options>]" msgstr "git column [<opcions>]" +#: builtin/column.c msgid "lookup config vars" msgstr "cerca les variables de configuració" +#: builtin/column.c msgid "layout to use" msgstr "disposició a usar" +#: builtin/column.c msgid "maximum width" msgstr "amplada màxima" +#: builtin/column.c msgid "padding space on left border" msgstr "espai de farciment al marge esquerre" +#: builtin/column.c msgid "padding space on right border" msgstr "espai de farciment al marge dret" +#: builtin/column.c msgid "padding space between columns" msgstr "espai de farciment entre columnes" +#: builtin/column.c +#, c-format +msgid "%s must be non-negative" +msgstr "%s ha de ser no negatiu" + +#: builtin/column.c msgid "--command must be the first argument" msgstr "--command ha de ser el primer argument" +#: builtin/commit-graph.c msgid "" "git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]" msgstr "" "git commit-graph verify [--object-dir <dir>] [--shallow] [--[no-]progress]" +#: builtin/commit-graph.c msgid "" "git commit-graph write [--object-dir <dir>] [--append]\n" " [--split[=<strategy>]] [--reachable | --stdin-packs | " @@ -4510,131 +5676,169 @@ msgstr "" "[no-]progress]\n" " <split-options>" +#: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c msgid "dir" msgstr "directori" +#: builtin/commit-graph.c msgid "the object directory to store the graph" msgstr "el directori d'objectes a emmagatzemar al graf" +#: builtin/commit-graph.c msgid "if the commit-graph is split, only verify the tip file" msgstr "" "si el graf de comissions està dividit només, verifica el fitxer de consell" +#: builtin/commit-graph.c #, c-format msgid "Could not open commit-graph '%s'" msgstr "No s'ha pogut obrir el graf de comissions «%s»" +#: builtin/commit-graph.c #, c-format msgid "could not open commit-graph chain '%s'" msgstr "no s'ha pogut obrir la cadena «%s» del graf de comissions" +#: builtin/commit-graph.c #, c-format msgid "unrecognized --split argument, %s" msgstr "argument --split no reconegut, %s" +#: builtin/commit-graph.c #, c-format msgid "unexpected non-hex object ID: %s" msgstr "ID de l'objecte no hexadecimal inesperat: %s" +#: builtin/commit-graph.c #, c-format msgid "invalid object: %s" msgstr "no és un objecte vàlid: %s" +#: builtin/commit-graph.c parse-options-cb.c #, c-format msgid "option `%s' expects a numerical value" msgstr "l'opció «%s» espera un valor numèric" +#: builtin/commit-graph.c msgid "start walk at all refs" msgstr "comença el recorregut en totes les referències" +#: builtin/commit-graph.c msgid "scan pack-indexes listed by stdin for commits" msgstr "explora els índexs del paquet llistats per a stdin per a comissions" +#: builtin/commit-graph.c msgid "start walk at commits listed by stdin" msgstr "comença el recorregut per les comissions llistades per stdin" +#: builtin/commit-graph.c msgid "include all commits already in the commit-graph file" msgstr "inclou ja totes les comissions al fitxer del graf de comissions" +#: builtin/commit-graph.c msgid "enable computation for changed paths" msgstr "habilita la computació per als camins canviats" +#: builtin/commit-graph.c msgid "allow writing an incremental commit-graph file" msgstr "permet escriure un fitxer de graf de comissions incrementals" +#: builtin/commit-graph.c msgid "maximum number of commits in a non-base split commit-graph" msgstr "" "nombre màxim de comissions en un graf de comissions separades sense base" +#: builtin/commit-graph.c msgid "maximum ratio between two levels of a split commit-graph" msgstr "ràtio màxima entre dos nivells d'un graf de comissions dividit" +#: builtin/commit-graph.c msgid "only expire files older than a given date-time" msgstr "fes caducar només els objectes més antics que l'hora i data donades" +#: builtin/commit-graph.c msgid "maximum number of changed-path Bloom filters to compute" -msgstr "nombre màxim de canvis de camí en filtres Bloom a calcular" +msgstr "nombre màxim de canvis de camí en filtres de Bloom a calcular" +#: builtin/commit-graph.c msgid "use at most one of --reachable, --stdin-commits, or --stdin-packs" -msgstr "usa com a màxim un --reachable, --stdin-commits, o --stdin-packs" +msgstr "usa com a màxim un entre --reachable, --stdin-commits, o --stdin-packs" +#: builtin/commit-graph.c msgid "Collecting commits from input" msgstr "S'estan recollint les comissions de l'entrada" +#: builtin/commit-tree.c msgid "git commit-tree <tree> [(-p <parent>)...]" -msgstr "git commit-tree <tree> [(-p <pare>)...]" +msgstr "git commit-tree <arbre> [(-p <pare>)...]" +#: builtin/commit-tree.c msgid "" "git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...]\n" " [(-F <file>)...] <tree>" msgstr "" "git commit-tree [(-p <pare>)...] [-S[<keyid>]] [(-m <missatge>)...]\n" -" [(-F <fitxer>)...] <tree>" +" [(-F <fitxer>)...] <arbre>" +#: builtin/commit-tree.c #, c-format msgid "duplicate parent %s ignored" msgstr "s'han ignorat el pare %s duplicat" +#: builtin/commit-tree.c builtin/log.c #, c-format msgid "not a valid object name %s" msgstr "no és un nom d'objecte vàlid %s" +#: builtin/commit-tree.c #, c-format msgid "git commit-tree: failed to read '%s'" msgstr "git commit-tree: ha fallat en llegir «%s»" +#: builtin/commit-tree.c #, c-format msgid "git commit-tree: failed to close '%s'" msgstr "git commit-tree: ha fallat en tancar «%s»" +#: builtin/commit-tree.c msgid "parent" msgstr "pare" +#: builtin/commit-tree.c msgid "id of a parent commit object" msgstr "id d'un objecte de comissió pare" +#: builtin/commit-tree.c builtin/commit.c builtin/merge.c builtin/notes.c +#: builtin/stash.c builtin/tag.c msgid "message" msgstr "missatge" +#: builtin/commit-tree.c builtin/commit.c msgid "commit message" msgstr "missatge de comissió" +#: builtin/commit-tree.c msgid "read commit log message from file" msgstr "llegeix el missatge de registre de comissió des d'un fitxer" +#: builtin/commit-tree.c builtin/commit.c builtin/merge.c builtin/pull.c +#: builtin/revert.c msgid "GPG sign commit" msgstr "signa la comissió amb GPG" +#: builtin/commit-tree.c msgid "must give exactly one tree" msgstr "ha de donar exactament un arbre" +#: builtin/commit-tree.c msgid "git commit-tree: failed to read" msgstr "git commit-tree: ha fallat en llegir" +#: builtin/commit.c msgid "" "git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4644,17 +5848,19 @@ msgid "" msgstr "" "git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <comissió> | --fixup [(amend|" -"reword):]<comissió>)]\n" +"reword):]<comissió>]\n" " [-F <fitxer> | -m <msg>] [--reset-author] [--allow-empty]\n" -" [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" -" [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" +" [--allow-empty-message] [--no-verify] [-e] [--author=<autor>]\n" +" [--date=<data>] [--cleanup=<mode>] [--[no-]status]\n" " [-i | -o] [--pathspec-from-file=<fitxer> [--pathspec-file-nul]]\n" -" [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" -" [--] [<pathspec>...]" +" [(--trailer <token>[(=|:)<valor>])...] [-S[<id-clau>]]\n" +" [--] [<especificació-camí>...]" +#: builtin/commit.c msgid "git status [<options>] [--] [<pathspec>...]" msgstr "git status [<opcions>] [--] [<pathspec>...]" +#: builtin/commit.c msgid "" "You asked to amend the most recent commit, but doing so would make\n" "it empty. You can repeat your command with --allow-empty, or you can\n" @@ -4664,6 +5870,7 @@ msgstr "" "deixaria buida. Podeu repetir la vostra ordre amb --allow-empty, o\n" "podeu eliminar la comissió per complet amb «git reset HEAD^».\n" +#: builtin/commit.c msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" "If you wish to commit it anyway, use:\n" @@ -4678,12 +5885,15 @@ msgstr "" " git commit --allow-empty\n" "\n" +#: builtin/commit.c msgid "Otherwise, please use 'git rebase --skip'\n" msgstr "Altrament, si us plau useu «git rebase --skip»\n" +#: builtin/commit.c msgid "Otherwise, please use 'git cherry-pick --skip'\n" msgstr "Altrament, si us plau useu «git cherry-pick --skip»\n" +#: builtin/commit.c msgid "" "and then use:\n" "\n" @@ -4705,57 +5915,74 @@ msgstr "" " git cherry-pick --skip\n" "\n" +#: builtin/commit.c read-cache.c msgid "updating files failed" msgstr "s'ha produït un error en actualitzar els fitxers" +#: builtin/commit.c msgid "failed to unpack HEAD tree object" msgstr "s'ha produït un error en desempaquetar l'objecte d'arbre HEAD" +#: builtin/commit.c msgid "No paths with --include/--only does not make sense." msgstr "--include/--only no té sentit sense camí." +#: builtin/commit.c msgid "unable to create temporary index" msgstr "no s'ha pogut crear un índex temporal" +#: builtin/commit.c msgid "interactive add failed" msgstr "l'afegiment interactiu ha fallat" +#: builtin/commit.c msgid "unable to update temporary index" msgstr "no s'ha pogut actualitzar l'índex temporal" +#: builtin/commit.c msgid "Failed to update main cache tree" msgstr "S'ha produït un error en actualitzar l'arbre principal de memòria cau" +#: builtin/commit.c msgid "cannot do a partial commit during a merge." msgstr "no es pot fer una comissió parcial durant una fusió." +#: builtin/commit.c msgid "cannot do a partial commit during a cherry-pick." msgstr "no es pot fer una comissió parcial durant un «cherry pick»." +#: builtin/commit.c msgid "cannot do a partial commit during a rebase." msgstr "no es pot fer una comissió parcial durant un «rebase»." +#: builtin/commit.c msgid "cannot read the index" msgstr "no es pot llegir l'índex" +#: builtin/commit.c msgid "unable to write temporary index file" msgstr "no s'ha pogut escriure un fitxer d'índex temporal" +#: builtin/commit.c #, c-format msgid "commit '%s' lacks author header" msgstr "a la comissió «%s» li manca la capçalera d'autor" +#: builtin/commit.c #, c-format msgid "commit '%s' has malformed author line" msgstr "la comissió «%s» té una línia d'autor mal formada" +#: builtin/commit.c msgid "malformed --author parameter" msgstr "paràmetre --author mal format" +#: builtin/commit.c ident.c #, c-format msgid "invalid date format: %s" msgstr "format de data no vàlid: %s" +#: builtin/commit.c msgid "" "unable to select a comment character that is not used\n" "in the current commit message" @@ -4763,74 +5990,88 @@ msgstr "" "no es pot seleccionar un caràcter de comentari que\n" "no sigui usat en el missatge de comissió actual" +#: builtin/commit.c #, c-format msgid "could not lookup commit '%s'" msgstr "no s'ha pogut cercar la comissió «%s»" +#: builtin/commit.c builtin/shortlog.c #, c-format msgid "(reading log message from standard input)\n" msgstr "(s'està llegint el missatge de registre des de l'entrada estàndard)\n" +#: builtin/commit.c msgid "could not read log from standard input" msgstr "no s'ha pogut llegir el registre des de l'entrada estàndard" +#: builtin/commit.c #, c-format msgid "could not read log file '%s'" msgstr "no s'ha pogut llegir el fitxer de registre «%s»" +#: builtin/commit.c #, c-format msgid "options '%s' and '%s:%s' cannot be used together" msgstr "les opcions «%s» i «%s:%s» no es poden usar juntes" +#: builtin/commit.c msgid "could not read SQUASH_MSG" msgstr "no s'ha pogut llegir SQUASH_MSG" +#: builtin/commit.c msgid "could not read MERGE_MSG" msgstr "no s'ha pogut llegir MERGE_MSG" +#: builtin/commit.c bundle.c rerere.c sequencer.c #, c-format msgid "could not open '%s'" msgstr "no s'ha pogut obrir «%s»" +#: builtin/commit.c msgid "could not write commit template" msgstr "no s'ha pogut escriure la plantilla de comissió" +#: builtin/commit.c #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be ignored.\n" +"with '%s' will be ignored.\n" msgstr "" -"Introduïu el missatge de comissió per als vostres canvis.\n" -"S'ignoraran les línies que comencin amb «%c».\n" +"Introduïu el missatge de comissió per als vostres canvis. \n" +"S'ignoraran les línies que comencin amb «%s».\n" +#: builtin/commit.c #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be ignored, and an empty message aborts the commit.\n" +"with '%s' will be ignored, and an empty message aborts the commit.\n" msgstr "" "Introduïu el missatge de comissió dels vostres canvis.\n" -"S'ignoraran les línies que comencin amb «%c». Un missatge de\n" +"S'ignoraran les línies que comencin amb «%s». Un missatge de\n" "comissió buit avorta la comissió.\n" +#: builtin/commit.c #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be kept; you may remove them yourself if you want to.\n" +"with '%s' will be kept; you may remove them yourself if you want to.\n" msgstr "" "Introduïu el missatge de comissió pels vostres canvis. Es mantindran\n" -"les línies que comencin amb «%c»; podeu eliminar-les si voleu.\n" +"les línies que comencin amb «%s»; podeu eliminar-les vosaltres mateixos\n" +"si voleu.\n" +#: builtin/commit.c #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be kept; you may remove them yourself if you want to.\n" +"with '%s' will be kept; you may remove them yourself if you want to.\n" "An empty message aborts the commit.\n" msgstr "" "Introduïu el missatge de comissió dels vostres canvis.\n" -"Es mantindran les línies que comencin amb «%c»; podeu eliminar-les " -"vosaltres\n" -"mateixos si voleu. Un missatge buit avorta la comissió.\n" +"Es mantindran les línies que comencin amb «%s»; podeu eliminar-les \n" +"vosaltres mateixos si voleu. Un missatge buit avorta la comissió.\n" +#: builtin/commit.c msgid "" "\n" "It looks like you may be committing a merge.\n" @@ -4844,6 +6085,7 @@ msgstr "" "\tgit update-ref -d MERGE_HEAD\n" "i intenteu-ho de nou.\n" +#: builtin/commit.c msgid "" "\n" "It looks like you may be committing a cherry-pick.\n" @@ -4857,111 +6099,142 @@ msgstr "" "\tgit update-ref -d CHERRY_PICK_HEAD\n" "i intenteu-ho de nou.\n" +#: builtin/commit.c #, c-format msgid "%sAuthor: %.*s <%.*s>" msgstr "%sAutor: %.*s <%.*s>" +#: builtin/commit.c #, c-format msgid "%sDate: %s" msgstr "%sData: %s" +#: builtin/commit.c #, c-format msgid "%sCommitter: %.*s <%.*s>" msgstr "%sComitent: %.*s <%.*s>" +#: builtin/commit.c msgid "Cannot read index" msgstr "No es pot llegir l'índex" +#: builtin/commit.c builtin/tag.c msgid "unable to pass trailers to --trailers" msgstr "no s'han pogut passar els «trailers» a --trailers" +#: builtin/commit.c msgid "Error building trees" msgstr "Error en construir els arbres" +#: builtin/commit.c builtin/tag.c #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Especifiqueu el missatge usant l'opció -m o l'opció -F.\n" +#: builtin/commit.c #, c-format msgid "--author '%s' is not 'Name <email>' and matches no existing author" msgstr "" "--author «%s» no és «Nom <adreça-electrònica>» i no coincideix amb\n" "cap autor existent" +#: builtin/commit.c #, c-format msgid "Invalid ignored mode '%s'" msgstr "Mode d'ignorància no vàlid «%s»" +#: builtin/commit.c #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Mode de fitxers no seguits no vàlid «%s»" +#: builtin/commit.c msgid "You are in the middle of a merge -- cannot reword." msgstr "Esteu enmig d'una fusió -- no es pot fer «reword»." +#: builtin/commit.c msgid "You are in the middle of a cherry-pick -- cannot reword." msgstr "Esteu enmig d'un «cherry pick» -- no es pot fer «reword»." +#: builtin/commit.c #, c-format msgid "reword option of '%s' and path '%s' cannot be used together" msgstr "les opcions de «reword» «%s» i camí «%s» no es poden usar juntes" +#: builtin/commit.c #, c-format msgid "reword option of '%s' and '%s' cannot be used together" msgstr "les opcions de «reword» «%s» i «%s» no es poden usar juntes" +#: builtin/commit.c msgid "You have nothing to amend." msgstr "No teniu res a esmenar." +#: builtin/commit.c msgid "You are in the middle of a merge -- cannot amend." msgstr "Esteu enmig d'una fusió -- no es pot esmenar." +#: builtin/commit.c msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "Esteu enmig d'un «cherry pick» -- no es pot esmenar." +#: builtin/commit.c msgid "You are in the middle of a rebase -- cannot amend." msgstr "Esteu enmig d'un «rebase» -- no es pot esmenar." +#: builtin/commit.c msgid "--reset-author can be used only with -C, -c or --amend." msgstr "--reset-author només es pot usar amb -C, -c o --amend." +#: builtin/commit.c #, c-format msgid "unknown option: --fixup=%s:%s" msgstr "opció desconeguda: --fixup=%s:%s" +#: builtin/commit.c #, c-format msgid "paths '%s ...' with -a does not make sense" msgstr "els camins «%s ...» amb -a no tenen sentit" +#: builtin/commit.c msgid "show status concisely" msgstr "mostra l'estat concisament" +#: builtin/commit.c msgid "show branch information" msgstr "mostra la informació de branca" +#: builtin/commit.c msgid "show stash information" msgstr "mostra la informació de «stash»" +#: builtin/commit.c msgid "compute full ahead/behind values" msgstr "calcula els valors complets endavant/darrere" +#: builtin/commit.c msgid "version" msgstr "versió" +#: builtin/commit.c builtin/fetch.c builtin/push.c builtin/worktree.c msgid "machine-readable output" msgstr "sortida llegible per una màquina" +#: builtin/commit.c msgid "show status in long format (default)" msgstr "mostra l'estat en format llarg (per defecte)" +#: builtin/commit.c msgid "terminate entries with NUL" msgstr "acaba les entrades amb NUL" +#: builtin/commit.c msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" "mostra els fitxers no seguits, modes opcionals: all, normal, no. (Per " "defecte: all)" +#: builtin/commit.c msgid "" "show ignored files, optional modes: traditional, matching, no. (Default: " "traditional)" @@ -4969,9 +6242,11 @@ msgstr "" "mostra els fitxers ignorats, modes opcionals: traditional, matching, no. " "(Per defecte: traditional, matching, no.)" +#: builtin/commit.c parse-options.h msgid "when" msgstr "quan" +#: builtin/commit.c msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -4979,153 +6254,199 @@ msgstr "" "ignora els canvis als submòduls, opcional quan: all, dirty, untracked. (Per " "defecte: all)" +#: builtin/commit.c msgid "list untracked files in columns" msgstr "mostra els fitxers no seguits en columnes" +#: builtin/commit.c msgid "do not detect renames" msgstr "no detectis canvis de noms" +#: builtin/commit.c msgid "detect renames, optionally set similarity index" msgstr "detecta canvis de noms, i opcionalment estableix un índex de semblança" +#: builtin/commit.c msgid "Unsupported combination of ignored and untracked-files arguments" msgstr "" "No s'admet la combinació d'arguments d'ignorància i de fitxers no seguits" +#: builtin/commit.c msgid "suppress summary after successful commit" msgstr "omet el resum després d'una comissió reeixida" +#: builtin/commit.c msgid "show diff in commit message template" msgstr "mostra la diferència en la plantilla de missatge de comissió" +#: builtin/commit.c msgid "Commit message options" msgstr "Opcions de missatge de comissió" +#: builtin/commit.c builtin/merge.c builtin/tag.c msgid "read message from file" msgstr "llegeix el missatge des d'un fitxer" +#: builtin/commit.c msgid "author" msgstr "autor" +#: builtin/commit.c msgid "override author for commit" msgstr "sobreescriu l'autor de la comissió" +#: builtin/commit.c builtin/gc.c msgid "date" msgstr "data" +#: builtin/commit.c msgid "override date for commit" msgstr "sobreescriu la data de la comissió" +#: builtin/commit.c parse-options.h ref-filter.h msgid "commit" msgstr "comissió" +#: builtin/commit.c msgid "reuse and edit message from specified commit" msgstr "reusa i edita el missatge de la comissió especificada" +#: builtin/commit.c msgid "reuse message from specified commit" msgstr "reusa el missatge de la comissió especificada" #. TRANSLATORS: Leave "[(amend|reword):]" as-is, #. and only translate <commit>. #. +#: builtin/commit.c msgid "[(amend|reword):]commit" msgstr "[(amend|reword):]commit" +#: builtin/commit.c msgid "" "use autosquash formatted message to fixup or amend/reword specified commit" msgstr "" -"usa un missatge amb format de «squash» automàtic per a esmenar la comissió " -"especificada" +"usa un missatge amb format de «squash» automàtic per a fer amend/reword de " +"la comissió especificada" +#: builtin/commit.c msgid "use autosquash formatted message to squash specified commit" msgstr "" "usa un missatge amb format de «squash» automàtic per a fer «squash» de la " "comissió especificada" +#: builtin/commit.c msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "l'autor de la comissió soc jo ara (s'usa amb -C/-c/--amend)" +#: builtin/commit.c builtin/interpret-trailers.c builtin/tag.c msgid "trailer" msgstr "remolc" +#: builtin/commit.c builtin/tag.c msgid "add custom trailer(s)" msgstr "afegeix un «trailer» personalitzat" +#: builtin/commit.c builtin/log.c builtin/merge.c builtin/pull.c +#: builtin/revert.c msgid "add a Signed-off-by trailer" msgstr "afegeix un «trailer» tipus «Signed-off-by»" +#: builtin/commit.c msgid "use specified template file" msgstr "usa el fitxer de plantilla especificat" +#: builtin/commit.c msgid "force edit of commit" msgstr "força l'edició de la comissió" +#: builtin/commit.c msgid "include status in commit message template" msgstr "inclou l'estat en la plantilla de missatge de comissió" +#: builtin/commit.c msgid "Commit contents options" msgstr "Opcions per al contingut de les comissions" +#: builtin/commit.c msgid "commit all changed files" msgstr "comet tots els fitxers canviats" +#: builtin/commit.c msgid "add specified files to index for commit" msgstr "afegeix els fitxers especificats a l'índex per a cometre" +#: builtin/commit.c msgid "interactively add files" msgstr "afegeix els fitxers interactivament" +#: builtin/commit.c msgid "interactively add changes" msgstr "afegeix els canvis interactivament" +#: builtin/commit.c msgid "commit only specified files" msgstr "comet només els fitxers especificats" +#: builtin/commit.c msgid "bypass pre-commit and commit-msg hooks" msgstr "evita els lligams de precomissió i missatge de comissió" +#: builtin/commit.c msgid "show what would be committed" msgstr "mostra què es cometria" +#: builtin/commit.c msgid "amend previous commit" msgstr "esmena la comissió anterior" +#: builtin/commit.c msgid "bypass post-rewrite hook" msgstr "evita el lligam de post escriptura" +#: builtin/commit.c msgid "ok to record an empty change" msgstr "està bé registrar un canvi buit" +#: builtin/commit.c msgid "ok to record a change with an empty message" msgstr "està bé registrar un canvi amb missatge buit" +#: builtin/commit.c sequencer.c msgid "could not parse HEAD commit" msgstr "no s'ha pogut analitzar la comissió HEAD" +#: builtin/commit.c #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Fitxer MERGE_HEAD malmès (%s)" +#: builtin/commit.c msgid "could not read MERGE_MODE" msgstr "no s'ha pogut llegir MERGE_MODE" +#: builtin/commit.c #, c-format msgid "could not read commit message: %s" msgstr "no s'ha pogut llegir el missatge de comissió: %s" +#: builtin/commit.c #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "S'està avortant la comissió a causa d'un missatge de comissió buit.\n" +#: builtin/commit.c #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "S'està avortant la comissió; no heu editat el missatge.\n" +#: builtin/commit.c #, c-format msgid "Aborting commit due to empty commit message body.\n" msgstr "" "S'està interrompent la comissió a causa d'un missatge de comissió buit.\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" @@ -5136,183 +6457,230 @@ msgstr "" "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>]" +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "git config list [<file-option>] [<display-option>] [--includes]" +msgstr "git config list [<opció-fitxer>] [<opció-presentació>] [--includes]" -#, c-format -msgid "unrecognized --type argument, %s" -msgstr "argument --type no reconegut, %s" +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +msgstr "" +"git config get [<opció-fitxer>] [<opció-presentació>] [--includes] [--all] " +"[--regexp] [--value=<valor>] [--fixed-value] [--default=<default>] <nom>" -msgid "only one type at a time" -msgstr "només un tipus cada cop" +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" +"fixed-value] <name> <value>" +msgstr "" +"git config set [<opció-fitxer>] [--type=<tipus>] [--all] [--value=<valor>] " +"[--fixed-value] <nom> <valor>" + +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "" +"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"<name> <value>" +msgstr "" +"git config unset [<opció-fitxer>] [--all] [--value=<valor>] [--fixed-value] " +"<name> <valor>" + +#: builtin/config.c +msgid "git config rename-section [<file-option>] <old-name> <new-name>" +msgstr "git config rename-section [<opció-fitxer>] <nom-vell> <nom-nou>" + +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "git config remove-section [<file-option>] <name>" +msgstr "git config remove-section [<opció-fitxer>] <nom>" + +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "git config edit [<file-option>]" +msgstr "git config edit [<opció-fitxer>]" + +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" +msgstr "git config [<opció-fitxer>] --get-colorbool <nom> [<stdout-is-tty>]" +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<opció-fitxer>] [<opció-presentació>] [--includes] [--all] " +"[--regexp=<expr-reg>] [--value=<valor>] [--fixed-value] [--" +"default=<default>] <nom>" + +# Cal traduir els paràmetres amb <...>? +#: builtin/config.c +msgid "" +"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " +"[--value=<value>] [--fixed-value] <name> <value>" +msgstr "" +"git config set [<opció-fitxer>] [--type=<tipus>] [--comment=<missatge>] [--" +"all] [--value=<valor>] [--fixed-value] <nom> <valor>" + +#: builtin/config.c msgid "Config file location" msgstr "Ubicació del fitxer de configuració" +#: builtin/config.c msgid "use global config file" msgstr "usa el fitxer de configuració global" +#: builtin/config.c msgid "use system config file" msgstr "usa el fitxer de configuració del sistema" +#: builtin/config.c msgid "use repository config file" msgstr "usa el fitxer de configuració del repositori" +#: builtin/config.c msgid "use per-worktree config file" msgstr "usa un fitxer de configuració per repositori" +#: builtin/config.c builtin/gc.c msgid "use given config file" msgstr "usa el fitxer de configuració donat" +#: builtin/config.c msgid "blob-id" msgstr "ID de blob" +#: builtin/config.c msgid "read config from given blob object" msgstr "llegeix la configuració de l'objecte de blob donat" -msgid "Action" -msgstr "Acció" - -msgid "get value: name [value-pattern]" -msgstr "obtén valor: nom [value-pattern]" - -msgid "get all values: key [value-pattern]" -msgstr "obtén tots els valors: clau [value-pattern]" - -msgid "get values for regexp: name-regex [value-pattern]" -msgstr "obtén valors de regexp: name-regex [value-pattern]" - -msgid "get value specific for the URL: section[.var] URL" -msgstr "obtén el valor específic per a l'URL: secció[.variable] URL" - -msgid "replace all matching variables: name value [value-pattern]" -msgstr "" -"reemplaça totes les variables que coincideixen: nom valor [value-pattern]" - -msgid "add a new variable: name value" -msgstr "afegeix una variable nova: nom valor" - -msgid "remove a variable: name [value-pattern]" -msgstr "elimina una variable: nom [value-pattern]" - -msgid "remove all matches: name [value-pattern]" -msgstr "elimina totes les coincidències: nom [value-pattern]" - -msgid "rename section: old-name new-name" -msgstr "canvia el nom de secció: nom-antic nom-nou" - -msgid "remove a section: name" -msgstr "elimina una secció: nom" - -msgid "list all" -msgstr "llista'ls tots" - -msgid "use string equality when comparing values to 'value-pattern'" -msgstr "" -"usa la igualtat de les cadenes quan es comparen els valors amb «value-" -"pattern»" - -msgid "open an editor" -msgstr "obre un editor" - -msgid "find the color configured: slot [default]" -msgstr "troba el color configurat: ranura [per defecte]" - -msgid "find the color setting: slot [stdout-is-tty]" -msgstr "troba el paràmetre de color: ranura [stdout-és-tty]" - +#: builtin/config.c msgid "Type" msgstr "Tipus" +#: builtin/config.c builtin/hash-object.c msgid "type" msgstr "tipus" +#: builtin/config.c msgid "value is given this type" msgstr "el valor és d'aquest tipus que s'ha donat" +#: builtin/config.c msgid "value is \"true\" or \"false\"" msgstr "el valor és «true» o «false»" +#: builtin/config.c msgid "value is decimal number" msgstr "el valor és un nombre decimal" +#: builtin/config.c msgid "value is --bool or --int" msgstr "el valor és --bool o --int" +#: builtin/config.c msgid "value is --bool or string" msgstr "el valor és --bool o string" +#: builtin/config.c msgid "value is a path (file or directory name)" msgstr "el valor és un camí (nom de fitxer o directori)" +#: builtin/config.c msgid "value is an expiry date" msgstr "el valor és una data de venciment" -msgid "Other" -msgstr "Altre" +#: builtin/config.c +msgid "Display options" +msgstr "Opcions de visualització" +#: builtin/config.c msgid "terminate values with NUL byte" msgstr "acaba els valors amb un octet NUL" +#: builtin/config.c msgid "show variable names only" msgstr "mostra només els noms de variable" -msgid "respect include directives on lookup" -msgstr "respecta les directives d'inclusió en cercar" - +#: builtin/config.c msgid "show origin of config (file, standard input, blob, command line)" msgstr "" "mostra l'origen de la configuració (fitxer, entrada estàndard, blob, línia " "d'ordres)" +#: builtin/config.c msgid "show scope of config (worktree, local, global, system, command)" msgstr "" "mostra l'abast de la configuració («worktree», «local», «global», «system», " "«command»)" -msgid "value" -msgstr "valor" +#: builtin/config.c +msgid "show config keys in addition to their values" +msgstr "mostra les claus de configuració a més dels seus valors" -msgid "with --get, use default value when missing entry" -msgstr "amb --get utilitza el valor per defecte quan falti una entrada" +#: builtin/config.c +#, c-format +msgid "unrecognized --type argument, %s" +msgstr "argument --type no reconegut, %s" + +#: builtin/config.c +msgid "only one type at a time" +msgstr "només un tipus cada cop" +#: builtin/config.c #, c-format msgid "wrong number of arguments, should be %d" msgstr "nombre d'arguments erroni, ha de ser %d" +#: builtin/config.c #, c-format msgid "wrong number of arguments, should be from %d to %d" msgstr "nombre d'arguments erroni, ha de ser %d a %d" +#: builtin/config.c #, c-format msgid "invalid key pattern: %s" msgstr "patró de la clau no vàlid: %s" +#: builtin/config.c config.c #, c-format msgid "invalid pattern: %s" msgstr "patró no vàlid: %s" +#: builtin/config.c #, c-format msgid "failed to format default config value: %s" msgstr "" "s'ha produït un error en formatar el valor per defecte de la configuració: %s" +#: builtin/config.c #, c-format msgid "cannot parse color '%s'" msgstr "no es pot analitzar el color «%s»" +#: builtin/config.c msgid "unable to parse default color value" msgstr "no s'ha pogut analitzar el valor de color per defecte" +#: builtin/config.c msgid "not in a git directory" msgstr "no és en un directori git" +#: builtin/config.c msgid "writing to stdin is not supported" msgstr "no s'admet escriure a stdin" +#: builtin/config.c msgid "writing config blobs is not supported" msgstr "no s'admet l'escriptura de blobs de configuració" +#: builtin/config.c #, c-format msgid "" "# This is Git's per-user configuration file.\n" @@ -5327,21 +6695,27 @@ msgstr "" "#\tname = %s\n" "#\temail = %s\n" +#: builtin/config.c msgid "only one config file at a time" msgstr "només un fitxer de configuració cada cop" +#: builtin/config.c msgid "--local can only be used inside a git repository" msgstr "--local només es pot usar dins d'un repositori git" +#: builtin/config.c msgid "--blob can only be used inside a git repository" msgstr "--blob només es pot usar dins d'un repositori git" +#: builtin/config.c msgid "--worktree can only be used inside a git repository" msgstr "--worktree només es pot usar dins d'un repositori git" +#: builtin/config.c builtin/gc.c msgid "$HOME not set" msgstr "$HOME no està establerta" +#: builtin/config.c msgid "" "--worktree cannot be used with multiple working trees unless the config\n" "extension worktreeConfig is enabled. Please read \"CONFIGURATION FILE\"\n" @@ -5351,44 +6725,102 @@ msgstr "" "l'extensió de configuració worktreeConfig estigui habilitada. Llegiu la " "secció «CONFIGURATION FILE» a «git help worktree» per a més detalls" -msgid "--get-color and variable type are incoherent" -msgstr "--get-color i el tipus de variable són incoherents" +#: builtin/config.c +msgid "Other" +msgstr "Altre" -msgid "only one action at a time" -msgstr "només una acció cada cop" +#: builtin/config.c +msgid "respect include directives on lookup" +msgstr "respecta les directives d'inclusió en cercar" -msgid "--name-only is only applicable to --list or --get-regexp" -msgstr "--name-only només és aplicable a --list o --get-regexp" +#: builtin/config.c +#, c-format +msgid "unable to read config file '%s'" +msgstr "no s'ha pogut llegir el fitxer de configuració «%s»" -msgid "" -"--show-origin is only applicable to --get, --get-all, --get-regexp, and --" -"list" +#: builtin/config.c +msgid "error processing config file(s)" +msgstr "s'ha produït un error en processar els fitxers de configuració" + +#: builtin/config.c +msgid "Filter options" +msgstr "Opcions de filtre" + +# multi-valued → multivalor? +#: builtin/config.c +msgid "return all values for multi-valued config options" +msgstr "retorna tots els valors per a les opcions de configuració multivalor" + +#: builtin/config.c +msgid "interpret the name as a regular expression" +msgstr "interpreta el nom com una expressió regular" + +#: builtin/config.c +msgid "show config with values matching the pattern" +msgstr "mostra la configuració amb els valors coincidents amb el patró" + +#: builtin/config.c +msgid "use string equality when comparing values to value pattern" msgstr "" -"--show-origin només és aplicable a --get, --get-all, --get-regexp, i --list" +"usa la igualtat de cadenes quan es comparen els valors amb el patró de valor" -msgid "--default is only applicable to --get" -msgstr "--default només és aplicable a --get" +#: builtin/config.c +msgid "URL" +msgstr "URL" + +#: builtin/config.c +msgid "show config matching the given URL" +msgstr "mostra la configuració coincident amb l'URL indicat" + +#: builtin/config.c +msgid "value" +msgstr "valor" + +#: builtin/config.c +msgid "use default value when missing entry" +msgstr "utilitza el valor per defecte quan falti una entrada" +#: builtin/config.c msgid "--fixed-value only applies with 'value-pattern'" msgstr "--fixed-value només s'aplica amb «value-pattern»" -#, c-format -msgid "unable to read config file '%s'" -msgstr "no s'ha pogut llegir el fitxer de configuració «%s»" +#: builtin/config.c +msgid "--default= cannot be used with --all or --url=" +msgstr "--default= no es pot utilitzar amb --all o --url=" -msgid "error processing config file(s)" -msgstr "s'ha produït un error en processar els fitxers de configuració" +#: builtin/config.c +msgid "--url= cannot be used with --all, --regexp or --value" +msgstr "--url= no es pot usar amb --all, --regexp o --value" -msgid "editing stdin is not supported" -msgstr "no hi ha compatibilitat per a l'edició a stdin" +#: builtin/config.c +msgid "Filter" +msgstr "Filtra" -msgid "editing blobs is not supported" -msgstr "no hi ha compatibilitat per l'edició de blobs" +# multi-valued → multivalor? +#: builtin/config.c +msgid "replace multi-valued config option with new value" +msgstr "reemplaça l'opció de configuració multivalor amb el valor nou" -#, c-format -msgid "cannot create configuration file %s" -msgstr "no es pot crear el fitxer de configuració %s" +#: builtin/config.c +msgid "human-readable comment string (# will be prepended as needed)" +msgstr "" +"cadena de comentari llegible per humans (es farà que comence per\n" +"# si cal)" + +#: builtin/config.c +msgid "add a new line without altering any existing values" +msgstr "afegeix una línia nova sense alterar cap dels valors existents" +# only applies → només funciona? +#: builtin/config.c +msgid "--fixed-value only applies with --value=<pattern>" +msgstr "--fixed-value només s'aplica amb --value=<patró>" + +#: builtin/config.c +msgid "--append cannot be used with --value=<pattern>" +msgstr "no es pot utilitzar --append amb --value=<patró>" + +#: builtin/config.c #, c-format msgid "" "cannot overwrite multiple values with a single value\n" @@ -5397,13 +6829,128 @@ msgstr "" "no es poden sobreescriure múltiples valors amb un sol valor\n" " Useu una expressió regular, --add o --replace-all per a canviar %s." +#: builtin/config.c #, c-format msgid "no such section: %s" msgstr "no existeix la secció: %s" +#: builtin/config.c +msgid "editing stdin is not supported" +msgstr "no hi ha compatibilitat per a l'edició a stdin" + +#: builtin/config.c +msgid "editing blobs is not supported" +msgstr "no hi ha compatibilitat per l'edició de blobs" + +#: builtin/config.c +#, c-format +msgid "cannot create configuration file %s" +msgstr "no es pot crear el fitxer de configuració %s" + +#: builtin/config.c +msgid "Action" +msgstr "Acció" + +#: builtin/config.c +msgid "get value: name [<value-pattern>]" +msgstr "get value: nom [<patró-valors>]" + +#: builtin/config.c +msgid "get all values: key [<value-pattern>]" +msgstr "obté tots els valors: clau [<patró-valors>]" + +# he traduit el nom del paràmetre +#: builtin/config.c +msgid "get values for regexp: name-regex [<value-pattern>]" +msgstr "" +"obté els valors per a l'expressió regular: expressio-regular-nom [<patró-" +"valors>]" + +#: builtin/config.c +msgid "get value specific for the URL: section[.var] URL" +msgstr "obtén el valor específic per a l'URL: secció[.variable] URL" + +# he traduït els noms dels paràmetres +#: builtin/config.c +msgid "replace all matching variables: name value [<value-pattern>]" +msgstr "" +"reemplaça totes les variables que coincideixin: nom valor [<patró-valors>]" + +#: builtin/config.c +msgid "add a new variable: name value" +msgstr "afegeix una variable nova: nom valor" + +# cal traduir name? +#: builtin/config.c +msgid "remove a variable: name [<value-pattern>]" +msgstr "elimina una variable: nom [<patró-valors>]" + +#: builtin/config.c +msgid "remove all matches: name [<value-pattern>]" +msgstr "elimina totes les coincidències: nom [<patró-valors>]" + +#: builtin/config.c +msgid "rename section: old-name new-name" +msgstr "canvia el nom de secció: nom-antic nom-nou" + +#: builtin/config.c +msgid "remove a section: name" +msgstr "elimina una secció: nom" + +#: builtin/config.c +msgid "list all" +msgstr "llista'ls tots" + +#: builtin/config.c +msgid "open an editor" +msgstr "obre un editor" + +# slot → ??? ; <default> → ??? +#: builtin/config.c +msgid "find the color configured: slot [<default>]" +msgstr "troba el color configurat: slot [<default>]" + +#: builtin/config.c +msgid "find the color setting: slot [<stdout-is-tty>]" +msgstr "troba la configuració de color: slot [<stdout-is-tty>]" + +#: builtin/config.c +msgid "with --get, use default value when missing entry" +msgstr "amb --get utilitza el valor per defecte quan falti una entrada" + +#: builtin/config.c +msgid "--get-color and variable type are incoherent" +msgstr "--get-color i el tipus de variable són incoherents" + +#: builtin/config.c +msgid "no action specified" +msgstr "no s'ha especificat cap acció" + +#: builtin/config.c +msgid "--name-only is only applicable to --list or --get-regexp" +msgstr "--name-only només és aplicable a --list o --get-regexp" + +#: builtin/config.c +msgid "" +"--show-origin is only applicable to --get, --get-all, --get-regexp, and --" +"list" +msgstr "" +"--show-origin només és aplicable a --get, --get-all, --get-regexp, i --list" + +#: builtin/config.c +msgid "--default is only applicable to --get" +msgstr "--default només és aplicable a --get" + +# add/set/replace sense traduir, entenc +#: builtin/config.c +msgid "--comment is only applicable to add/set/replace operations" +msgstr "--comment només es pot aplicar a operacions add/set/replace" + +#: builtin/count-objects.c msgid "print sizes in human readable format" msgstr "imprimeix les mides en un format llegible pels humans" +#: builtin/credential-cache--daemon.c #, c-format msgid "" "The permissions on your socket directory are too loose; other\n" @@ -5417,67 +6964,83 @@ msgstr "" "\n" "\tchmod 0700 %s" +#: builtin/credential-cache--daemon.c msgid "print debugging messages to stderr" msgstr "imprimeix els missatges de depuració a stderr" +#: builtin/credential-cache--daemon.c msgid "credential-cache--daemon unavailable; no unix socket support" msgstr "" "credential-cache--daemon no disponible; no hi ha compatibilitat amb sòcols " "d'unix" +#: builtin/credential-cache.c msgid "credential-cache unavailable; no unix socket support" msgstr "" "credencial-cache no disponible; no hi ha compatibilitat amb els sòcols d'unix" +#: builtin/credential-store.c #, c-format msgid "unable to get credential storage lock in %d ms" msgstr "" "no s'ha pogut obtenir el bloqueig de l'emmagatzematge de credencials en %d ms" +#: builtin/describe.c msgid "" "git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]" msgstr "" "git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]" +#: builtin/describe.c msgid "" "git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]" msgstr "" "git describe [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]" +#: builtin/describe.c msgid "git describe <blob>" msgstr "git describe <blob>" +#: builtin/describe.c msgid "head" msgstr "davant per" +#: builtin/describe.c msgid "lightweight" msgstr "lleuger" +#: builtin/describe.c msgid "annotated" msgstr "anotat" +#: builtin/describe.c #, c-format msgid "annotated tag %s not available" msgstr "l'etiqueta anotada %s no és disponible" +#: builtin/describe.c #, c-format msgid "tag '%s' is externally known as '%s'" msgstr "l'etiqueta «%s» es coneix externament com a «%s»" +#: builtin/describe.c #, c-format msgid "no tag exactly matches '%s'" msgstr "cap etiqueta coincideix exactament amb «%s»" +#: builtin/describe.c #, c-format msgid "No exact match on refs or tags, searching to describe\n" msgstr "" "No hi ha cap coincidència exacta en la cerca de referències o etiquetes per " "a descriure\n" +#: builtin/describe.c #, c-format msgid "finished search at %s\n" msgstr "s'ha finalitzat la cerca a %s\n" +#: builtin/describe.c #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -5486,6 +7049,7 @@ msgstr "" "Cap etiqueta anotada pot descriure «%s».\n" "No obstant això, hi havia etiquetes no anotades: proveu --tags." +#: builtin/describe.c #, c-format msgid "" "No tags can describe '%s'.\n" @@ -5494,10 +7058,12 @@ msgstr "" "Cap etiqueta pot descriure «%s».\n" "Proveu --always, o creeu algunes etiquetes." +#: builtin/describe.c #, c-format msgid "traversed %lu commits\n" msgstr "%lu comissions recorregudes\n" +#: builtin/describe.c #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -5506,67 +7072,87 @@ msgstr "" "s'han trobat més de %i etiquetes: s'han llistat les %i més recents\n" "s'ha renunciat la cerca a %s\n" +#: builtin/describe.c #, c-format msgid "describe %s\n" msgstr "descriu %s\n" +#: builtin/describe.c #, c-format msgid "Not a valid object name %s" msgstr "%s no és un nom d'objecte vàlid" +#: builtin/describe.c #, c-format msgid "%s is neither a commit nor blob" msgstr "%s no és una comissió o un blob" +#: builtin/describe.c msgid "find the tag that comes after the commit" msgstr "troba l'etiqueta que vingui després de la comissió" +#: builtin/describe.c msgid "debug search strategy on stderr" msgstr "estratègia de cerca de depuració en stderr" +#: builtin/describe.c msgid "use any ref" msgstr "usa qualsevol referència" +#: builtin/describe.c msgid "use any tag, even unannotated" msgstr "usa qualsevol etiqueta, fins i tot aquelles sense anotar" +#: builtin/describe.c msgid "always use long format" msgstr "sempre usa el format llarg" +#: builtin/describe.c msgid "only follow first parent" msgstr "només segueix el primer pare" +#: builtin/describe.c msgid "only output exact matches" msgstr "emet només coincidències exactes" +#: builtin/describe.c msgid "consider <n> most recent tags (default: 10)" msgstr "considera les <n> etiquetes més recents (per defecte: 10)" +#: builtin/describe.c msgid "only consider tags matching <pattern>" msgstr "només considera les etiquetes que coincideixen amb <patró>" +#: builtin/describe.c msgid "do not consider tags matching <pattern>" msgstr "no consideris les etiquetes que no coincideixen amb <patró>" +#: builtin/describe.c builtin/name-rev.c msgid "show abbreviated commit object as fallback" msgstr "mostra l'objecte de comissió abreviat com a sistema alternatiu" +#: builtin/describe.c msgid "mark" msgstr "marca" +#: builtin/describe.c msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "annexa <marca> en l'arbre de treball brut (per defecte: «-dirty»)" +#: builtin/describe.c msgid "append <mark> on broken working tree (default: \"-broken\")" msgstr "annexa <marca> en l'arbre de treball brut (per defecte: «-broken»)" +#: builtin/describe.c msgid "No names found, cannot describe anything." msgstr "No s'ha trobat cap nom, no es pot descriure res." +#: builtin/describe.c #, c-format msgid "option '%s' and commit-ishes cannot be used together" msgstr "opció «%s» i les de comissió no es poden usar juntes" +#: builtin/diagnose.c msgid "" "git diagnose [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n" " [--mode=<mode>]" @@ -5574,67 +7160,85 @@ msgstr "" "git diagnose [(-o | --output-directory) <camí>] [(-s | --suffix) <format>]\n" " [--mode=<mode>]" +#: builtin/diagnose.c msgid "specify a destination for the diagnostics archive" msgstr "especifiqueu una destinació per a l'arxiu de diagnòstic" +#: builtin/diagnose.c msgid "specify a strftime format suffix for the filename" msgstr "especifiqueu un sufix en format strftime per al nom de fitxer" +#: builtin/diagnose.c msgid "specify the content of the diagnostic archive" msgstr "especifica el contingut de l'arxiu de diagnòstic" +#: builtin/diff-tree.c msgid "--merge-base only works with two commits" msgstr "--merge-base només funciona amb dues comissions" +#: builtin/diff.c #, c-format msgid "'%s': not a regular file or symlink" msgstr "«%s»: no és ni fitxer regular ni enllaç simbòlic" +#: builtin/diff.c msgid "no merge given, only parents." msgstr "no s'ha donat cap fusió, només els pares." +#: builtin/diff.c #, c-format msgid "invalid option: %s" msgstr "opció no vàlida: %s" +#: builtin/diff.c #, c-format msgid "%s...%s: no merge base" msgstr "%s...%s: sense una base de fusió" +#: builtin/diff.c msgid "Not a git repository" msgstr "No és un repositori de git" +#: builtin/diff.c builtin/grep.c #, c-format msgid "invalid object '%s' given." msgstr "s'ha donat un objecte no vàlid «%s»." +#: builtin/diff.c #, c-format msgid "more than two blobs given: '%s'" msgstr "s'ha donat més de dos blobs: «%s»" +#: builtin/diff.c #, c-format msgid "unhandled object '%s' given." msgstr "s'ha donat l'objecte no gestionat «%s»." +#: builtin/diff.c #, c-format msgid "%s...%s: multiple merge bases, using %s" msgstr "%s...%s: múltiples bases de fusió, utilitzant %s" +#: builtin/difftool.c msgid "git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]" msgstr "git difftool [<opcions>] [<comissió> [<comissió>]] [--] [<camí>...]" +#: builtin/difftool.c #, c-format msgid "could not read symlink %s" msgstr "no s'ha pogut llegir l'enllaç simbòlic %s" +#: builtin/difftool.c #, c-format msgid "could not read symlink file %s" msgstr "no s'ha pogut llegir el fitxer d'enllaç simbòlic %s" +#: builtin/difftool.c #, c-format msgid "could not read object %s for symlink %s" msgstr "no es pot llegir l'objecte %s per l'enllaç simbòlic %s" +#: builtin/difftool.c msgid "" "combined diff formats ('-c' and '--cc') are not supported in\n" "directory diff mode ('-d' and '--dir-diff')." @@ -5642,50 +7246,64 @@ msgstr "" "els formats de diff combinats («-c» i «--cc») no s'admeten\n" "en el mode diff de directoris («-d» i «--dir-diff»)." +#: builtin/difftool.c #, c-format msgid "both files modified: '%s' and '%s'." msgstr "s'han modificat ambdós fitxers: «%s» i «%s»." +#: builtin/difftool.c msgid "working tree file has been left." msgstr "s'ha deixat un fitxer de l'arbre de treball." +#: builtin/difftool.c sequencer.c #, c-format msgid "could not copy '%s' to '%s'" msgstr "no s'ha pogut copiar «%s» a «%s»" +#: builtin/difftool.c #, c-format msgid "temporary files exist in '%s'." msgstr "existeix un fitxer temporal a «%s»." +#: builtin/difftool.c msgid "you may want to cleanup or recover these." msgstr "podeu netejar o recuperar-los." +#: builtin/difftool.c #, c-format msgid "failed: %d" msgstr "ha fallat: %d" +#: builtin/difftool.c msgid "use `diff.guitool` instead of `diff.tool`" msgstr "usa «diff.guitool» en lloc de «diff.tool»" +#: builtin/difftool.c msgid "perform a full-directory diff" msgstr "fes un diff de tot el directori" +#: builtin/difftool.c msgid "do not prompt before launching a diff tool" msgstr "no preguntis abans d'executar l'eina diff" +#: builtin/difftool.c msgid "use symlinks in dir-diff mode" msgstr "utilitza enllaços simbòlics en mode dir-diff" +#: builtin/difftool.c msgid "tool" msgstr "eina" +#: builtin/difftool.c msgid "use the specified diff tool" msgstr "utilitza l'eina de diff especificada" +#: builtin/difftool.c msgid "print a list of diff tools that may be used with `--tool`" msgstr "" "imprimeix una llista de totes les eines diff que podeu usar amb «--tool»" +#: builtin/difftool.c msgid "" "make 'git-difftool' exit when an invoked diff tool returns a non-zero exit " "code" @@ -5693,187 +7311,241 @@ msgstr "" "fes que «git-difftool» surti quan l'eina de diff invocada torna un codi de " "sortida diferent de zero" +#: builtin/difftool.c msgid "specify a custom command for viewing diffs" msgstr "especifiqueu una ordre personalitzada per a veure diffs" +#: builtin/difftool.c msgid "passed to `diff`" msgstr "passa-ho a «diff»" +#: builtin/difftool.c msgid "difftool requires worktree or --no-index" msgstr "difftool requereix worktree o --no-index" +#: builtin/difftool.c msgid "no <tool> given for --tool=<tool>" msgstr "no s'ha proporcionat l'<eina> per a --tool=<eina>" +#: builtin/difftool.c msgid "no <cmd> given for --extcmd=<cmd>" msgstr "no s'ha proporcionat l'<ordre> per a --extcmd=<ordre>" +#: builtin/fast-export.c msgid "git fast-export [<rev-list-opts>]" msgstr "git fast-export [<rev-list-opts>]" +#: builtin/fast-export.c msgid "Error: Cannot export nested tags unless --mark-tags is specified." msgstr "" "Error: no es poden exportar les etiquetes imbricades a menys que " "s'especifiqui --mark-tags." +#: builtin/fast-export.c msgid "--anonymize-map token cannot be empty" msgstr "el testimoni de --anonymize-map no pot estar buit" +#: builtin/fast-export.c msgid "show progress after <n> objects" msgstr "mostra el progrés després de <n> objectes" +#: builtin/fast-export.c msgid "select handling of signed tags" msgstr "selecciona la gestió de les etiquetes signades" +#: builtin/fast-export.c msgid "select handling of tags that tag filtered objects" msgstr "selecciona la gestió de les etiquetes que etiquetin objectes filtrats" +#: builtin/fast-export.c msgid "select handling of commit messages in an alternate encoding" msgstr "" "selecciona la gestió dels missatges de comissió en una codificació " "alternativa" +#: builtin/fast-export.c msgid "dump marks to this file" msgstr "bolca les marques a aquest fitxer" +#: builtin/fast-export.c msgid "import marks from this file" msgstr "importa les marques d'aquest fitxer" +#: builtin/fast-export.c msgid "import marks from this file if it exists" msgstr "importa marques d'aquest fitxer si existeix" +#: builtin/fast-export.c msgid "fake a tagger when tags lack one" msgstr "fingeix un etiquetador quan en falti un a les etiquetes" +#: builtin/fast-export.c msgid "output full tree for each commit" msgstr "imprimeix l'arbre complet de per a cada comissió" +#: builtin/fast-export.c msgid "use the done feature to terminate the stream" msgstr "usa la característica fet per a acabar el flux" +#: builtin/fast-export.c msgid "skip output of blob data" msgstr "omet la sortida de dades de blob" +#: builtin/fast-export.c builtin/log.c msgid "refspec" msgstr "especificació de referència" +#: builtin/fast-export.c msgid "apply refspec to exported refs" msgstr "aplica l'especificació de referència a les referències exportades" +#: builtin/fast-export.c msgid "anonymize output" msgstr "anonimitza la sortida" +#: builtin/fast-export.c msgid "from:to" msgstr "des de:a" +#: builtin/fast-export.c msgid "convert <from> to <to> in anonymized output" msgstr "converteix <from> a <to> en una sortida anònima" +#: builtin/fast-export.c msgid "reference parents which are not in fast-export stream by object id" msgstr "" "referència els pares que no estan en flux d'exportació ràpida per " "identificador d'objecte" +#: builtin/fast-export.c msgid "show original object ids of blobs/commits" msgstr "mostra els ID dels objectes originals dels blobs i comissions" +#: builtin/fast-export.c msgid "label tags with mark ids" msgstr "marca les etiquetes amb els identificadors de marca" +#: builtin/fast-import.c #, c-format msgid "Missing from marks for submodule '%s'" msgstr "Falten les marques «from» per al submòdul «%s»" +#: builtin/fast-import.c #, c-format msgid "Missing to marks for submodule '%s'" msgstr "Falten les marques per al submòdul «%s»" +#: builtin/fast-import.c #, c-format msgid "Expected 'mark' command, got %s" msgstr "S'esperava l'ordre «mark», s'ha rebut %s" +#: builtin/fast-import.c #, c-format msgid "Expected 'to' command, got %s" msgstr "S'esperava l'ordre «to», s'ha rebut «%s»" +#: builtin/fast-import.c msgid "Expected format name:filename for submodule rewrite option" msgstr "" "S'esperava el format «nom:nom de fitxer» per a l'opció de reescriptura de " "submòdul" +#: builtin/fast-import.c #, c-format msgid "feature '%s' forbidden in input without --allow-unsafe-features" msgstr "" "característica «%s» prohibida a l'entrada sense --allow-unsafe-features" +#: builtin/fetch-pack.c #, c-format msgid "Lockfile created but not reported: %s" msgstr "S'ha creat el fitxer de bloqueig però no s'ha informat: %s" +#: builtin/fetch.c msgid "git fetch [<options>] [<repository> [<refspec>...]]" -msgstr "" -"git fetch [<opcions>] [<repositori> [<especificació-de-referència>...]]" +msgstr "git fetch [<opcions>] [<repositori> [<especificació-referència>...]]" +#: builtin/fetch.c msgid "git fetch [<options>] <group>" msgstr "git fetch [<opcions>] <grup>" +#: builtin/fetch.c msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]" msgstr "git fetch --multiple [<opcions>] [(<repositori> | <grup>)...]" +#: builtin/fetch.c msgid "git fetch --all [<options>]" msgstr "git fetch --all [<opcions>]" +#: builtin/fetch.c msgid "fetch.parallel cannot be negative" msgstr "fetch.parallel no pot ser negatiu" +#: builtin/fetch.c msgid "couldn't find remote ref HEAD" msgstr "no s'ha pogut trobar la referència HEAD remota" +#: builtin/fetch.c #, c-format msgid "From %.*s\n" msgstr "De %.*s\n" +#: builtin/fetch.c #, c-format msgid "object %s not found" msgstr "objecte %s no trobat" +#: builtin/fetch.c msgid "[up to date]" msgstr "[al dia]" +#: builtin/fetch.c msgid "[rejected]" msgstr "[rebutjat]" +#: builtin/fetch.c msgid "can't fetch into checked-out branch" msgstr "no es pot obtenir en la branca actual" +#: builtin/fetch.c msgid "[tag update]" msgstr "[actualització d'etiqueta]" +#: builtin/fetch.c msgid "unable to update local ref" msgstr "no s'ha pogut actualitzar la referència local" +#: builtin/fetch.c msgid "would clobber existing tag" msgstr "s'adjuntaria l'etiqueta existent" +#: builtin/fetch.c msgid "[new tag]" msgstr "[etiqueta nova]" +#: builtin/fetch.c msgid "[new branch]" msgstr "[branca nova]" +#: builtin/fetch.c msgid "[new ref]" msgstr "[referència nova]" +#: builtin/fetch.c msgid "forced update" msgstr "actualització forçada" +#: builtin/fetch.c msgid "non-fast-forward" msgstr "sense avanç ràpid" +#: builtin/fetch.c builtin/grep.c sequencer.c #, c-format msgid "cannot open '%s'" msgstr "no es pot obrir «%s»" +#: builtin/fetch.c msgid "" "fetch normally indicates which branches had a forced update,\n" "but that check has been disabled; to re-enable, use '--show-forced-updates'\n" @@ -5885,6 +7557,7 @@ msgstr "" "utilitzeu\n" "«--show-forced-updates» o executeu «git config fetch.showForcedUpdates true»" +#: builtin/fetch.c #, c-format msgid "" "it took %.2f seconds to check forced updates; you can use\n" @@ -5896,15 +7569,18 @@ msgstr "" "utilitzar «--no-show-forced-updates» o executar «git config \n" "fetch.showForcedUpdates false» per a evitar aquesta comprovació.\n" +#: builtin/fetch.c #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s no ha enviat tots els objectes necessaris\n" +msgid "%s did not send all necessary objects" +msgstr "%s no ha enviat tot els objectes necessaris" +#: builtin/fetch.c #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "" "s'ha rebutjat %s perquè no es permeten actualitzar les arrels superficials" +#: builtin/fetch.c #, c-format msgid "" "some local refs could not be updated; try running\n" @@ -5914,43 +7590,54 @@ msgstr "" " intenteu executar «git remote prune %s» per a eliminar\n" " qualsevol branca antiga o conflictiva" +#: builtin/fetch.c #, c-format msgid " (%s will become dangling)" -msgstr " (%s es tornarà penjant)" +msgstr " (%s es tornarà despenjat)" +#: builtin/fetch.c #, c-format msgid " (%s has become dangling)" -msgstr " (%s s'ha tornat penjant)" +msgstr " (%s s'ha quedat despenjat)" +#: builtin/fetch.c msgid "[deleted]" msgstr "[suprimit]" +#: builtin/fetch.c builtin/remote.c msgid "(none)" msgstr "(cap)" +#: builtin/fetch.c #, c-format msgid "refusing to fetch into branch '%s' checked out at '%s'" msgstr "s'ha rebutjat l'obtenció en la branca «%s» agafada a «%s»" +#: builtin/fetch.c #, c-format msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "l'opció «%s» amb valor «%s» no és vàlida per a %s" +#: builtin/fetch.c #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "s'ignora l'opció «%s» per a %s\n" +msgid "option \"%s\" is ignored for %s" +msgstr "l'opció «%s» s'ignora per a «%s»" +#: builtin/fetch.c object-file.c #, c-format msgid "%s is not a valid object" msgstr "%s no és un objecte vàlid" +#: builtin/fetch.c #, c-format msgid "the object %s does not exist" msgstr "l'objecte %s no existeix" +#: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "s'han detectat múltiples branques, incompatible amb --set-upstream" +#: builtin/fetch.c #, c-format msgid "" "could not set upstream of HEAD to '%s' from '%s' when it does not point to " @@ -5959,16 +7646,20 @@ msgstr "" "no s'ha pogut establir la font de HEAD a «%s» des de «%s» quan no assenyala " "cap branca." +#: builtin/fetch.c msgid "not setting upstream for a remote remote-tracking branch" msgstr "" "no s'està configurant la font per a una branca remota amb seguiment remot" +#: builtin/fetch.c msgid "not setting upstream for a remote tag" msgstr "no s'està configurant la font d'una etiqueta remota" +#: builtin/fetch.c msgid "unknown branch type" msgstr "tipus de branca desconegut" +#: builtin/fetch.c msgid "" "no source branch found;\n" "you need to specify exactly one branch with the --set-upstream option" @@ -5976,18 +7667,22 @@ msgstr "" "no s'ha trobat cap branca d'origen.\n" "heu d'especificar exactament una branca amb l'opció --set-upstream" +#: builtin/fetch.c #, c-format msgid "Fetching %s\n" msgstr "S'està obtenint %s\n" +#: builtin/fetch.c #, c-format msgid "could not fetch %s" msgstr "no s'ha pogut obtenir %s" +#: builtin/fetch.c #, c-format msgid "could not fetch '%s' (exit code: %d)\n" msgstr "no s'ha pogut obtenir «%s» (codi de sortida: %d)\n" +#: builtin/fetch.c msgid "" "no remote repository specified; please specify either a URL or a\n" "remote name from which new revisions should be fetched" @@ -5995,82 +7690,107 @@ msgstr "" "no s'ha especificat cap repositori remot. Especifiqueu un URL o\n" "un nom remot del qual s'han d'obtenir les revisions noves" +#: builtin/fetch.c msgid "you need to specify a tag name" msgstr "necessiteu especificar un nom d'etiqueta" +#: builtin/fetch.c builtin/pull.c msgid "fetch from all remotes" msgstr "obtén de tots els remots" +#: builtin/fetch.c builtin/pull.c msgid "set upstream for git pull/fetch" msgstr "estableix la font per a git pull/fetch" +#: builtin/fetch.c builtin/pull.c msgid "append to .git/FETCH_HEAD instead of overwriting" msgstr "annexa a .git/FETCH_HEAD en lloc de sobreescriure'l" +#: builtin/fetch.c msgid "use atomic transaction to update references" msgstr "usa una transacció atòmica per a actualitzar les referències" +#: builtin/fetch.c builtin/pull.c msgid "path to upload pack on remote end" msgstr "camí al qual pujar el paquet al costat remot" +#: builtin/fetch.c msgid "force overwrite of local reference" msgstr "força la sobreescriptura de la referència local" +#: builtin/fetch.c msgid "fetch from multiple remotes" msgstr "obtén de múltiples remots" +#: builtin/fetch.c builtin/pull.c msgid "fetch all tags and associated objects" msgstr "obtén totes les etiquetes i tots els objectes associats" +#: builtin/fetch.c msgid "do not fetch all tags (--no-tags)" msgstr "no obtinguis les etiquetes (--no-tags)" +#: builtin/fetch.c msgid "number of submodules fetched in parallel" msgstr "nombre de submòduls obtinguts en paral·lel" +#: builtin/fetch.c msgid "modify the refspec to place all refs within refs/prefetch/" msgstr "" "modifica l'especificació de referència per a col·locar totes les referències " "dins de refs/prefetch/" +#: builtin/fetch.c builtin/pull.c msgid "prune remote-tracking branches no longer on remote" msgstr "poda les branques amb seguiment remot que ja no estiguin en el remot" +#: builtin/fetch.c msgid "prune local tags no longer on remote and clobber changed tags" msgstr "" "poda les etiquetes locals que ja no existeixen al remot i adjunta les " "etiquetes que han canviat" +#: builtin/fetch.c builtin/pull.c msgid "on-demand" msgstr "sota demanda" +#: builtin/fetch.c msgid "control recursive fetching of submodules" msgstr "controla l'obtenció recursiva de submòduls" +#: builtin/fetch.c msgid "write fetched references to the FETCH_HEAD file" msgstr "escriu les referències obtingudes al fitxer FETCH_HEAD" +#: builtin/fetch.c builtin/pull.c msgid "keep downloaded pack" msgstr "retén el paquet baixat" +#: builtin/fetch.c msgid "allow updating of HEAD ref" msgstr "permet l'actualització de la referència HEAD" +#: builtin/fetch.c builtin/pull.c msgid "deepen history of shallow clone" msgstr "aprofundeix la història d'un clon superficial" +#: builtin/fetch.c builtin/pull.c msgid "deepen history of shallow repository based on time" msgstr "aprofundeix la història d'un clon superficial basat en una data" +#: builtin/fetch.c builtin/pull.c msgid "convert to a complete repository" msgstr "converteix en un repositori complet" +#: builtin/fetch.c msgid "re-fetch without negotiating common commits" msgstr "tornar a obtenir sense negociar comissions comunes" +#: builtin/fetch.c msgid "prepend this to submodule path output" msgstr "anteposa això a la sortida de camí del submòdul" +#: builtin/fetch.c msgid "" "default for recursive fetching of submodules (lower priority than config " "files)" @@ -6078,68 +7798,88 @@ msgstr "" "per defecte per a l'obtenció recursiva de submòduls (prioritat més baixa que " "els fitxers de configuració)" +#: builtin/fetch.c builtin/pull.c msgid "accept refs that update .git/shallow" msgstr "accepta les referències que actualitzin .git/shallow" +#: builtin/fetch.c builtin/pull.c msgid "refmap" msgstr "mapa de referències" +#: builtin/fetch.c builtin/pull.c msgid "specify fetch refmap" msgstr "específica l'obtenció del mapa de referències" +#: builtin/fetch.c builtin/pull.c msgid "report that we have only objects reachable from this object" msgstr "informa que només hi ha objectes abastables des d'aquest objecte" +#: builtin/fetch.c msgid "do not fetch a packfile; instead, print ancestors of negotiation tips" msgstr "" "no obtinguis un fitxer de paquet; en canvi, mostra els avantpassats dels " "consells de negociació" +#: builtin/fetch.c msgid "run 'maintenance --auto' after fetching" msgstr "executa «maintenance --auto» després d'obtenir" +#: builtin/fetch.c builtin/pull.c msgid "check for forced-updates on all updated branches" msgstr "" "comprova si hi ha actualitzacions forçades a totes les branques actualitzades" +#: builtin/fetch.c msgid "write the commit-graph after fetching" msgstr "escriu el graf de comissions després de recollir" +#: builtin/fetch.c msgid "accept refspecs from stdin" msgstr "llegeix les especificacions de referència des de stdin" +#: builtin/fetch.c msgid "--negotiate-only needs one or more --negotiation-tip=*" msgstr "--negotiate-only necessita un o més --negotiation-tip=*" +#: builtin/fetch.c msgid "negative depth in --deepen is not supported" msgstr "no s'admet una profunditat negativa en --deepen" +#: builtin/fetch.c msgid "--unshallow on a complete repository does not make sense" msgstr "--unshallow en un repositori complet no té sentit" +#: builtin/fetch.c #, c-format msgid "failed to fetch bundles from '%s'" msgstr "no s'han pogut obtenir els paquets de «%s»" +#: builtin/fetch.c msgid "fetch --all does not take a repository argument" msgstr "fetch --all no accepta un argument de repositori" +#: builtin/fetch.c msgid "fetch --all does not make sense with refspecs" msgstr "fetch --all no té sentit amb especificacions de referència" +#: builtin/fetch.c #, c-format msgid "no such remote or remote group: %s" msgstr "no existeix un remot ni un grup remot: %s" +#: builtin/fetch.c msgid "fetching a group and specifying refspecs does not make sense" msgstr "obtenir un grup i especificar referències no té sentit" +#: builtin/fetch.c msgid "must supply remote when using --negotiate-only" msgstr "s'ha de subministrar el remot en usar --negotiate-only" +#: builtin/fetch.c msgid "protocol does not support --negotiate-only, exiting" msgstr "el protocol no admet --negotiate-only, se surt" +#: builtin/fetch.c msgid "" "--filter can only be used with the remote configured in extensions." "partialclone" @@ -6147,125 +7887,170 @@ msgstr "" "--filter només es pot utilitzar amb el remot configurat en extensions." "partialclone" +#: builtin/fetch.c msgid "--atomic can only be used when fetching from one remote" msgstr "l'opció --atomic només es pot usar quan s'obté des d'un remot" +#: builtin/fetch.c msgid "--stdin can only be used when fetching from one remote" msgstr "l'opció --stdin només es pot usar quan s'obté des d'un remot" +#: builtin/fmt-merge-msg.c msgid "" "git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]" msgstr "" "git fmt-merge-msg [-m <missatge>] [--log[=<n>] | --no-log] [--file <fitxer>]" +#: builtin/fmt-merge-msg.c msgid "populate log with at most <n> entries from shortlog" msgstr "emplena el registre amb <n> entrades del registre curt com a màxim" +#: builtin/fmt-merge-msg.c msgid "alias for --log (deprecated)" msgstr "àlies per a --log (en desús)" +#: builtin/fmt-merge-msg.c msgid "text" msgstr "text" +#: builtin/fmt-merge-msg.c msgid "use <text> as start of message" msgstr "usa <text> com a inici de missatge" +#: builtin/fmt-merge-msg.c msgid "use <name> instead of the real target branch" msgstr "usa <nom> en lloc de la branca de destí real" +#: builtin/fmt-merge-msg.c msgid "file to read from" msgstr "fitxer del qual llegir" +#: builtin/for-each-ref.c msgid "git for-each-ref [<options>] [<pattern>]" msgstr "git for-each-ref [<opcions>] [<patró>]" +#: builtin/for-each-ref.c msgid "git for-each-ref [--points-at <object>]" msgstr "git for-each-ref [--points-at <objecte>]" +#: builtin/for-each-ref.c msgid "git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]" msgstr "git for-each-ref [--merged [<comissió>]] [--no-merged [<comissió>]]" +#: builtin/for-each-ref.c msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "" "git for-each-ref [--contains [<comissió>]] [--no-contains [<comissió>]]" +#: builtin/for-each-ref.c msgid "quote placeholders suitably for shells" msgstr "" "posa els marcadors de posició entre cometes adequades per a intèrprets " "d'ordres" +#: builtin/for-each-ref.c msgid "quote placeholders suitably for perl" msgstr "posa els marcadors de posició entre cometes adequades per al perl" +#: builtin/for-each-ref.c msgid "quote placeholders suitably for python" msgstr "posa els marcadors de posició entre cometes adequades per al python" +#: builtin/for-each-ref.c msgid "quote placeholders suitably for Tcl" msgstr "posa els marcadors de posició entre cometes adequades per al Tcl" +#: builtin/for-each-ref.c msgid "show only <n> matched refs" msgstr "mostra només <n> referències coincidents" +#: builtin/for-each-ref.c builtin/tag.c msgid "respect format colors" msgstr "respecta els colors del format" +#: builtin/for-each-ref.c msgid "print only refs which points at the given object" msgstr "imprimeix només les referències que assenyalin l'objecte donat" +#: builtin/for-each-ref.c msgid "print only refs that are merged" msgstr "imprimeix només les referències que s'han fusionat" +#: builtin/for-each-ref.c msgid "print only refs that are not merged" msgstr "imprimeix només les referències que no s'han fusionat" +#: builtin/for-each-ref.c msgid "print only refs which contain the commit" msgstr "imprimeix només les referències que continguin la comissió" +#: builtin/for-each-ref.c msgid "print only refs which don't contain the commit" msgstr "imprimeix només les referències que no continguin la comissió" +#: builtin/for-each-ref.c msgid "read reference patterns from stdin" msgstr "llegeix els patrons de referència de l'entrada estàndard" +#: builtin/for-each-ref.c +msgid "also include HEAD ref and pseudorefs" +msgstr "inclou també la referència HEAD i les pseudoreferències" + +#: builtin/for-each-ref.c msgid "unknown arguments supplied with --stdin" msgstr "s'han proporcionat arguments desconeguts amb --stdin" +#: builtin/for-each-repo.c msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<config> [--] <arguments>" +#: builtin/for-each-repo.c msgid "config" msgstr "config" +#: builtin/for-each-repo.c msgid "config key storing a list of repository paths" msgstr "clau de configuració emmagatzemant una llista de camins de repositori" +#: builtin/for-each-repo.c +msgid "keep going even if command fails in a repository" +msgstr "continua fins i tot si l'ordre falla en un repositori" + +#: builtin/for-each-repo.c msgid "missing --config=<config>" msgstr "falta --config=<config>" +#: builtin/for-each-repo.c #, c-format msgid "got bad config --config=%s" msgstr "s'ha obtingut una configuració incorrecta --config=%s" +#: builtin/fsck.c msgid "unknown" msgstr "desconegut" #. TRANSLATORS: e.g. error in tree 01bfda: <more explanation> +#: builtin/fsck.c #, c-format msgid "error in %s %s: %s" msgstr "error en %s %s: %s" #. TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> +#: builtin/fsck.c #, c-format msgid "warning in %s %s: %s" msgstr "avís en %s %s: %s" +#: builtin/fsck.c #, c-format msgid "broken link from %7s %s" msgstr "enllaç trencat de %7s %s" +#: builtin/fsck.c msgid "wrong object type in link" msgstr "tipus d'objecte incorrecte en l'enllaç" +#: builtin/fsck.c #, c-format msgid "" "broken link from %7s %s\n" @@ -6274,147 +8059,186 @@ msgstr "" "enllaç trencat des de %7s %s\n" " fins a %7s %s" +#: builtin/fsck.c builtin/prune.c connected.c msgid "Checking connectivity" msgstr "S'està comprovant la connectivitat" +#: builtin/fsck.c #, c-format msgid "missing %s %s" msgstr "%s %s manca" +#: builtin/fsck.c #, c-format msgid "unreachable %s %s" msgstr "%s %s inabastable" +#: builtin/fsck.c #, c-format msgid "dangling %s %s" msgstr "%s %s sense assignació" +#: builtin/fsck.c msgid "could not create lost-found" msgstr "no s'ha pogut crear el trobat-perdut" +#: builtin/fsck.c builtin/gc.c builtin/rebase.c rebase-interactive.c rerere.c +#: sequencer.c #, c-format msgid "could not write '%s'" msgstr "no s'ha pogut escriure «%s»" +#: builtin/fsck.c #, c-format msgid "could not finish '%s'" msgstr "no s'ha pogut finalitzar «%s»" +#: builtin/fsck.c #, c-format msgid "Checking %s" msgstr "S'està comprovant %s" +#: builtin/fsck.c #, c-format msgid "Checking connectivity (%d objects)" msgstr "S'està comprovant la connectivitat (%d objectes)" +#: builtin/fsck.c #, c-format msgid "Checking %s %s" msgstr "S'està comprovant %s %s" +#: builtin/fsck.c msgid "broken links" msgstr "enllaços trencats" +#: builtin/fsck.c #, c-format msgid "root %s" msgstr "arrel %s" +#: builtin/fsck.c #, c-format msgid "tagged %s %s (%s) in %s" msgstr "marcat %s %s (%s) a %s" +#: builtin/fsck.c #, c-format msgid "%s: object corrupt or missing" msgstr "%s: objecte corrupte o no trobat" +#: builtin/fsck.c #, c-format msgid "%s: invalid reflog entry %s" -msgstr "%s: entrada de referència no vàlida %s" +msgstr "%s: entrada de registre de referències no vàlida %s" +#: builtin/fsck.c #, c-format msgid "Checking reflog %s->%s" -msgstr "S'està comprovant reflog %s->%s" +msgstr "S'està comprovant el registre de referències %s->%s" +#: builtin/fsck.c #, c-format msgid "%s: invalid sha1 pointer %s" msgstr "%s: punter %s sha1 no vàlid" +#: builtin/fsck.c #, c-format msgid "%s: not a commit" msgstr "%s: no és una comissió" +#: builtin/fsck.c msgid "notice: No default references" msgstr "avís: no hi ha referències per defecte" +#: builtin/fsck.c #, c-format msgid "%s: hash-path mismatch, found at: %s" msgstr "%s: el resum del camí no coincideix, trobat a: %s" +#: builtin/fsck.c #, c-format msgid "%s: object corrupt or missing: %s" msgstr "%s: objecte corrupte o no trobat: %s" +#: builtin/fsck.c #, c-format msgid "%s: object is of unknown type '%s': %s" msgstr "%s: l'objecte és de tipus desconegut «%s»: %s" +#: builtin/fsck.c #, c-format msgid "%s: object could not be parsed: %s" msgstr "%s: no s'ha pogut analitzar l'objecte: %s" +#: builtin/fsck.c #, c-format msgid "bad sha1 file: %s" msgstr "fitxer sha1 malmès: %s" +#: builtin/fsck.c msgid "Checking object directory" msgstr "S'està comprovant el directori d'objecte" +#: builtin/fsck.c msgid "Checking object directories" msgstr "S'estan comprovant els directoris d'objecte" +#: builtin/fsck.c #, c-format msgid "Checking %s link" msgstr "S'està comprovant l'enllaç %s" +#: builtin/fsck.c builtin/index-pack.c #, c-format msgid "invalid %s" msgstr "%s no vàlid" +#: builtin/fsck.c #, c-format msgid "%s points to something strange (%s)" msgstr "%s apunta a una cosa estranya (%s)" +#: builtin/fsck.c #, c-format msgid "%s: detached HEAD points at nothing" msgstr "%s: la HEAD separada no apunta a res" +#: builtin/fsck.c #, c-format msgid "notice: %s points to an unborn branch (%s)" msgstr "avís: %s apunta a una branca no nascuda (%s)" +#: builtin/fsck.c #, c-format msgid "Checking cache tree of %s" msgstr "S'està comprovant l'arbre de la memòria cau %s" +#: builtin/fsck.c #, c-format msgid "%s: invalid sha1 pointer in cache-tree of %s" msgstr "%s: punter sha1 no vàlid a l'arbre de la memòria cau %s" +#: builtin/fsck.c msgid "non-tree in cache-tree" msgstr "un no arbre en l'arbre de la memòria cau" +#: builtin/fsck.c #, c-format msgid "%s: invalid sha1 pointer in resolve-undo of %s" msgstr "%s: punter sha1 no vàlid a «resolve-undo» de %s" +#: builtin/fsck.c #, c-format msgid "unable to load rev-index for pack '%s'" msgstr "no s'ha pogut carregar l'índex de reversió per al paquet «%s»" +#: builtin/fsck.c #, c-format msgid "invalid rev-index for pack '%s'" msgstr "rev-index no vàlid per al paquet «%s»" +#: builtin/fsck.c msgid "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" @@ -6426,159 +8250,205 @@ msgstr "" " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n" " [--[no-]name-objects] [<objecte>...]" +#: builtin/fsck.c msgid "show unreachable objects" msgstr "mostra els objectes inabastables" +#: builtin/fsck.c msgid "show dangling objects" -msgstr "mostra els objectes penjants" +msgstr "mostra els objectes despenjats" +#: builtin/fsck.c msgid "report tags" msgstr "informa de les etiquetes" +#: builtin/fsck.c msgid "report root nodes" msgstr "informa dels nodes d'arrel" +#: builtin/fsck.c msgid "make index objects head nodes" -msgstr "fes dels objectes d'índex nodes cap" +msgstr "fes dels objectes d'índex nodes HEAD" +#: builtin/fsck.c msgid "make reflogs head nodes (default)" -msgstr "fes que els registres de referències siguin nodes cap (per defecte)" +msgstr "fes que els registres de referències siguin nodes HEAD (per defecte)" +#: builtin/fsck.c msgid "also consider packs and alternate objects" msgstr "també considera els paquets i els objectes alternatius" +#: builtin/fsck.c msgid "check only connectivity" msgstr "comprova només la connectivitat" +#: builtin/fsck.c builtin/mktag.c msgid "enable more strict checking" msgstr "habilita la comprovació més estricta" +#: builtin/fsck.c msgid "write dangling objects in .git/lost-found" -msgstr "escriu objectes penjants a .git/lost-found" +msgstr "escriu objectes despenjats a .git/lost-found" +#: builtin/fsck.c builtin/prune.c msgid "show progress" msgstr "mostra el progrés" +#: builtin/fsck.c msgid "show verbose names for reachable objects" msgstr "mostra els noms detallats dels objectes abastables" +#: builtin/fsck.c builtin/index-pack.c msgid "Checking objects" msgstr "S'estan comprovant els objectes" +#: builtin/fsck.c #, c-format msgid "%s: object missing" msgstr "%s: falta l'objecte" +#: builtin/fsck.c #, c-format msgid "invalid parameter: expected sha1, got '%s'" msgstr "paràmetre no vàlid: s'esperava sha1, s'ha obtingut «%s»" +#: builtin/fsmonitor--daemon.c msgid "git fsmonitor--daemon start [<options>]" msgstr "git fsmonitor--daemon start [<opcions>]" +#: builtin/fsmonitor--daemon.c msgid "git fsmonitor--daemon run [<options>]" msgstr "git fsmonitor--daemon run [<opcions>]" +#: builtin/fsmonitor--daemon.c #, c-format msgid "value of '%s' out of range: %d" msgstr "el valor de «%s» està fora de rang: %d" +#: builtin/fsmonitor--daemon.c #, c-format msgid "value of '%s' not bool or int: %d" msgstr "valor de «%s» no és booleà ni enter: %d" +#: builtin/fsmonitor--daemon.c #, c-format msgid "fsmonitor-daemon is watching '%s'\n" msgstr "fsmonitor-daemon està veient «%s»\n" +#: builtin/fsmonitor--daemon.c #, c-format msgid "fsmonitor-daemon is not watching '%s'\n" msgstr "fsmonitor-daemon no està vigilant «%s»\n" +#: builtin/fsmonitor--daemon.c #, c-format msgid "could not create fsmonitor cookie '%s'" msgstr "no s'ha pogut crear la galeta fsmonitor «%s»" +#: builtin/fsmonitor--daemon.c #, c-format msgid "fsmonitor: cookie_result '%d' != SEEN" msgstr "fsmonitor: cookie_result «%d» != SEEN" +#: builtin/fsmonitor--daemon.c #, c-format msgid "could not start IPC thread pool on '%s'" msgstr "no s'ha pogut iniciar el grup de fils IPC a «%s»" +#: builtin/fsmonitor--daemon.c msgid "could not start fsmonitor listener thread" msgstr "no s'ha pogut iniciar el fil receptor del fsmonitor" +#: builtin/fsmonitor--daemon.c msgid "could not start fsmonitor health thread" msgstr "no s'ha pogut iniciar el fil de salut del fsmonitor" +#: builtin/fsmonitor--daemon.c msgid "could not initialize listener thread" msgstr "no s'ha pogut inicialitzar el fil receptor" +#: builtin/fsmonitor--daemon.c msgid "could not initialize health thread" msgstr "no s'ha pogut inicialitzar el fil de salut" +#: builtin/fsmonitor--daemon.c #, c-format msgid "could not cd home '%s'" msgstr "no s'ha pogut fer cd home «%s»" +#: builtin/fsmonitor--daemon.c #, c-format msgid "fsmonitor--daemon is already running '%s'" msgstr "fsmonitor--daemon is already running «%s»" +#: builtin/fsmonitor--daemon.c #, c-format msgid "running fsmonitor-daemon in '%s'\n" msgstr "s'està executant fsmonitor-daemon en «%s»\n" +#: builtin/fsmonitor--daemon.c #, c-format msgid "starting fsmonitor-daemon in '%s'\n" msgstr "s'està iniciant fsmonitor-daemon a «%s»\n" +#: builtin/fsmonitor--daemon.c msgid "daemon failed to start" msgstr "el dimoni ha fallat en iniciar" +#: builtin/fsmonitor--daemon.c msgid "daemon not online yet" msgstr "el dimoni encara no està en línia" +#: builtin/fsmonitor--daemon.c msgid "daemon terminated" msgstr "s'ha finalitzat el dimoni" +#: builtin/fsmonitor--daemon.c msgid "detach from console" msgstr "separat de la consola" +#: builtin/fsmonitor--daemon.c msgid "use <n> ipc worker threads" msgstr "usa <n> fils de treball ipc" +#: builtin/fsmonitor--daemon.c msgid "max seconds to wait for background daemon startup" msgstr "màxim de segons a esperar a l'inici del dimoni en segon pla" +#: builtin/fsmonitor--daemon.c #, c-format msgid "invalid 'ipc-threads' value (%d)" msgstr "valor «ipc-threads» no vàlid (%d)" +#: builtin/fsmonitor--daemon.c t/helper/test-cache-tree.c #, c-format msgid "Unhandled subcommand '%s'" msgstr "Subordre no gestionada «%s»" +#: builtin/fsmonitor--daemon.c msgid "fsmonitor--daemon not supported on this platform" msgstr "fsmonitor--daemon no és compatible amb aquesta plataforma" +#: builtin/gc.c msgid "git gc [<options>]" msgstr "git gc [<opcions>]" +#: builtin/gc.c #, c-format msgid "Failed to fstat %s: %s" msgstr "S'ha produït un error en fer fstat %s: %s" +#: builtin/gc.c #, c-format msgid "failed to parse '%s' value '%s'" msgstr "no s'ha pogut analitzar «%s» valor «%s»" +#: builtin/gc.c setup.c #, c-format msgid "cannot stat '%s'" msgstr "no es pot fer stat en «%s»" +#: builtin/gc.c #, c-format msgid "" "The last gc run reported the following. Please correct the root cause\n" @@ -6593,246 +8463,322 @@ msgstr "" "\n" "%s" +#: builtin/gc.c msgid "prune unreferenced objects" msgstr "poda objectes sense referència" +#: builtin/gc.c msgid "pack unreferenced objects separately" msgstr "empaqueta els objectes no referenciats de forma separada" +#: builtin/gc.c builtin/repack.c msgid "with --cruft, limit the size of new cruft packs" msgstr "amb --cruft, limiteu la mida dels paquets cruft nous" +#: builtin/gc.c msgid "be more thorough (increased runtime)" msgstr "sigues més exhaustiu (el temps d'execució augmenta)" +#: builtin/gc.c msgid "enable auto-gc mode" msgstr "habilita el mode de recollida d'escombraries automàtica" +#: builtin/gc.c +msgid "perform garbage collection in the background" +msgstr "fes la recollida de memòria brossa en segon pla" + +#: builtin/gc.c msgid "force running gc even if there may be another gc running" msgstr "" "força l'execució de gc encara que hi pugui haver un altre gc executant-se" +#: builtin/gc.c msgid "repack all other packs except the largest pack" msgstr "reempaqueta tots els altres paquets excepte el paquet més gran" +#: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "no s'ha pogut analitzar el valor %s de gc.logExpiry" +#: builtin/gc.c #, c-format msgid "failed to parse prune expiry value %s" msgstr "no s'ha pogut analitzar el valor de venciment de la poda %s" +#: builtin/gc.c #, c-format msgid "Auto packing the repository in background for optimum performance.\n" msgstr "" "S'està empaquetant el repositori automàticament en el rerefons per a un " "rendiment òptim.\n" +#: builtin/gc.c #, c-format msgid "Auto packing the repository for optimum performance.\n" msgstr "" "S'està empaquetant automàticament el repositori per a un rendiment òptim.\n" +#: builtin/gc.c #, c-format msgid "See \"git help gc\" for manual housekeeping.\n" msgstr "Vegeu «git help gc» per a neteja manual.\n" +#: builtin/gc.c #, c-format msgid "" "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)" msgstr "" "gc ja s'està executant en la màquina «%s» pid %<PRIuMAX> (useu --force si no)" +#: builtin/gc.c msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" "Hi ha massa objectes solts inabastables; executeu «git prune» per a eliminar-" "los." +#: builtin/gc.c msgid "" "git maintenance run [--auto] [--[no-]quiet] [--task=<task>] [--schedule]" msgstr "" "git maintenance run [--auto] [--[no-]quiet] [--task=<task>] [--schedule]" +#: builtin/gc.c msgid "--no-schedule is not allowed" msgstr "--no-schedule no està permès" +#: builtin/gc.c #, c-format msgid "unrecognized --schedule argument '%s'" msgstr "argument --schedule no reconegut, «%s»" +#: builtin/gc.c msgid "failed to write commit-graph" msgstr "s'ha produït un error en escriure el graf de comissions" +#: builtin/gc.c msgid "failed to prefetch remotes" msgstr "s'ha produït un error en preobtenir els remots" +#: builtin/gc.c msgid "failed to start 'git pack-objects' process" msgstr "no s'ha pogut iniciar el procés «git pack-objects»" +#: builtin/gc.c msgid "failed to finish 'git pack-objects' process" msgstr "no s'ha pogut finalitzar el procés «git pack-objects»" +#: builtin/gc.c msgid "failed to write multi-pack-index" msgstr "no s'ha pogut escriure l'índex del multipaquet" +#: builtin/gc.c msgid "'git multi-pack-index expire' failed" msgstr "ha fallat el venciment de «git multi-pack-index expire»" +#: builtin/gc.c msgid "'git multi-pack-index repack' failed" msgstr "ha fallat l'execució de «git multi-pack-index repack»" +#: builtin/gc.c msgid "" "skipping incremental-repack task because core.multiPackIndex is disabled" msgstr "" "s'està ometent la tasca incremental-repack perquè core.multiPackIndex està " "desactivat" +#: builtin/gc.c #, c-format msgid "lock file '%s' exists, skipping maintenance" msgstr "el fitxer de bloqueig «%s» existeix, s'omet el manteniment" +#: builtin/gc.c #, c-format msgid "task '%s' failed" msgstr "la tasca «%s» ha fallat" +#: builtin/gc.c #, c-format msgid "'%s' is not a valid task" msgstr "«%s» no és una tasca vàlida" +#: builtin/gc.c #, c-format msgid "task '%s' cannot be selected multiple times" msgstr "la tasca «%s» no es pot seleccionar múltiples vegades" +#: builtin/gc.c msgid "run tasks based on the state of the repository" msgstr "executa les tasques basades en l'estat del repositori" +#: builtin/gc.c +msgid "perform maintenance in the background" +msgstr "fes el manteniment en segon pla" + +#: builtin/gc.c msgid "frequency" msgstr "freqüència" +#: builtin/gc.c msgid "run tasks based on frequency" msgstr "executa les tasques basant-se en freqüència" +#: builtin/gc.c msgid "do not report progress or other information over stderr" -msgstr "no informeu sobre el progrés o altra informació as stderr" +msgstr "no informeu sobre el progrés o altra informació a stderr" +#: builtin/gc.c msgid "task" msgstr "tasca" +#: builtin/gc.c msgid "run a specific task" msgstr "executa una tasca específica" +#: builtin/gc.c msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "usa com a màxim un entre --auto i --schedule=<frequency>" +msgstr "usa com a màxim un entre --auto i --schedule=<freqüència>" +#: builtin/gc.c #, c-format msgid "unable to add '%s' value of '%s'" msgstr "no es pot afegir el valor «%s» de «%s»" +#: builtin/gc.c msgid "return success even if repository was not registered" msgstr "retorna èxit encara que el repositori no estigui registrat" +#: builtin/gc.c #, c-format msgid "unable to unset '%s' value of '%s'" msgstr "no es pot desassignar el valor «%s» de «%s»" +#: builtin/gc.c #, c-format msgid "repository '%s' is not registered" msgstr "el repositori «%s» no està registrat" +#: builtin/gc.c #, c-format msgid "failed to expand path '%s'" msgstr "s'ha produït un error en expandir el camí «%s»" +#: builtin/gc.c msgid "failed to start launchctl" msgstr "s'ha produït un error en iniciar launchctl" +#: builtin/gc.c #, c-format msgid "failed to create directories for '%s'" msgstr "s'ha produït un error en crear els directoris per a «%s»" +#: builtin/gc.c #, c-format msgid "failed to bootstrap service %s" msgstr "s'ha produït un error en arrencar el servei %s" +#: builtin/gc.c msgid "failed to create temp xml file" msgstr "no s'han pogut crear un fitxer xml temporal" +#: builtin/gc.c msgid "failed to start schtasks" msgstr "s'ha produït un error en iniciar schtasks" +#: builtin/gc.c msgid "failed to run 'crontab -l'; your system might not support 'cron'" msgstr "" "no s'ha pogut executar «crontab -l»; el vostre sistema podria no admetre " "«cron»" +#: builtin/gc.c msgid "failed to create crontab temporary file" msgstr "no s'ha pogut crear un fitxer temporal crontab" +#: builtin/gc.c msgid "failed to open temporary file" msgstr "no s'ha pogut obrir el fitxer temporal" +#: builtin/gc.c msgid "failed to run 'crontab'; your system might not support 'cron'" msgstr "" "no s'ha pogut executar «crontab»; el vostre sistema podria no admetre «cron»" +#: builtin/gc.c msgid "'crontab' died" msgstr "«crontab» ha mort" +#: builtin/gc.c builtin/worktree.c #, c-format msgid "failed to delete '%s'" msgstr "s'ha produït un error en suprimir «%s»" +#: builtin/gc.c rerere.c #, c-format msgid "failed to flush '%s'" msgstr "no s'ha pogut buidar «%s»" +#: builtin/gc.c msgid "failed to start systemctl" msgstr "s'ha produït un error en iniciar systemctl" +#: builtin/gc.c msgid "failed to run systemctl" msgstr "s'ha produït un error en executar systemctl" +#: builtin/gc.c #, c-format msgid "unrecognized --scheduler argument '%s'" msgstr "l'argument --scheduler no reconegut «%s»" +#: builtin/gc.c msgid "neither systemd timers nor crontab are available" msgstr "ni els temporitzadors de systemd ni de crontab estan disponibles" +#: builtin/gc.c #, c-format msgid "%s scheduler is not available" msgstr "el planificador %s no està disponible" +#: builtin/gc.c msgid "another process is scheduling background maintenance" msgstr "un altre procés està planificant un manteniment en segon pla" +#: builtin/gc.c msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=<scheduler>]" +#: builtin/gc.c msgid "scheduler" msgstr "planificador" +#: builtin/gc.c msgid "scheduler to trigger git maintenance run" msgstr "planificador per a activar l'execució de manteniment del git" +#: builtin/gc.c msgid "failed to set up maintenance schedule" msgstr "no s'ha pogut configurar la planificació del manteniment" +#: builtin/gc.c msgid "failed to add repo to global config" msgstr "no s'ha pogut afegir un repositori a la configuració global" +#: builtin/gc.c msgid "git maintenance <subcommand> [<options>]" -msgstr "git maintenance <subcommand> [<opcions>]" +msgstr "git maintenance <subordre> [<opcions>]" +#: builtin/grep.c msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]" msgstr "git grep [<opcions>] [-e] <patró> [<revisió>...] [[--] <camí>...]" +#: builtin/grep.c #, c-format msgid "grep: failed to create thread: %s" msgstr "grep: s'ha produït un error en crear fil: %s" +#: builtin/grep.c #, c-format msgid "invalid number of threads specified (%d) for %s" msgstr "s'ha especificat un nombre de fils no vàlid (%d) per a %s" @@ -6842,203 +8788,261 @@ msgstr "s'ha especificat un nombre de fils no vàlid (%d) per a %s" #. variable for tweaking threads, currently #. grep.threads #. +#: builtin/grep.c builtin/index-pack.c builtin/pack-objects.c #, c-format msgid "no threads support, ignoring %s" msgstr "no s'admeten fils, s'ignorarà %s" -#, c-format -msgid "unable to read tree (%s)" -msgstr "no s'ha pogut llegir l'arbre (%s)" - +#: builtin/grep.c #, c-format msgid "unable to read tree %s" msgstr "no s'ha pogut llegir l'arbre %s" +#: builtin/grep.c #, c-format msgid "unable to grep from object of type %s" msgstr "no es pot fer grep des d'un objecte de tipus %s" +#: builtin/grep.c #, c-format msgid "switch `%c' expects a numerical value" msgstr "l'opció «%c» espera un valor numèric" +#: builtin/grep.c msgid "search in index instead of in the work tree" msgstr "cerca en l'índex en lloc de l'arbre de treball" +#: builtin/grep.c msgid "find in contents not managed by git" msgstr "cerca en continguts no gestionats per git" +#: builtin/grep.c msgid "search in both tracked and untracked files" msgstr "cerca tant en fitxers seguits com en no seguits" +#: builtin/grep.c msgid "ignore files specified via '.gitignore'" msgstr "ignora els fitxers especificats mitjançant «.gitignore»" +#: builtin/grep.c msgid "recursively search in each submodule" msgstr "cerca recursivament a cada submòdul" +#: builtin/grep.c msgid "show non-matching lines" msgstr "mostra les línies no coincidents" +#: builtin/grep.c msgid "case insensitive matching" msgstr "coincidència no distingeix entre majúscules i minúscules" +#: builtin/grep.c msgid "match patterns only at word boundaries" msgstr "coincideix amb els patrons només als límits de paraula" +#: builtin/grep.c msgid "process binary files as text" msgstr "processa els fitxers binaris com a text" +#: builtin/grep.c msgid "don't match patterns in binary files" msgstr "no cerquis els patrons en els fitxers binaris" +#: builtin/grep.c msgid "process binary files with textconv filters" msgstr "processa els fitxers binaris amb filtres de textconv" +#: builtin/grep.c msgid "search in subdirectories (default)" msgstr "cerca als subdirectoris (per defecte)" +#: builtin/grep.c msgid "descend at most <n> levels" msgstr "descendeix com a màxim <n> nivells" +#: builtin/grep.c msgid "use extended POSIX regular expressions" msgstr "usa les expressions regulars POSIX ampliades" +#: builtin/grep.c msgid "use basic POSIX regular expressions (default)" msgstr "usa les expressions regulars POSIX bàsiques (per defecte)" +#: builtin/grep.c msgid "interpret patterns as fixed strings" msgstr "interpreta els patrons com a cadenes fixes" +#: builtin/grep.c msgid "use Perl-compatible regular expressions" msgstr "usa les expressions regulars compatibles amb Perl" +#: builtin/grep.c msgid "show line numbers" msgstr "mostra els números de línia" +#: builtin/grep.c msgid "show column number of first match" msgstr "mostra el nombre de columna de la primera coincidència" +#: builtin/grep.c msgid "don't show filenames" msgstr "no mostris els noms de fitxer" +#: builtin/grep.c msgid "show filenames" msgstr "mostra els noms de fitxer" +#: builtin/grep.c msgid "show filenames relative to top directory" msgstr "mostra els noms de fitxer relatius al directori superior" +#: builtin/grep.c msgid "show only filenames instead of matching lines" msgstr "mostra només els noms de fitxer en lloc de les línies coincidents" +#: builtin/grep.c msgid "synonym for --files-with-matches" msgstr "sinònim de --files-with-matches" +#: builtin/grep.c msgid "show only the names of files without match" msgstr "mostra només els noms dels fitxers sense coincidència" +#: builtin/grep.c msgid "print NUL after filenames" msgstr "imprimeix NUL després dels noms de fitxer" +#: builtin/grep.c msgid "show only matching parts of a line" msgstr "mostra només les parts de coincidents de la línia" +#: builtin/grep.c msgid "show the number of matches instead of matching lines" msgstr "mostra el nombre de coincidències en lloc de les línies coincidents" +#: builtin/grep.c msgid "highlight matches" msgstr "ressalta les coincidències" +#: builtin/grep.c msgid "print empty line between matches from different files" msgstr "imprimeix una línia buida entre coincidències de fitxers distints" +#: builtin/grep.c msgid "show filename only once above matches from same file" msgstr "" "mostra el nom de fitxer només una vegada a dalt de les coincidències del " "mateix fitxer" +#: builtin/grep.c msgid "show <n> context lines before and after matches" msgstr "mostra <n> línies de context abans i després d'una coincidència" +#: builtin/grep.c msgid "show <n> context lines before matches" msgstr "mostra <n> línies de context abans d'una coincidència" +#: builtin/grep.c msgid "show <n> context lines after matches" msgstr "mostra <n> línies de context després d'una coincidència" +#: builtin/grep.c msgid "use <n> worker threads" msgstr "usa <n> fils de treball" +#: builtin/grep.c msgid "shortcut for -C NUM" msgstr "drecera per a -C NUM" +#: builtin/grep.c msgid "show a line with the function name before matches" msgstr "mostra una línia amb el nom de funció abans de les coincidències" +#: builtin/grep.c msgid "show the surrounding function" msgstr "mostra la funció circumdant" +#: builtin/grep.c msgid "read patterns from file" msgstr "llegeix els patrons des d'un fitxer" +#: builtin/grep.c msgid "match <pattern>" msgstr "coincideix amb <patró>" +#: builtin/grep.c msgid "combine patterns specified with -e" msgstr "combina els patrons especificats amb -e" +#: builtin/grep.c msgid "indicate hit with exit status without output" msgstr "indica coincidència amb estat de sortida sense sortida textual" +#: builtin/grep.c msgid "show only matches from files that match all patterns" msgstr "" "mostra només les coincidències dels fitxers que coincideixin amb tots els " "patrons" +#: builtin/grep.c msgid "pager" msgstr "paginador" +#: builtin/grep.c msgid "show matching files in the pager" msgstr "mostra els fitxers coincidents en el paginador" +#: builtin/grep.c msgid "allow calling of grep(1) (ignored by this build)" msgstr "permet la invocació de grep(1) (ignorat per aquesta compilació)" +#: builtin/grep.c msgid "maximum number of results per file" msgstr "nombre màxim de resultats per fitxer" +#: builtin/grep.c msgid "no pattern given" msgstr "no s'ha donat cap patró" +#: builtin/grep.c msgid "--no-index or --untracked cannot be used with revs" msgstr "--no-index o --untracked no es pot usar amb revisions" +#: builtin/grep.c #, c-format msgid "unable to resolve revision: %s" msgstr "no s'ha pogut resoldre la revisió: %s" +#: builtin/grep.c msgid "--untracked not supported with --recurse-submodules" msgstr "--untracked no s'admet amb --recurse-submodules" +#: builtin/grep.c msgid "invalid option combination, ignoring --threads" msgstr "combinació d'opcions no vàlida, s'està ignorant --threads" +#: builtin/grep.c builtin/pack-objects.c msgid "no threads support, ignoring --threads" msgstr "no s'admeten fils, s'ignorarà --threads" +#: builtin/grep.c builtin/index-pack.c builtin/pack-objects.c #, c-format msgid "invalid number of threads specified (%d)" msgstr "s'ha especificat un nombre de fils no vàlid (%d)" +#: builtin/grep.c msgid "--open-files-in-pager only works on the worktree" msgstr "--open-files-in-pager només funciona en l'arbre de treball" +#: builtin/grep.c msgid "--[no-]exclude-standard cannot be used for tracked contents" msgstr "--[no-]exclude-standard no es pot utilitzar per als continguts seguits" +#: builtin/grep.c msgid "both --cached and trees are given" msgstr "ambdós --cached i arbres venen donats" +#: builtin/hash-object.c msgid "" "git hash-object [-t <type>] [-w] [--path=<file> | --no-filters]\n" " [--stdin [--literally]] [--] <file>..." @@ -7046,91 +9050,117 @@ msgstr "" "git hash-object [-t <tipus>] [-w] [--path=<fitxer> | --no-filters]\n" " [--stdin [--literally]] [--] <fitxer>..." +#: builtin/hash-object.c msgid "git hash-object [-t <type>] [-w] --stdin-paths [--no-filters]" msgstr "git hash-object [-t <tipus>] [-w] --stdin-paths [--no-filters]" +#: builtin/hash-object.c msgid "object type" msgstr "tipus d'objecte" +#: builtin/hash-object.c msgid "write the object into the object database" msgstr "escriu l'objecte a la base de dades d'objectes" +#: builtin/hash-object.c msgid "read the object from stdin" msgstr "llegeix l'objecte des de stdin" +#: builtin/hash-object.c msgid "store file as is without filters" msgstr "emmagatzema el fitxer tal com és sense filtres" +#: builtin/hash-object.c msgid "" "just hash any random garbage to create corrupt objects for debugging Git" msgstr "" "només suma qualsevol brossa aleatòria per a crear objectes malmesos per a " "depurar al Git" +#: builtin/hash-object.c msgid "process file as it were from this path" msgstr "processa el fitxer com si fos d'aquest camí" +#: builtin/help.c msgid "print all available commands" msgstr "imprimeix totes les ordres disponibles" +#: builtin/help.c msgid "show external commands in --all" msgstr "mostra les ordres externes a --all" +#: builtin/help.c msgid "show aliases in --all" msgstr "mostra els àlies a --all" +#: builtin/help.c msgid "exclude guides" msgstr "exclou guies" +#: builtin/help.c msgid "show man page" msgstr "mostra la pàgina de manual" +#: builtin/help.c msgid "show manual in web browser" msgstr "mostra la pàgina de manual en el navegador web" +#: builtin/help.c msgid "show info page" msgstr "mostra la pàgina d'informació" +#: builtin/help.c msgid "print command description" msgstr "imprimeix la descripció de l'ordre" +#: builtin/help.c msgid "print list of useful guides" msgstr "imprimeix la llista de guies útils" +#: builtin/help.c msgid "print list of user-facing repository, command and file interfaces" msgstr "" "imprimeix la llista de repositoris, ordres i interfícies de fitxers que veu " "l'usuari" +#: builtin/help.c msgid "print list of file formats, protocols and other developer interfaces" msgstr "" "mostra la llista de formats de fitxer, protocols i altres interfícies de " "desenvolupador" +#: builtin/help.c msgid "print all configuration variable names" msgstr "imprimeix tots els noms de les variables de configuració" +#: builtin/help.c msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]" -msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]" +msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<ordre>|<doc>]" +#: builtin/help.c #, c-format msgid "unrecognized help format '%s'" msgstr "format d'ajuda no reconegut «%s»" +#: builtin/help.c msgid "Failed to start emacsclient." msgstr "S'ha produït un error en iniciar emacsclient." +#: builtin/help.c msgid "Failed to parse emacsclient version." msgstr "S'ha produït un error en analitzar la versió d'emacsclient." +#: builtin/help.c #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "la versió d'emacsclient «%d» és massa vella (< 22)." +#: builtin/help.c #, c-format msgid "failed to exec '%s'" msgstr "s'ha produït un error en executar «%s»" +#: builtin/help.c #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -7139,6 +9169,7 @@ msgstr "" "«%s»: camí a un visualitzador de manuals no compatible.\n" "Considereu usar «man.<eina>.cmd» en lloc d'això." +#: builtin/help.c #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -7147,41 +9178,51 @@ msgstr "" "«%s»: ordre per a un visualitzador de manuals compatible.\n" "Considereu usar «man.<eina>.path» en lloc d'això." +#: builtin/help.c #, c-format msgid "'%s': unknown man viewer." msgstr "«%s»: visualitzador de manuals desconegut." +#: builtin/help.c msgid "no man viewer handled the request" msgstr "cap visualitzador de manuals ha gestionat la sol·licitud" +#: builtin/help.c msgid "no info viewer handled the request" msgstr "cap visualitzador d'informació ha gestionat la sol·licitud" +#: builtin/help.c git.c #, c-format msgid "'%s' is aliased to '%s'" msgstr "«%s» és un àlies de «%s»" +#: builtin/help.c git.c #, c-format msgid "bad alias.%s string: %s" msgstr "cadena «alias.%s» incorrecte: %s" +#: builtin/help.c #, c-format msgid "the '%s' option doesn't take any non-option arguments" msgstr "l'opció «%s» no pren cap argument que no sigui una opció" +#: builtin/help.c msgid "" "the '--no-[external-commands|aliases]' options can only be used with '--all'" msgstr "" "les opcions «--no-[external-commands|aliases]» només es poden utilitzar amb " "«--all»" +#: builtin/help.c #, c-format msgid "usage: %s%s" msgstr "ús: %s%s" +#: builtin/help.c msgid "'git help config' for more information" msgstr "«git help config» per a més informació" +#: builtin/hook.c msgid "" "git hook run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-" "args>]" @@ -7189,75 +9230,95 @@ msgstr "" "git hook run [--ignore-missing] [--to-stdin=<camí>] <hook-name> [-- <hook-" "args>]" +#: builtin/hook.c msgid "silently ignore missing requested <hook-name>" msgstr "ignora silenciosament la sol·licitud <hook-name> perduda" +#: builtin/hook.c msgid "file to read into hooks' stdin" msgstr "fitxer per a llegir a l'entrada estàndard dels lligams" +#: builtin/index-pack.c #, c-format msgid "object type mismatch at %s" msgstr "hi ha una discordança de tipus d'objecte a %s" +#: builtin/index-pack.c #, c-format msgid "did not receive expected object %s" msgstr "no s'ha rebut l'objecte esperat %s" +#: builtin/index-pack.c #, c-format msgid "object %s: expected type %s, found %s" msgstr "objecte %s: s'esperava el tipus %s, s'ha trobat %s" +#: builtin/index-pack.c #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "no es pot omplir %d octet" msgstr[1] "no es poden omplir %d octets" +#: builtin/index-pack.c msgid "early EOF" msgstr "EOF prematur" +#: builtin/index-pack.c msgid "read error on input" msgstr "error de lectura d'entrada" +#: builtin/index-pack.c msgid "used more bytes than were available" msgstr "s'han usat més octets que hi havia disponibles" +#: builtin/index-pack.c builtin/pack-objects.c msgid "pack too large for current definition of off_t" msgstr "paquet massa gran per a la definició actual d'off_t" +#: builtin/index-pack.c #, c-format msgid "pack exceeds maximum allowed size (%s)" msgstr "el paquet supera la mida màxima permesa (%s)" +#: builtin/index-pack.c msgid "pack signature mismatch" msgstr "hi ha una discordança de signatura de paquet" +#: builtin/index-pack.c #, c-format msgid "pack version %<PRIu32> unsupported" msgstr "la versió de paquet %<PRIu32> no és compatible" +#: builtin/index-pack.c #, c-format msgid "pack has bad object at offset %<PRIuMAX>: %s" msgstr "el paquet té un objecte incorrecte a la posició %<PRIuMAX>: %s" +#: builtin/index-pack.c #, c-format msgid "inflate returned %d" msgstr "la inflació ha retornat %d" +#: builtin/index-pack.c msgid "offset value overflow for delta base object" msgstr "" "desbordament de valor de desplaçament per a l'objecte base de diferències" +#: builtin/index-pack.c msgid "delta base offset is out of bound" msgstr "el desplaçament de base de diferències està fora de límits" +#: builtin/index-pack.c #, c-format msgid "unknown object type %d" msgstr "tipus d'objecte desconegut %d" +#: builtin/index-pack.c msgid "cannot pread pack file" msgstr "no es pot fer pread en el fitxer empaquetat" +#: builtin/index-pack.c #, c-format msgid "premature end of pack file, %<PRIuMAX> byte missing" msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing" @@ -7265,150 +9326,189 @@ msgstr[0] "el final del fitxer empaquetat és prematur, manca %<PRIuMAX> octet" msgstr[1] "" "el final del fitxer empaquetat és prematur, manquen %<PRIuMAX> octets" +#: builtin/index-pack.c msgid "serious inflate inconsistency" msgstr "hi ha una inconsistència seriosa d'inflació" +#: builtin/index-pack.c #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "S'HA TROBAT UNA COL·LISIÓ SHA1 AMB %s !" +#: builtin/index-pack.c #, c-format msgid "cannot read existing object info %s" msgstr "no es pot llegir la informació d'objecte existent %s" +#: builtin/index-pack.c #, c-format msgid "cannot read existing object %s" msgstr "no es pot llegir l'objecte existent %s" +#: builtin/index-pack.c #, c-format msgid "invalid blob object %s" msgstr "objecte de blob no vàlid %s" +#: builtin/index-pack.c msgid "fsck error in packed object" msgstr "fsck error en un objecte empaquetat" +#: builtin/index-pack.c #, c-format msgid "Not all child objects of %s are reachable" msgstr "No tots els objectes fills de %s són abastables" +#: builtin/index-pack.c msgid "failed to apply delta" msgstr "s'ha produït un error en aplicar la diferència" +#: builtin/index-pack.c msgid "Receiving objects" msgstr "S'estan rebent objectes" +#: builtin/index-pack.c msgid "Indexing objects" msgstr "S'estan indexant objectes" +#: builtin/index-pack.c msgid "pack is corrupted (SHA1 mismatch)" msgstr "el paquet és malmès (discordança SHA1)" +#: builtin/index-pack.c msgid "cannot fstat packfile" msgstr "no es pot fer fstat en el fitxer de paquet" +#: builtin/index-pack.c msgid "pack has junk at the end" msgstr "el paquet té brossa al seu final" +#: builtin/index-pack.c msgid "confusion beyond insanity in parse_pack_objects()" msgstr "confusió més enllà de la bogeria en parse_pack_objects()" +#: builtin/index-pack.c msgid "Resolving deltas" msgstr "S'estan resolent les diferències" +#: builtin/index-pack.c builtin/pack-objects.c #, c-format msgid "unable to create thread: %s" msgstr "no s'ha pogut crear fil: %s" +#: builtin/index-pack.c msgid "confusion beyond insanity" msgstr "confusió més enllà de la bogeria" +#: builtin/index-pack.c #, c-format msgid "completed with %d local object" msgid_plural "completed with %d local objects" msgstr[0] "s'ha completat amb %d objecte local" msgstr[1] "s'ha completat amb %d objectes locals" +#: builtin/index-pack.c #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "Suma de verificació final no esperada per a %s (corrupció de disc?)" +#: builtin/index-pack.c #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "el paquet té %d diferència no resolta" msgstr[1] "el paquet té %d diferències no resoltes" +#: builtin/index-pack.c #, c-format msgid "unable to deflate appended object (%d)" msgstr "no s'ha pogut desinflar l'objecte annexat (%d)" +#: builtin/index-pack.c #, c-format msgid "local object %s is corrupt" msgstr "l'objecte local %s és malmès" +#: builtin/index-pack.c #, c-format msgid "packfile name '%s' does not end with '.%s'" msgstr "el nom del fitxer de paquet «%s» no acaba amb «.%s»" +#: builtin/index-pack.c #, c-format msgid "cannot write %s file '%s'" msgstr "no es pot escriure «%s» al fitxer «%s»" +#: builtin/index-pack.c #, c-format msgid "cannot close written %s file '%s'" msgstr "no s'ha pogut tancar el fitxer %s escrit «%s»" +#: builtin/index-pack.c #, c-format msgid "unable to rename temporary '*.%s' file to '%s'" msgstr "no s'ha pogut canviar el nom del fitxer temporal «*.%s» a «%s»" +#: builtin/index-pack.c msgid "error while closing pack file" msgstr "error en tancar el fitxer empaquetat" +#: builtin/index-pack.c builtin/pack-objects.c #, c-format msgid "bad pack.indexVersion=%<PRIu32>" msgstr "bad pack.indexVersion=%<PRIu32>" +#: builtin/index-pack.c #, c-format msgid "Cannot open existing pack file '%s'" msgstr "No es pot obrir el fitxer empaquetat existent «%s»" +#: builtin/index-pack.c #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "No es pot obrir el fitxer d'índex de paquets existent de «%s»" +#: builtin/index-pack.c #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "sense diferències: %d objecte" msgstr[1] "sense diferències: %d objectes" +#: builtin/index-pack.c #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "longitud de cadena = %d: %lu objecte" msgstr[1] "longitud de cadena = %d: %lu objectes" +#: builtin/index-pack.c msgid "Cannot come back to cwd" msgstr "No es pot tornar al directori de treball actual" +#: builtin/index-pack.c #, c-format msgid "bad %s" msgstr "%s incorrecte" +#: builtin/index-pack.c builtin/init-db.c setup.c #, c-format msgid "unknown hash algorithm '%s'" msgstr "algorisme de resum desconegut «%s»" +#: builtin/index-pack.c msgid "--stdin requires a git repository" msgstr "--stdin requereix un repositori git" +#: builtin/index-pack.c msgid "--verify with no packfile name given" msgstr "s'ha donat --verify sense nom de fitxer de paquet" +#: builtin/index-pack.c builtin/unpack-objects.c msgid "fsck error in pack objects" msgstr "error fsck als objectes del paquet" +#: builtin/init-db.c msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>]\n" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" @@ -7420,32 +9520,40 @@ msgstr "" " [--separate-git-dir <git-dir>] [--object-format=<format>]\n" " [--ref-format=<format>]\n" " [-b <branch-name> | --initial-branch=<branch-name>]\n" -" [--shared[=<permissions>]] [<directory>]" +" [--shared[=<permissions>]] [<directori>]" +#: builtin/init-db.c msgid "permissions" msgstr "permisos" +#: builtin/init-db.c msgid "specify that the git repository is to be shared amongst several users" msgstr "" "especifica que el repositori de git es compartirà entre diversos usuaris" +#: builtin/init-db.c msgid "override the name of the initial branch" msgstr "sobreescriu el nom de la branca inicial" +#: builtin/init-db.c builtin/verify-pack.c msgid "hash" msgstr "resum" +#: builtin/init-db.c builtin/show-index.c builtin/verify-pack.c msgid "specify the hash algorithm to use" msgstr "especifiqueu l'algorisme de resum a usar" +#: builtin/init-db.c #, c-format msgid "cannot mkdir %s" msgstr "no es pot mkdir %s" +#: builtin/init-db.c #, c-format msgid "cannot chdir to %s" msgstr "no es pot canviar de directori a %s" +#: builtin/init-db.c #, c-format msgid "" "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-" @@ -7454,174 +9562,252 @@ msgstr "" "no es permet %s (o --work-tree=<directori>) sense especificar %s (o --git-" "dir=<directori>)" +#: builtin/init-db.c #, c-format msgid "Cannot access work tree '%s'" msgstr "No es pot accedir a l'arbre de treball «%s»" +#: builtin/init-db.c msgid "--separate-git-dir incompatible with bare repository" msgstr "--separate-git-dir és incompatible amb un repositori nu" +#: builtin/interpret-trailers.c msgid "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" +" [(--trailer (<key>|<key-alias>)[(=|:)<value>])...]\n" " [--parse] [<file>...]" msgstr "" "git interpret-trailers [--in-place] [--trim-empty]\n" -" [(--trailer (<key>|<keyAlias>)[(=|:)<value>])...]\n" -" [--parse] [<file>...]" +" [(--trailer (<clau>|<alies-clau>)[(=|:)<valor>])...]\n" +" [--parse] [<fitxer>...]" + +#: builtin/interpret-trailers.c wrapper.c +#, c-format +msgid "could not stat %s" +msgstr "no s'ha pogut fer stat a %s" + +#: builtin/interpret-trailers.c +#, c-format +msgid "file %s is not a regular file" +msgstr "el fitxer %s no és un fitxer regular" + +#: builtin/interpret-trailers.c +#, c-format +msgid "file %s is not writable by user" +msgstr "el fitxer %s no és gravable per l'usuari" + +#: builtin/interpret-trailers.c +msgid "could not open temporary file" +msgstr "no s'ha pogut obrir el fitxer temporal" + +#: builtin/interpret-trailers.c +#, c-format +msgid "could not read input file '%s'" +msgstr "no s'ha pogut llegir el fitxer d'entrada «%s»" + +#: builtin/interpret-trailers.c builtin/mktag.c imap-send.c +msgid "could not read from stdin" +msgstr "no s'ha pogut llegir des de stdin" +#: builtin/interpret-trailers.c +#, c-format +msgid "could not rename temporary file to %s" +msgstr "no s'ha pogut canviar el nom del fitxer temporal a %s" + +#: builtin/interpret-trailers.c msgid "edit files in place" msgstr "edita els fitxers in situ" +#: builtin/interpret-trailers.c msgid "trim empty trailers" msgstr "escurça els remolcs buits" +#: builtin/interpret-trailers.c msgid "placement" msgstr "posicionament" +#: builtin/interpret-trailers.c msgid "where to place the new trailer" msgstr "on ubicar el «trailer» nou" +#: builtin/interpret-trailers.c msgid "action if trailer already exists" msgstr "acció si el «trailer» ja existeix" +#: builtin/interpret-trailers.c msgid "action if trailer is missing" msgstr "acció si el «trailer» falta" +#: builtin/interpret-trailers.c msgid "output only the trailers" msgstr "mostra només els «trailer»" +#: builtin/interpret-trailers.c msgid "do not apply trailer.* configuration variables" msgstr "no apliquis les variables de configuració trailer.*" +#: builtin/interpret-trailers.c 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" +#: builtin/interpret-trailers.c msgid "alias for --only-trailers --only-input --unfold" msgstr "àlies per a --only-trailers --only-input --unfold" +#: builtin/interpret-trailers.c msgid "do not treat \"---\" as the end of input" msgstr "no tractis «---» com el final de l'entrada" +#: builtin/interpret-trailers.c msgid "trailer(s) to add" msgstr "remolcs a afegir" +#: builtin/interpret-trailers.c msgid "--trailer with --only-input does not make sense" msgstr "--trailer amb --only-input no té sentit" +#: builtin/interpret-trailers.c msgid "no input file given for in-place editing" msgstr "no s'ha donat cap fitxer d'entrada per a edició in situ" +#: builtin/log.c msgid "git log [<options>] [<revision-range>] [[--] <path>...]" msgstr "git log [<opcions>] [<rang-de-revisions>] [[--] <camí>...]" +#: builtin/log.c msgid "git show [<options>] <object>..." msgstr "git show [<opcions>] <objecte>..." +#: builtin/log.c #, c-format msgid "invalid --decorate option: %s" msgstr "opció --decorate no vàlida: %s" +#: builtin/log.c diff.c msgid "suppress diff output" msgstr "omet la sortida de diferències" +#: builtin/log.c msgid "show source" msgstr "mostra la font" +#: builtin/log.c msgid "clear all previously-defined decoration filters" msgstr "neteja tots els filtres de decoració prèviament definits" +#: builtin/log.c msgid "only decorate refs that match <pattern>" msgstr "només decora les referències que coincideixin amb <patró>" +#: builtin/log.c msgid "do not decorate refs that match <pattern>" msgstr "no decoris les referències que coincideixen amb <patró>" +#: builtin/log.c msgid "decorate options" msgstr "opcions de decoració" +#: builtin/log.c msgid "" "trace the evolution of line range <start>,<end> or function :<funcname> in " "<file>" msgstr "" -"traça l'evolució del rang de línia <start>,<end> o funcions :<funcname> a " -"<fitxer>" +"traça l'evolució del rang de línia <inici>,<final> o funcions :<nom-funció> " +"a <fitxer>" +#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c #, c-format msgid "unrecognized argument: %s" msgstr "argument no reconegut: %s" +#: builtin/log.c msgid "-L<range>:<file> cannot be used with pathspec" -msgstr "-L<range>:<fitxer> no es pot usar amb una especificació de camí" +msgstr "-L<rang>:<fitxer> no es pot usar amb una especificació de camí" +#: builtin/log.c #, c-format msgid "Final output: %d %s\n" msgstr "Sortida final: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "no s'ha pogut crear el directori temporal de l'objecte" - +#: builtin/log.c #, c-format msgid "git show %s: bad file" msgstr "git show %s: fitxer incorrecte" +#: builtin/log.c #, c-format msgid "could not read object %s" msgstr "no s'ha pogut llegir l'objecte %s" +#: builtin/log.c #, c-format msgid "unknown type: %d" msgstr "tipus desconegut: %d" +#: builtin/log.c #, c-format msgid "%s: invalid cover from description mode" msgstr "%s: cobertura no vàlida des del mode descripció" +#: builtin/log.c msgid "format.headers without value" msgstr "format.headers sense valor" +#: builtin/log.c #, c-format msgid "cannot open patch file %s" msgstr "no s'ha pogut obrir el fitxer de pedaç %s" +#: builtin/log.c msgid "need exactly one range" msgstr "necessita exactament un interval" +#: builtin/log.c msgid "not a range" msgstr "no és un interval" +#: builtin/log.c #, c-format msgid "unable to read branch description file '%s'" msgstr "no es pot llegir el fitxer de descripció de la branca «%s»" +#: builtin/log.c msgid "cover letter needs email format" msgstr "la carta de presentació necessita un format de correu electrònic" +#: builtin/log.c msgid "failed to create cover-letter file" msgstr "s'ha produït un error en crear el fitxer de carta de presentació" +#: builtin/log.c #, c-format msgid "insane in-reply-to: %s" msgstr "in-reply-to boig: %s" +#: builtin/log.c msgid "git format-patch [<options>] [<since> | <revision-range>]" msgstr "git format-patch [<opcions>] [<des-de> | <rang-de-revisions>]" +#: builtin/log.c msgid "two output directories?" msgstr "dos directoris de sortida?" +#: builtin/log.c #, c-format msgid "unknown commit %s" msgstr "comissió desconeguda %s" +#: builtin/log.c builtin/replace.c #, c-format msgid "failed to resolve '%s' as a valid ref" msgstr "s'ha produït un error en resoldre «%s» com a referència vàlida" +#: builtin/log.c msgid "could not find exact merge base" msgstr "no s'ha pogut trobar la base exacta de la fusió" +#: builtin/log.c msgid "" "failed to get upstream, if you want to record base commit automatically,\n" "please use git branch --set-upstream-to to track a remote branch.\n" @@ -7632,228 +9818,302 @@ msgstr "" "branca remota. També podeu especificar la comissió base amb --base=<base-" "commit-id> manualment" +#: builtin/log.c msgid "failed to find exact merge base" msgstr "no s'ha pogut trobar la base exacta de la fusió" +#: builtin/log.c msgid "base commit should be the ancestor of revision list" msgstr "la comissió base ha de ser l'avantpassat de la llista de revisions" +#: builtin/log.c msgid "base commit shouldn't be in revision list" msgstr "la comissió base no ha de ser en la llista de revisions" +#: builtin/log.c msgid "cannot get patch id" msgstr "no es pot obtenir l'id del pedaç" +#: builtin/log.c msgid "failed to infer range-diff origin of current series" msgstr "" "no s'ha pogut inferir el rang de diferències d'origen de les sèries actuals" +#: builtin/log.c #, c-format msgid "using '%s' as range-diff origin of current series" msgstr "utilitzant «%s» com a origen de rang de diferències de la sèrie actual" +#: builtin/log.c msgid "use [PATCH n/m] even with a single patch" msgstr "usa [PATCH n/m] fins i tot amb un sol pedaç" +#: builtin/log.c msgid "use [PATCH] even with multiple patches" msgstr "usa [PATCH] fins i tot amb múltiples pedaços" +#: builtin/log.c msgid "print patches to standard out" msgstr "imprimeix els pedaços a la sortida estàndard" +#: builtin/log.c msgid "generate a cover letter" msgstr "genera una carta de presentació" +#: builtin/log.c msgid "use simple number sequence for output file names" msgstr "usa una seqüència de números per als noms dels fitxers de sortida" +#: builtin/log.c msgid "sfx" msgstr "sufix" +#: builtin/log.c msgid "use <sfx> instead of '.patch'" msgstr "usa <sufix> en lloc de «.patch»" +#: builtin/log.c msgid "start numbering patches at <n> instead of 1" msgstr "comença numerant els pedaços a <n> en lloc d'1" +#: builtin/log.c msgid "reroll-count" msgstr "reroll-count" +#: builtin/log.c msgid "mark the series as Nth re-roll" msgstr "marca la sèrie com a l'enèsima llançada" +#: builtin/log.c msgid "max length of output filename" msgstr "mida màxima del nom del fitxer de sortida" -msgid "use [RFC PATCH] instead of [PATCH]" -msgstr "useu [RFC PATCH] en comptes de [PATCH]" +#: builtin/log.c +msgid "rfc" +msgstr "rfc" + +#: builtin/log.c +msgid "add <rfc> (default 'RFC') before 'PATCH'" +msgstr "afig <rfc> (per defecte «RFC») abans de «PATCH»" +#: builtin/log.c msgid "cover-from-description-mode" msgstr "cover-from-description-mode" +#: builtin/log.c msgid "generate parts of a cover letter based on a branch's description" msgstr "" "genera parts d'una carta de presentació basant-se en la descripció d'una " "branca" +#: builtin/log.c msgid "use branch description from file" msgstr "utilitza la descripció de la branca des del fitxer" +#: builtin/log.c msgid "use [<prefix>] instead of [PATCH]" msgstr "useu [<prefix>] en comptes de [PATCH]" +#: builtin/log.c msgid "store resulting files in <dir>" msgstr "emmagatzema els fitxers resultants a <directori>" +#: builtin/log.c msgid "don't strip/add [PATCH]" msgstr "no despullis/afegeixis [PATCH]" +#: builtin/log.c msgid "don't output binary diffs" msgstr "no emetis diferències binàries" +#: builtin/log.c msgid "output all-zero hash in From header" msgstr "emet un resum de tots zeros en la capçalera From" +#: builtin/log.c msgid "don't include a patch matching a commit upstream" msgstr "no incloguis pedaços que coincideixin amb comissions a la font" +#: builtin/log.c msgid "show patch format instead of default (patch + stat)" msgstr "" "mostra el format de pedaç en lloc del per defecte (pedaç + estadístiques)" +#: builtin/log.c msgid "Messaging" msgstr "Missatgeria" +#: builtin/log.c msgid "header" msgstr "capçalera" +#: builtin/log.c msgid "add email header" msgstr "afegeix una capçalera de correu electrònic" +#: builtin/log.c msgid "email" msgstr "correu electrònic" +#: builtin/log.c msgid "add To: header" msgstr "afegeix la capçalera To:" +#: builtin/log.c msgid "add Cc: header" msgstr "afegeix la capçalera Cc:" +#: builtin/log.c msgid "ident" msgstr "identitat" +#: builtin/log.c msgid "set From address to <ident> (or committer ident if absent)" msgstr "" "estableix l'adreça From a <identitat> (o la identitat del comitent si manca)" +#: builtin/log.c msgid "message-id" msgstr "ID de missatge" +#: builtin/log.c msgid "make first mail a reply to <message-id>" msgstr "fes que el primer missatge sigui una resposta a <ID de missatge>" +#: builtin/log.c msgid "boundary" msgstr "límit" +#: builtin/log.c msgid "attach the patch" msgstr "adjunta el pedaç" +#: builtin/log.c msgid "inline the patch" msgstr "posa el pedaç en el cos" +#: builtin/log.c msgid "enable message threading, styles: shallow, deep" msgstr "habilita l'enfilada de missatges, estils: shallow, deep" +#: builtin/log.c msgid "signature" msgstr "signatura" +#: builtin/log.c msgid "add a signature" msgstr "afegeix una signatura" +#: builtin/log.c msgid "base-commit" msgstr "comissió base" +#: builtin/log.c msgid "add prerequisite tree info to the patch series" msgstr "afegeix la informació d'arbre requerida a la sèrie de pedaços" +#: builtin/log.c msgid "add a signature from a file" msgstr "afegeix una signatura des d'un fitxer" +#: builtin/log.c msgid "don't print the patch filenames" msgstr "no imprimeixis els noms de fitxer del pedaç" +#: builtin/log.c msgid "show progress while generating patches" msgstr "mostra el progrés durant la generació de pedaços" +#: builtin/log.c msgid "show changes against <rev> in cover letter or single patch" msgstr "" -"mostra els canvis contra <rev> a la carta de presentació o a un sol pedaç" +"mostra els canvis contra <revisió> a la carta de presentació o a un sol pedaç" +#: builtin/log.c msgid "show changes against <refspec> in cover letter or single patch" msgstr "" "mostra els canvis contra <refspec> a la carta de presentació o a un sol pedaç" +#: builtin/log.c builtin/range-diff.c msgid "percentage by which creation is weighted" msgstr "percentatge pel qual la creació és ponderada" +#: builtin/log.c msgid "show in-body From: even if identical to the e-mail header" msgstr "" "mostra en el cos el remitent: encara que sigui idèntic a la capçalera del " "correu electrònic" +#: builtin/log.c #, c-format msgid "invalid ident line: %s" msgstr "línia d'identitat no vàlida: %s" +#: builtin/log.c msgid "--name-only does not make sense" msgstr "--name-only no té sentit" +#: builtin/log.c msgid "--name-status does not make sense" msgstr "--name-status no té sentit" +#: builtin/log.c msgid "--check does not make sense" msgstr "--check no té sentit" +#: builtin/log.c msgid "--remerge-diff does not make sense" msgstr "--remerge-diff no té sentit" +#: builtin/log.c builtin/submodule--helper.c rerere.c submodule.c #, c-format msgid "could not create directory '%s'" msgstr "no s'ha pogut crear el directori «%s»" +#: builtin/log.c msgid "--interdiff requires --cover-letter or single patch" msgstr "--interdiff requereix --cover-letter o un sol pedaç" +#: builtin/log.c msgid "Interdiff:" msgstr "Interdiff:" +#: builtin/log.c #, c-format msgid "Interdiff against v%d:" msgstr "Interdiff contra v%d:" +#: builtin/log.c msgid "--range-diff requires --cover-letter or single patch" msgstr "--range-diff requereix --cover-letter o un sol pedaç" +#: builtin/log.c msgid "Range-diff:" msgstr "Diferència de l'interval:" +#: builtin/log.c #, c-format msgid "Range-diff against v%d:" msgstr "Diferència de l'interval contra el v%d:" +#: builtin/log.c #, c-format msgid "unable to read signature file '%s'" msgstr "no s'ha pogut llegir el fitxer de signatura «%s»" +#: builtin/log.c msgid "Generating patches" msgstr "S'estan generant els pedaços" +#: builtin/log.c msgid "failed to create output files" msgstr "no s'han pogut crear els fitxers de sortida" +#: builtin/log.c msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<font> [<cap> [<límit>]]]" +#: builtin/log.c #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -7861,108 +10121,126 @@ msgstr "" "No s'ha pogut trobar una branca remota seguida. Especifiqueu <font> " "manualment.\n" +#: builtin/ls-files.c builtin/ls-tree.c #, c-format msgid "could not get object info about '%s'" msgstr "no s'ha pogut obtenir la informació sobre l'objecte «%s»" -#, c-format -msgid "bad ls-files format: element '%s' does not start with '('" -msgstr "format incorrecte del ls-files: l'element «%s» no comença amb «(»" - -#, c-format -msgid "bad ls-files format: element '%s' does not end in ')'" -msgstr "format incorrecte del ls-files: l'element «%s» no acaba amb «)»" - -#, c-format -msgid "bad ls-files format: %%%.*s" -msgstr "format incorrecte de ls-files: %%%.*s" - +#: builtin/ls-files.c msgid "git ls-files [<options>] [<file>...]" msgstr "git ls-files [<opcions>] [<fitxer>...]" +#: builtin/ls-files.c builtin/merge-tree.c msgid "separate paths with the NUL character" msgstr "separa els camins amb el caràcter NUL" +#: builtin/ls-files.c msgid "identify the file status with tags" msgstr "identifica l'estat de fitxer amb etiquetes" +#: builtin/ls-files.c msgid "use lowercase letters for 'assume unchanged' files" msgstr "usa lletres minúscules per als fitxers «assume unchanged»" +#: builtin/ls-files.c msgid "use lowercase letters for 'fsmonitor clean' files" msgstr "usa lletres minúscules per als fitxers «fsmonitor clean»" +#: builtin/ls-files.c msgid "show cached files in the output (default)" msgstr "" "mostra en la sortida els fitxers desats en la memòria cau (per defecte)" +#: builtin/ls-files.c msgid "show deleted files in the output" msgstr "mostra en la sortida els fitxers suprimits" +#: builtin/ls-files.c msgid "show modified files in the output" msgstr "mostra en la sortida els fitxers modificats" +#: builtin/ls-files.c msgid "show other files in the output" msgstr "mostra en la sortida els altres fitxers" +#: builtin/ls-files.c msgid "show ignored files in the output" msgstr "mostra en la sortida els fitxers ignorats" +#: builtin/ls-files.c msgid "show staged contents' object name in the output" msgstr "mostra en la sortida el nom d'objecte dels continguts «stage»" +#: builtin/ls-files.c msgid "show files on the filesystem that need to be removed" msgstr "mostra els fitxers en el sistema de fitxers que s'han d'eliminar" +#: builtin/ls-files.c msgid "show 'other' directories' names only" msgstr "mostra només els noms dels directoris «other»" +#: builtin/ls-files.c msgid "show line endings of files" msgstr "mostra els terminadors de línia dels fitxers" +#: builtin/ls-files.c msgid "don't show empty directories" msgstr "no mostris els directoris buits" +#: builtin/ls-files.c msgid "show unmerged files in the output" msgstr "mostra en la sortida els fitxers sense fusionar" +#: builtin/ls-files.c msgid "show resolve-undo information" msgstr "mostra la informació de resolució de desfet" +#: builtin/ls-files.c msgid "skip files matching pattern" msgstr "omet els fitxers coincidents amb el patró" +#: builtin/ls-files.c msgid "read exclude patterns from <file>" msgstr "llegeix els patrons des de <fitxer>" +#: builtin/ls-files.c msgid "read additional per-directory exclude patterns in <file>" msgstr "llegeix els patrons addicionals d'exclusió per directori en <fitxer>" +#: builtin/ls-files.c msgid "add the standard git exclusions" msgstr "afegeix les exclusions estàndards de git" +#: builtin/ls-files.c msgid "make the output relative to the project top directory" msgstr "fes que la sortida sigui relativa al directori superior del projecte" +#: builtin/ls-files.c msgid "if any <file> is not in the index, treat this as an error" msgstr "si qualsevol <fitxer> no és en l'índex, tracta-ho com a error" +#: builtin/ls-files.c builtin/merge-tree.c msgid "tree-ish" msgstr "arbre" +#: builtin/ls-files.c msgid "pretend that paths removed since <tree-ish> are still present" msgstr "" "pretén que els camins eliminats després de <arbre> encara siguin presents" +#: builtin/ls-files.c msgid "show debugging data" msgstr "mostra les dades de depuració" +#: builtin/ls-files.c msgid "suppress duplicate entries" msgstr "suprimeix les entrades duplicades" +#: builtin/ls-files.c msgid "show sparse directories in the presence of a sparse index" msgstr "mostra els directoris dispersos en presència d'un índex dispers" +#: builtin/ls-files.c msgid "" "--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, " "--eol" @@ -7970,163 +10248,202 @@ msgstr "" "--format no es pot usar amb -s, -o, -k, -t, --resolve-undo, --deduplicate, --" "eol" +#: builtin/ls-remote.c msgid "" -"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n" +"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n" " [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n" " [--symref] [<repository> [<patterns>...]]" msgstr "" -"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n" -" [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n" -" [--symref] [<repository> [<patterns>...]]" +"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n" +" [-q | --quiet] [--exit-code] [--get-url] [--sort=<clau>]\n" +" [--symref] [<repositori> [<patrons>...]]" +#: builtin/ls-remote.c msgid "do not print remote URL" msgstr "no imprimeixis l'URL remot" +#: builtin/ls-remote.c builtin/rebase.c msgid "exec" msgstr "executable" +#: builtin/ls-remote.c msgid "path of git-upload-pack on the remote host" msgstr "camí a git-upload-pack en la màquina remota" +#: builtin/ls-remote.c msgid "limit to tags" msgstr "limita a etiquetes" -msgid "limit to heads" -msgstr "limita a «heads»" +# limita-ho? +#: builtin/ls-remote.c +msgid "limit to branches" +msgstr "limita a les branques" +#: builtin/ls-remote.c builtin/show-ref.c +msgid "deprecated synonym for --branches" +msgstr "sinònim de «--branches» en desús" + +#: builtin/ls-remote.c msgid "do not show peeled tags" msgstr "no mostris les etiquetes pelades" +#: builtin/ls-remote.c msgid "take url.<base>.insteadOf into account" msgstr "tingues en compte url.<base>.insteadOf" +#: builtin/ls-remote.c msgid "exit with exit code 2 if no matching refs are found" msgstr "surt amb codi de sortida 2 si no es troba cap referència coincident" +#: builtin/ls-remote.c msgid "show underlying ref in addition to the object pointed by it" msgstr "mostra la referència subjacent a més de l'objecte que assenyali" +#: builtin/ls-tree.c msgid "git ls-tree [<options>] <tree-ish> [<path>...]" msgstr "git ls-tree [<opcions>] <arbre> [<camí>...]" -#, c-format -msgid "bad ls-tree format: element '%s' does not start with '('" -msgstr "format incorrecte del ls-tree: l'element '%s' no comença amb «(»" - -#, c-format -msgid "bad ls-tree format: element '%s' does not end in ')'" -msgstr "format incorrecte del ls-tree: l'element '%s' no acaba en «(»" - -#, c-format -msgid "bad ls-tree format: %%%.*s" -msgstr "format incorrecte de ls-tree: %%%.*s" - +#: builtin/ls-tree.c msgid "only show trees" msgstr "mostra només els arbres" +#: builtin/ls-tree.c msgid "recurse into subtrees" msgstr "inclou recursivament als subarbres" +#: builtin/ls-tree.c msgid "show trees when recursing" msgstr "mostra els arbres quan es treballa recursivament" +#: builtin/ls-tree.c msgid "terminate entries with NUL byte" msgstr "acaba les entrades amb un octet NUL" +#: builtin/ls-tree.c msgid "include object size" msgstr "mida de l'objecte d'inclusió" +#: builtin/ls-tree.c msgid "list only filenames" msgstr "llista només els noms de fitxer" +#: builtin/ls-tree.c msgid "list only objects" msgstr "llista només els objectes" +#: builtin/ls-tree.c msgid "use full path names" msgstr "usa els noms de camí complets" +#: builtin/ls-tree.c msgid "list entire tree; not just current directory (implies --full-name)" msgstr "" "llista l'arbre sencer; no només el directori actual (implica --full-name)" +#: builtin/ls-tree.c msgid "--format can't be combined with other format-altering options" msgstr "--format no es pot combinar amb altres opcions d'alteració de format" #. TRANSLATORS: keep <> in "<" mail ">" info. +#: builtin/mailinfo.c msgid "git mailinfo [<options>] <msg> <patch> < mail >info" msgstr "git mailinfo [<opcions>] <msg> <pedaç> < mail >info" +#: builtin/mailinfo.c msgid "keep subject" msgstr "mantén l'assumpte" +#: builtin/mailinfo.c msgid "keep non patch brackets in subject" msgstr "mantén els parèntesis que no són del pedaç en l'assumpte" +#: builtin/mailinfo.c msgid "copy Message-ID to the end of commit message" msgstr "copia el Message-ID al final del missatge de comissió" +#: builtin/mailinfo.c msgid "re-code metadata to i18n.commitEncoding" msgstr "torna a codificar les metadades a i18n.commitEncoding" +#: builtin/mailinfo.c msgid "disable charset re-coding of metadata" msgstr "inhabilita la recodificació del joc de caràcters de les metadades" +#: builtin/mailinfo.c msgid "encoding" msgstr "codificació" +#: builtin/mailinfo.c msgid "re-code metadata to this encoding" msgstr "recodifica les metadades en aquesta codificació" +#: builtin/mailinfo.c msgid "use scissors" msgstr "usa les tisores" +#: builtin/mailinfo.c msgid "<action>" msgstr "<acció>" +#: builtin/mailinfo.c msgid "action when quoted CR is found" msgstr "acció quan es troba un CR entre cometes" +#: builtin/mailinfo.c msgid "use headers in message's body" msgstr "utilitza les capçaleres en el cos del missatge" +#: builtin/mailsplit.c msgid "reading patches from stdin/tty..." msgstr "s'estan llegint pedaços de stdin/tty..." +#: builtin/mailsplit.c #, c-format msgid "empty mbox: '%s'" msgstr "mbox buit: «%s»" +#: builtin/merge-base.c msgid "git merge-base [-a | --all] <commit> <commit>..." msgstr "git merge-base [-a | --all] <comissió> <comissió>..." +#: builtin/merge-base.c msgid "git merge-base [-a | --all] --octopus <commit>..." msgstr "git merge-base [-a | --all] --octopus <comissió>..." +#: builtin/merge-base.c msgid "git merge-base --is-ancestor <commit> <commit>" msgstr "git merge-base --is-ancestor <comissió> <comissió>" +#: builtin/merge-base.c msgid "git merge-base --independent <commit>..." msgstr "git merge-base --independent <comissió>..." +#: builtin/merge-base.c msgid "git merge-base --fork-point <ref> [<commit>]" msgstr "git merge-base --fork-point <referència> [<comissió>]" +#: builtin/merge-base.c msgid "output all common ancestors" msgstr "emet tots els avantpassats comuns" +#: builtin/merge-base.c msgid "find ancestors for a single n-way merge" msgstr "troba els avantpassats per a una sola fusió d'n vies" +#: builtin/merge-base.c msgid "list revs not reachable from others" msgstr "llista les revisions no abastables d'altres" +#: builtin/merge-base.c msgid "is the first one ancestor of the other?" msgstr "és la primera un avantpassat de l'altre?" +#: builtin/merge-base.c msgid "find where <commit> forked from reflog of <ref>" msgstr "" "troba on <comissió> s'ha bifurcat del registre de referències de <referència>" +#: builtin/merge-file.c msgid "" "git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> " "<orig-file> <file2>" @@ -8134,269 +10451,342 @@ msgstr "" "git merge-file [<opcions>] [-L <nom1> [-L <original> [-L <nom2>]]] <fitxer1> " "<fitxer-original> <fitxer2>" +#: builtin/merge-file.c diff.c msgid "" "option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " "\"histogram\"" msgstr "" "l'opció diff-algorithm accepta «myers», «minimal», «patience» i «histogram»" +#: builtin/merge-file.c msgid "send results to standard output" msgstr "envia els resultats a la sortida estàndard" +#: builtin/merge-file.c msgid "use object IDs instead of filenames" msgstr "utilitza els ID dels objectes en comptes dels noms de fitxer" +#: builtin/merge-file.c msgid "use a diff3 based merge" msgstr "usa una fusió basada en diff3" +#: builtin/merge-file.c msgid "use a zealous diff3 based merge" msgstr "usa una fusió basada en zealous diff3" -msgid "for conflicts, use our version" -msgstr "en conflictes, usa la nostra versió" - -msgid "for conflicts, use their version" -msgstr "en conflictes, usa la seva versió" - -msgid "for conflicts, use a union version" -msgstr "en conflictes, usa una versió d'unió" - +#: builtin/merge-file.c diff.c msgid "<algorithm>" msgstr "<algorisme>" +#: builtin/merge-file.c diff.c msgid "choose a diff algorithm" msgstr "trieu un algorisme per al diff" +#: builtin/merge-file.c msgid "for conflicts, use this marker size" msgstr "en conflictes, usa aquesta mida de marcador" +#: builtin/merge-file.c msgid "do not warn about conflicts" msgstr "no avisis de conflictes" +#: builtin/merge-file.c msgid "set labels for file1/orig-file/file2" msgstr "estableix les etiquetes per a fitxer1/fitxer-original/fitxer2" +#: builtin/merge-file.c #, c-format msgid "object '%s' does not exist" msgstr "l'objecte «%s» no existeix" +#: builtin/merge-file.c msgid "Could not write object file" msgstr "No s'ha pogut escriure el fitxer de l'objecte" +#: builtin/merge-recursive.c #, c-format msgid "unknown option %s" msgstr "opció desconeguda %s" +#: builtin/merge-recursive.c #, c-format msgid "could not parse object '%s'" msgstr "no s'ha pogut analitzar l'objecte «%s»" +#: builtin/merge-recursive.c #, c-format msgid "cannot handle more than %d base. Ignoring %s." msgid_plural "cannot handle more than %d bases. Ignoring %s." msgstr[0] "no es pot gestionar més d'%d base. S'està ignorant %s." msgstr[1] "no es poden gestionar més de %d bases. S'està ignorant %s." +#: builtin/merge-recursive.c msgid "not handling anything other than two heads merge." msgstr "no s'està gestionant res a part de la fusió de dos caps." +#: builtin/merge-recursive.c #, c-format msgid "could not resolve ref '%s'" msgstr "no s'ha pogut resoldre la referència «%s»" +#: builtin/merge-recursive.c #, c-format msgid "Merging %s with %s\n" msgstr "S'està fusionant %s amb %s\n" +#: builtin/merge-tree.c +#, c-format +msgid "could not parse as tree '%s'" +msgstr "no s'ha pogut analitzar com a arbre «%s»" + +#: builtin/merge-tree.c builtin/merge.c msgid "not something we can merge" msgstr "no és quelcom que puguem fusionar" +#: builtin/merge-tree.c builtin/merge.c msgid "refusing to merge unrelated histories" msgstr "s'està refusant fusionar històries no relacionades" +#: builtin/merge-tree.c msgid "failure to merge" msgstr "s'ha produït un error en fusionar" +#: builtin/merge-tree.c msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>" -msgstr "git merge-tree [--write-tree] [<opcions>] <branch1> <branch2>" +msgstr "git merge-tree [--write-tree] [<opcions>] <branca1> <branca2>" +#: builtin/merge-tree.c msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>" -msgstr "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>" +msgstr "git merge-tree [--trivial-merge] <base-tree> <branca1> <branca2>" +#: builtin/merge-tree.c msgid "do a real merge instead of a trivial merge" msgstr "fes una fusió real en lloc d'una fusió trivial" +#: builtin/merge-tree.c msgid "do a trivial merge only" msgstr "fes només una fusió trivial" +#: builtin/merge-tree.c msgid "also show informational/conflict messages" msgstr "també mostra missatges informatius i de conflictes" +#: builtin/merge-tree.c msgid "list filenames without modes/oids/stages" msgstr "llista els noms de fitxer sense modes/oids/stages" +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c msgid "allow merging unrelated histories" msgstr "permet fusionar històries no relacionades" +#: builtin/merge-tree.c msgid "perform multiple merges, one per line of input" msgstr "realitza múltiples fusions, una per línia d'entrada" +#: builtin/merge-tree.c msgid "specify a merge-base for the merge" msgstr "cal especificar una referència base per a la fusió" +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c msgid "option=value" msgstr "opció=valor" +#: builtin/merge-tree.c builtin/merge.c builtin/pull.c msgid "option for selected merge strategy" msgstr "opció per a l'estratègia de fusió seleccionada" +#: builtin/merge-tree.c msgid "--trivial-merge is incompatible with all other options" msgstr "--trivial-merge és incompatible amb totes les altres opcions" +#: builtin/merge-tree.c builtin/merge.c #, c-format msgid "unknown strategy option: -X%s" msgstr "opció d'estratègia desconeguda: -X%s" +#: builtin/merge-tree.c builtin/notes.c #, c-format msgid "malformed input line: '%s'." msgstr "línia d'entrada mal formada: «%s»." +#: builtin/merge-tree.c #, c-format msgid "merging cannot continue; got unclean result of %d" msgstr "la fusió no pot continuar; s'ha obtingut un resultat no net de %d" +#: builtin/merge.c msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<opcions>] [<comissió>...]" +#: builtin/merge.c msgid "switch `m' requires a value" msgstr "l'opció «m» requereix un valor" +#: builtin/merge.c #, c-format msgid "option `%s' requires a value" msgstr "l'opció «%s» requereix un valor" +#: builtin/merge.c #, c-format msgid "Could not find merge strategy '%s'.\n" msgstr "No s'ha pogut trobar l'estratègia de fusió «%s».\n" +#: builtin/merge.c #, c-format msgid "Available strategies are:" msgstr "Les estratègies disponibles són:" +#: builtin/merge.c #, c-format msgid "Available custom strategies are:" msgstr "Les estratègies personalitzades disponibles són:" +#: builtin/merge.c builtin/pull.c msgid "do not show a diffstat at the end of the merge" msgstr "no mostris les estadístiques de diferència al final de la fusió" +#: builtin/merge.c builtin/pull.c msgid "show a diffstat at the end of the merge" msgstr "mostra les estadístiques de diferència al final de la fusió" +#: builtin/merge.c builtin/pull.c msgid "(synonym to --stat)" msgstr "(sinònim de --stat)" +#: builtin/merge.c builtin/pull.c msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "afegeix (com a màxim <n>) entrades del registre curt al missatge de comissió " "de fusió" +#: builtin/merge.c builtin/pull.c msgid "create a single commit instead of doing a merge" msgstr "crea una única comissió en lloc de fusionar" +#: builtin/merge.c builtin/pull.c msgid "perform a commit if the merge succeeds (default)" msgstr "realitza una comissió si la fusió té èxit (per defecte)" +#: builtin/merge.c builtin/pull.c msgid "edit message before committing" msgstr "edita el missatge abans de cometre" +#: builtin/merge.c msgid "allow fast-forward (default)" msgstr "permet l'avanç ràpid (per defecte)" +#: builtin/merge.c builtin/pull.c msgid "abort if fast-forward is not possible" msgstr "avorta si l'avanç ràpid no és possible" +#: builtin/merge.c builtin/pull.c msgid "verify that the named commit has a valid GPG signature" msgstr "verifica que la comissió anomenada tingui una signatura GPG vàlida" +#: builtin/merge.c builtin/notes.c builtin/pull.c builtin/rebase.c +#: builtin/revert.c msgid "strategy" msgstr "estratègia" +#: builtin/merge.c builtin/pull.c msgid "merge strategy to use" msgstr "estratègia de fusió a usar" +#: builtin/merge.c 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)" +#: builtin/merge.c msgid "use <name> instead of the real target" msgstr "usa <nom> en lloc de destí real" +#: builtin/merge.c msgid "abort the current in-progress merge" msgstr "avorta la fusió en curs actual" +#: builtin/merge.c msgid "--abort but leave index and working tree alone" msgstr "--abort però deixa l'índex i l'arbre de treball intactes" +#: builtin/merge.c msgid "continue the current in-progress merge" msgstr "continua la fusió actual en curs" +#: builtin/merge.c msgid "bypass pre-merge-commit and commit-msg hooks" msgstr "evita els lligams pre-merge-commit i commit-msg" +#: builtin/merge.c msgid "could not run stash." msgstr "no s'ha pogut executar «stash»." +#: builtin/merge.c msgid "stash failed" msgstr "l'«stash» ha fallat" +#: builtin/merge.c #, c-format msgid "not a valid object: %s" msgstr "no és un objecte vàlid: %s" +#: builtin/merge.c msgid "read-tree failed" msgstr "read-tree ha fallat" +#: builtin/merge.c msgid "Already up to date. (nothing to squash)" msgstr "Ja està actualitzat. (res a fer «squash»)" +#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c msgid "Already up to date." msgstr "Ja està al dia." +#: builtin/merge.c #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Comissió «squash» -- no s'està actualitzant HEAD\n" +#: builtin/merge.c #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "Cap missatge de fusió -- no s'està actualitzant HEAD\n" +#: builtin/merge.c #, c-format msgid "'%s' does not point to a commit" msgstr "«%s» no assenyala una comissió" +#: builtin/merge.c #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Cadena branch.%s.mergeoptions incorrecta: %s" +#: builtin/merge.c merge-recursive.c msgid "Unable to write index." msgstr "No s'ha pogut escriure l'índex." +#: builtin/merge.c msgid "Not handling anything other than two heads merge." msgstr "No s'està gestionant res a part de la fusió de dos caps." +#: builtin/merge.c builtin/sparse-checkout.c #, c-format msgid "unable to write %s" msgstr "no s'ha pogut escriure %s" +#: builtin/merge.c #, c-format msgid "Could not read from '%s'" msgstr "No s'ha pogut llegir de «%s»" +#: builtin/merge.c #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "No s'està cometent la fusió; useu «git commit» per a completar la fusió.\n" +#: builtin/merge.c msgid "" "Please enter a commit message to explain why this merge is necessary,\n" "especially if it merges an updated upstream into a topic branch.\n" @@ -8406,70 +10796,89 @@ msgstr "" "necessària, especialment si es fusiona una branca amb funcionalitat nova.\n" "\n" +#: builtin/merge.c msgid "An empty message aborts the commit.\n" msgstr "Un missatge buit interromp la comissió.\n" +# will be ignored → es descartaran? +#: builtin/merge.c #, c-format msgid "" -"Lines starting with '%c' will be ignored, and an empty message aborts\n" +"Lines starting with '%s' will be ignored, and an empty message aborts\n" "the commit.\n" msgstr "" -"Les línies que comencen amb «%c» seran ignorades i un missatge buit " -"interromp la comissió.\n" +"Les línies que comencin amb «%s» s'ignoraran, i un missatge buit\n" +"avorta la comissió.\n" +#: builtin/merge.c msgid "Empty commit message." msgstr "El missatge de comissió és buit." +#: builtin/merge.c #, c-format msgid "Wonderful.\n" msgstr "Meravellós.\n" +#: builtin/merge.c #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "La fusió automàtica ha fallat; arregleu els conflictes i després cometeu el " "resultat.\n" +#: builtin/merge.c msgid "No current branch." msgstr "No hi ha cap branca actual." +#: builtin/merge.c msgid "No remote for the current branch." msgstr "No hi ha cap remot per a la branca actual." +#: builtin/merge.c msgid "No default upstream defined for the current branch." msgstr "No hi ha cap font per defecte definida per a la branca actual." +#: builtin/merge.c #, c-format msgid "No remote-tracking branch for %s from %s" msgstr "No hi ha cap branca amb seguiment remot per a %s de %s" +#: builtin/merge.c #, c-format msgid "Bad value '%s' in environment '%s'" msgstr "Valor incorrecte «%s» en l'entorn «%s»" +#: builtin/merge.c editor.c read-cache.c wrapper.c #, c-format msgid "could not close '%s'" msgstr "no s'ha pogut tancar «%s»" +#: builtin/merge.c #, c-format msgid "not something we can merge in %s: %s" msgstr "no és quelcom que puguem fusionar en %s: %s" +#: builtin/merge.c msgid "--abort expects no arguments" msgstr "--abort no espera cap argument" +#: builtin/merge.c msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "No hi ha fusió a avortar (manca MERGE_HEAD)." +#: builtin/merge.c msgid "--quit expects no arguments" msgstr "--quit no espera cap argument" +#: builtin/merge.c msgid "--continue expects no arguments" msgstr "--continue no espera cap argument" +#: builtin/merge.c msgid "There is no merge in progress (MERGE_HEAD missing)." msgstr "No hi ha cap fusió en curs (manca MERGE_HEAD)." +#: builtin/merge.c msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you merge." @@ -8477,6 +10886,7 @@ msgstr "" "No heu conclòs la vostra fusió (MERGE_HEAD existeix).\n" "Cometeu els vostres canvis abans de fusionar." +#: builtin/merge.c msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." @@ -8484,31 +10894,39 @@ msgstr "" "No heu conclòs el vostre «cherry pick» (CHERRY_PICK_HEAD existeix).\n" "Cometeu els vostres canvis abans de fusionar." +#: builtin/merge.c msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "No heu conclòs el vostre «cherry pick» (CHERRY_PICK_HEAD existeix)." +#: builtin/merge.c msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" "No hi ha una comissió especificada i merge.defaultToUpstream no està " "establert." +#: builtin/merge.c msgid "Squash commit into empty head not supported yet" msgstr "Una comissió «squash» a una HEAD buida encara no es permet" +#: builtin/merge.c msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "Una comissió no d'avanç ràpid no té sentit a una HEAD buida" +#: builtin/merge.c #, c-format msgid "%s - not something we can merge" msgstr "%s - no és una cosa que puguem fusionar" +#: builtin/merge.c msgid "Can merge only exactly one commit into empty head" msgstr "Es pot fusionar només una comissió a una HEAD buida" +#: builtin/merge.c #, c-format msgid "Updating %s..%s\n" msgstr "S'estan actualitzant %s..%s\n" +#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -8517,126 +10935,159 @@ msgstr "" "Els canvis locals als fitxers següents se sobreescriuran per la fusió:\n" " %s" +#: builtin/merge.c #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "S'està intentant una fusió molt trivial en l'índex...\n" +#: builtin/merge.c #, c-format msgid "Nope.\n" msgstr "No.\n" +#: builtin/merge.c #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "S'està rebobinant l'arbre a la pristina...\n" +#: builtin/merge.c #, c-format msgid "Trying merge strategy %s...\n" msgstr "S'està intentant l'estratègia de fusió %s...\n" +#: builtin/merge.c #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Cap estratègia de fusió ha gestionat la fusió.\n" +#: builtin/merge.c #, c-format msgid "Merge with strategy %s failed.\n" msgstr "L'estratègia de fusió %s ha fallat.\n" +#: builtin/merge.c #, c-format msgid "Using the %s strategy to prepare resolving by hand.\n" msgstr "S'està usant l'estratègia %s per a preparar la resolució a mà.\n" +#: builtin/merge.c #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" "La fusió automàtica ha sortit bé; s'ha aturat abans de cometre com s'havia " "demanat\n" +#: builtin/merge.c #, c-format msgid "When finished, apply stashed changes with `git stash pop`\n" msgstr "Quan acabi, aplica els canvis «stashed» amb «git stash pop»\n" +#: builtin/mktag.c #, c-format msgid "warning: tag input does not pass fsck: %s" msgstr "avís: l'entrada d'etiqueta no passa fsck: %s" +#: builtin/mktag.c #, c-format msgid "error: tag input does not pass fsck: %s" msgstr "error: l'entrada d'etiqueta no passa fsck: %s" +#: builtin/mktag.c #, c-format msgid "%d (FSCK_IGNORE?) should never trigger this callback" msgstr "%d (FSCK_IGNORE?) no hauria d'activar mai aquesta crida de retorn" +#: builtin/mktag.c #, c-format msgid "could not read tagged object '%s'" msgstr "no s'ha pogut llegir l'objecte etiquetat «%s»" +#: builtin/mktag.c #, c-format msgid "object '%s' tagged as '%s', but is a '%s' type" msgstr "l'objecte «%s» s'ha etiquetat com a «%s», però és del tipus «%s»" -msgid "could not read from stdin" -msgstr "no s'ha pogut llegir des de stdin" - +#: builtin/mktag.c msgid "tag on stdin did not pass our strict fsck check" msgstr "l'etiqueta a stdin no ha passat la comprovació estricta del fsck" +#: builtin/mktag.c msgid "tag on stdin did not refer to a valid object" msgstr "l'etiqueta a stdin no apunta a un objecte vàlid" +#: builtin/mktag.c builtin/tag.c msgid "unable to write tag file" msgstr "no s'ha pogut escriure el fitxer d'etiqueta" +#: builtin/mktree.c msgid "input is NUL terminated" msgstr "l'entrada és acabada amb NUL" +#: builtin/mktree.c builtin/write-tree.c msgid "allow missing objects" msgstr "permet els objectes absents" +#: builtin/mktree.c msgid "allow creation of more than one tree" msgstr "permet la creació de més d'un arbre" +#: builtin/multi-pack-index.c msgid "" "git multi-pack-index [<options>] write [--preferred-pack=<pack>][--refs-" "snapshot=<path>]" msgstr "" -"git multi-pack-index [<opcions>] write [--preferred-pack=<pack>][--refs-" +"git multi-pack-index [<opcions>] write [--preferred-pack=<paquet>][--refs-" "snapshot=<camí>]" +#: builtin/multi-pack-index.c msgid "git multi-pack-index [<options>] verify" msgstr "git multi-pack-index [<opcions>] verify" +#: builtin/multi-pack-index.c msgid "git multi-pack-index [<options>] expire" msgstr "git multi-pack-index [<opcions>] expire" +#: builtin/multi-pack-index.c msgid "git multi-pack-index [<options>] repack [--batch-size=<size>]" msgstr "git multi-pack-index [<opcions>] repack [--batch-size=<mida>]" +#: builtin/multi-pack-index.c msgid "directory" msgstr "directori" +#: builtin/multi-pack-index.c msgid "object directory containing set of packfile and pack-index pairs" msgstr "" "directori de l'objecte que conté el conjunt de parells de fitxers i índexs " "de paquets" +#: builtin/multi-pack-index.c msgid "preferred-pack" msgstr "paquet preferit" +#: builtin/multi-pack-index.c msgid "pack for reuse when computing a multi-pack bitmap" msgstr "" "empaqueta per a reutilitzar quan es calcula un mapa de bits multipaquet" +#: builtin/multi-pack-index.c msgid "write multi-pack bitmap" msgstr "escriu un map de bits multipaquet" +#: builtin/multi-pack-index.c +msgid "write a new incremental MIDX" +msgstr "escriu un nou MIDX incremental" + +#: builtin/multi-pack-index.c msgid "write multi-pack index containing only given indexes" msgstr "escriu un índex multipaquet que contingui només els índexs donats" +#: builtin/multi-pack-index.c msgid "refs snapshot for selecting bitmap commits" msgstr "" "instantània de referències per a seleccionar les comissions de mapa de bits" +#: builtin/multi-pack-index.c msgid "" "during repack, collect pack-files of smaller size into a batch that is " "larger than this size" @@ -8644,245 +11095,309 @@ msgstr "" "durant el reempaquetament, recull els fitxers de paquets de mida més petita " "en un lot que és més gran que aquesta mida" +#: builtin/mv.c msgid "git mv [<options>] <source>... <destination>" msgstr "git mv [<opcions>] <origen>... <destí>" +#: builtin/mv.c #, c-format msgid "Directory %s is in index and no submodule?" msgstr "El directori %s és en l'índex i no hi ha cap submòdul?" +#: builtin/mv.c msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" "Feu «stage» dels vostres canvis a .gitmodules o feu «stash» dels mateixos " "per a procedir" +#: builtin/mv.c #, c-format msgid "%.*s is in index" msgstr "%.*s és en l'índex" +#: builtin/mv.c msgid "force move/rename even if target exists" msgstr "força el moviment / canvi de nom encara que el destí existeixi" +#: builtin/mv.c msgid "skip move/rename errors" msgstr "omet els errors de moviment / canvi de nom" +#: builtin/mv.c #, c-format msgid "destination '%s' is not a directory" msgstr "el destí «%s» no és un directori" +#: builtin/mv.c #, c-format msgid "Checking rename of '%s' to '%s'\n" msgstr "S'està comprovant el canvi de nom de «%s» a «%s»\n" +#: builtin/mv.c msgid "bad source" msgstr "origen incorrecte" +#: builtin/mv.c msgid "destination exists" msgstr "el destí existeix" +#: builtin/mv.c msgid "can not move directory into itself" msgstr "no es pot moure un directori a dins d'ell mateix" +#: builtin/mv.c msgid "destination already exists" msgstr "la destinació ja existeix" +#: builtin/mv.c msgid "source directory is empty" msgstr "el directori d'origen està buit" +#: builtin/mv.c msgid "not under version control" msgstr "no està sota control de versions" +#: builtin/mv.c msgid "conflicted" msgstr "en conflicte" +#: builtin/mv.c #, c-format msgid "overwriting '%s'" msgstr "s'està sobreescrivint «%s»" +#: builtin/mv.c msgid "Cannot overwrite" msgstr "No es pot sobreescriure" +#: builtin/mv.c msgid "multiple sources for the same target" msgstr "múltiples orígens per al mateix destí" +#: builtin/mv.c msgid "destination directory does not exist" msgstr "el directori destí no existeix" +#: builtin/mv.c msgid "destination exists in the index" msgstr "el destí existeix a l'índex" +#: builtin/mv.c #, c-format msgid "%s, source=%s, destination=%s" msgstr "%s, origen=%s, destí=%s" +#: builtin/mv.c #, c-format msgid "Renaming %s to %s\n" msgstr "S'està canviant el nom de %s a %s\n" +#: builtin/mv.c builtin/remote.c #, c-format msgid "renaming '%s' failed" msgstr "el canvi del nom de «%s» ha fallat" +#: builtin/name-rev.c msgid "git name-rev [<options>] <commit>..." msgstr "git name-rev [<opcions>] <comissió>..." +#: builtin/name-rev.c msgid "git name-rev [<options>] --all" msgstr "git name-rev [<opcions>] --all" +#: builtin/name-rev.c msgid "git name-rev [<options>] --annotate-stdin" msgstr "git name-rev [<opcions>] --annotate-stdin" +#: builtin/name-rev.c msgid "print only ref-based names (no object names)" msgstr "imprimeix només els noms basats en referències (no els noms d'objecte)" +#: builtin/name-rev.c msgid "only use tags to name the commits" msgstr "només usa les etiquetes per a anomenar les comissions" +#: builtin/name-rev.c msgid "only use refs matching <pattern>" msgstr "només usa les referències que coincideixin amb <patró>" +#: builtin/name-rev.c msgid "ignore refs matching <pattern>" msgstr "ignora les referències que coincideixin amb <patró>" +#: builtin/name-rev.c msgid "list all commits reachable from all refs" msgstr "llista totes les comissions abastables de totes les referències" +#: builtin/name-rev.c msgid "deprecated: use --annotate-stdin instead" msgstr "obsolet: useu en comptes --annotate-stdin" +#: builtin/name-rev.c msgid "annotate text from stdin" msgstr "anota el text de stdin" +#: builtin/name-rev.c msgid "allow to print `undefined` names (default)" msgstr "permet imprimir els noms «undefined» (per defecte)" +#: builtin/name-rev.c msgid "dereference tags in the input (internal use)" msgstr "desreferencia les etiquetes en l'entrada (ús intern)" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] [list [<object>]]" msgstr "git notes [--ref <referència-de-notes>] [llista [<objecte>]]" +#: builtin/notes.c msgid "" "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 <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" -"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <fitxer> | (-" +"c | -C) <object>] [<object>]" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" -"git notes [--ref <referència-de-notes>] copy [-f] <d'objecte> <a-objecte>" +"git notes [--ref <referència-de-notes>] copy [-f] <objecte-de> <objecte-a>" +#: builtin/notes.c msgid "" "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 <notes-ref>] append [--allow-empty] [--[no-]separator|--" -"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <fitxer> | (-" +"c | -C) <objecte>] [<objecte>]" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "" "git notes [--ref <referència-de-notes>] edit [--allow-empty] [<objecte>]" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] show [<object>]" msgstr "git notes [--ref <referència-de-notes>] show [<objecte>]" +#: builtin/notes.c msgid "" "git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>" msgstr "" "git notes [--ref <referència-de-notes>] merge [-v | -q] [-s <estratègia>] " "<referència-de-notes>" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] remove [<object>...]" msgstr "git notes [--ref <referència-de-notes>] remove [<objecte>...]" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] prune [-n] [-v]" msgstr "git notes [--ref <referència-de-notes>] prune [-n] [-v]" +#: builtin/notes.c msgid "git notes [--ref <notes-ref>] get-ref" msgstr "git notes [--ref <referència-de-notes>] get-ref" +#: builtin/notes.c msgid "git notes [list [<object>]]" msgstr "git notes [llista [<objecte>]]" +#: builtin/notes.c msgid "git notes add [<options>] [<object>]" msgstr "git notes add [<opcions>] [<objecte>]" +#: builtin/notes.c msgid "git notes copy [<options>] <from-object> <to-object>" -msgstr "git notes copy [<opcions>] <d'objecte> <a-objecte>" +msgstr "git notes copy [<opcions>] <objecte-de> <objecte-a>" +#: builtin/notes.c msgid "git notes copy --stdin [<from-object> <to-object>]..." -msgstr "git notes copy --stdin [<d'objecte> <a-objecte>]..." +msgstr "git notes copy --stdin [<objecte-de> <objecte-a>]..." +#: builtin/notes.c msgid "git notes append [<options>] [<object>]" msgstr "git notes append [<opcions>] [<objecte>]" +#: builtin/notes.c msgid "git notes edit [<object>]" msgstr "git notes edit [<objecte>]" +#: builtin/notes.c msgid "git notes show [<object>]" msgstr "git notes show [<objecte>]" +#: builtin/notes.c msgid "git notes merge [<options>] <notes-ref>" msgstr "git notes merge [<opcions>] <referència-de-notes>" +#: builtin/notes.c msgid "git notes merge --commit [<options>]" msgstr "git notes merge --commit [<opcions>]" +#: builtin/notes.c msgid "git notes merge --abort [<options>]" msgstr "git notes merge --abort [<opcions>]" +#: builtin/notes.c msgid "git notes remove [<object>]" msgstr "git notes remove [<objecte>]" +#: builtin/notes.c msgid "git notes prune [<options>]" msgstr "git notes prune [<opcions>]" +#: builtin/notes.c msgid "Write/edit the notes for the following object:" msgstr "Escriviu/editeu les notes per l'objecte següent:" -#, c-format -msgid "unable to start 'show' for object '%s'" -msgstr "no s'ha pogut iniciar «show» per a l'objecte «%s»" - +#: builtin/notes.c msgid "could not read 'show' output" msgstr "no s'ha pogut llegir la sortida de «show»" +#: builtin/notes.c #, c-format msgid "failed to finish 'show' for object '%s'" msgstr "s'ha produït un error en finalitzar «show» per a l'objecte «%s»" +#: builtin/notes.c msgid "please supply the note contents using either -m or -F option" msgstr "" "especifiqueu el contingut de la nota fent servir l'opció -m o l'opció -F" +#: builtin/notes.c msgid "unable to write note object" msgstr "no s'ha pogut escriure l'objecte de nota" +#: builtin/notes.c #, c-format msgid "the note contents have been left in %s" msgstr "s'han deixat els continguts de la nota en %s" +#: builtin/notes.c builtin/tag.c #, c-format msgid "could not open or read '%s'" msgstr "no s'ha pogut obrir o llegir «%s»" +#: builtin/notes.c #, c-format msgid "failed to resolve '%s' as a valid ref." msgstr "s'ha produït un error en resoldre «%s» com a referència vàlida." +#: builtin/notes.c #, c-format msgid "failed to read object '%s'." msgstr "s'ha produït un error en llegir l'objecte «%s»." +#: builtin/notes.c #, c-format msgid "cannot read note data from non-blob object '%s'." msgstr "no es poden llegir les dades de node de l'objecte no de blob «%s»." +#: builtin/notes.c #, c-format msgid "failed to copy notes from '%s' to '%s'" msgstr "s'ha produït un error en copiar les notes de «%s» a «%s»" @@ -8890,41 +11405,53 @@ msgstr "s'ha produït un error en copiar les notes de «%s» a «%s»" #. TRANSLATORS: the first %s will be replaced by a git #. notes command: 'add', 'merge', 'remove', etc. #. +#: builtin/notes.c #, c-format msgid "refusing to %s notes in %s (outside of refs/notes/)" msgstr "s'està refusant %s les notes en %s (fora de refs/notes/)" +#: builtin/notes.c #, c-format msgid "no note found for object %s." msgstr "no s'ha trobat cap nota per a l'objecte %s." +#: builtin/notes.c msgid "note contents as a string" msgstr "anota els continguts com a cadena" +#: builtin/notes.c msgid "note contents in a file" msgstr "anota els continguts en un fitxer" +#: builtin/notes.c msgid "reuse and edit specified note object" msgstr "reusa i edita l'objecte de nota especificat" +#: builtin/notes.c msgid "reuse specified note object" msgstr "reusa l'objecte de nota especificat" +#: builtin/notes.c msgid "allow storing empty note" msgstr "permet l'emmagatzematge d'una nota buida" +#: builtin/notes.c msgid "replace existing notes" msgstr "reemplaça les notes existents" +#: builtin/notes.c msgid "<paragraph-break>" msgstr "<paragraph-break>" +#: builtin/notes.c msgid "insert <paragraph-break> between paragraphs" msgstr "insereix <paragraph-break> entre paràgrafs" +#: builtin/notes.c msgid "remove unnecessary whitespace" msgstr "elimina l'espai en blanc innecessari" +#: builtin/notes.c #, c-format msgid "" "Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -8933,24 +11460,30 @@ msgstr "" "No es poden afegir les notes. S'han trobat notes existents de l'objecte %s. " "Useu «-f» per a sobreescriure les notes existents" +#: builtin/notes.c #, c-format msgid "Overwriting existing notes for object %s\n" msgstr "S'estan sobreescrivint les notes existents de l'objecte %s\n" +#: builtin/notes.c #, c-format msgid "Removing note for object %s\n" msgstr "S'està eliminant la nota de l'objecte %s\n" +#: builtin/notes.c msgid "read objects from stdin" msgstr "llegeix els objectes des de stdin" +#: builtin/notes.c msgid "load rewriting config for <command> (implies --stdin)" msgstr "" "carrega la configuració de reescriptura per a <ordre> (implica --stdin)" +#: builtin/notes.c msgid "too few arguments" msgstr "massa pocs arguments" +#: builtin/notes.c #, c-format msgid "" "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -8959,10 +11492,12 @@ msgstr "" "No es poden copiar les notes. S'han trobat notes existents de l'objecte %s. " "Useu «-f» per a sobreescriure les notes existents" +#: builtin/notes.c #, c-format msgid "missing notes on source object %s. Cannot copy." msgstr "manquen notes a l'objecte font %s. No es pot copiar." +#: builtin/notes.c #, c-format msgid "" "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" @@ -8971,41 +11506,53 @@ msgstr "" "Es desaconsellen les opcions -m/-F/-c/-C en favor de la subordre «edit».\n" "Useu «git notes add -f -m/-F/-c/-C» en lloc d'això.\n" +#: builtin/notes.c msgid "failed to delete ref NOTES_MERGE_PARTIAL" msgstr "s'ha produït un error en suprimir la referència NOTES_MERGE_PARTIAL" +#: builtin/notes.c msgid "failed to delete ref NOTES_MERGE_REF" msgstr "s'ha produït un error en suprimir la referència NOTES_MERGE_REF" +#: builtin/notes.c msgid "failed to remove 'git notes merge' worktree" msgstr "" "s'ha produït un error en eliminar l'arbre de treball de «git notes merge»" +#: builtin/notes.c msgid "failed to read ref NOTES_MERGE_PARTIAL" msgstr "s'ha produït un error en llegir la referència NOTES_MERGE_PARTIAL" +#: builtin/notes.c msgid "could not find commit from NOTES_MERGE_PARTIAL." msgstr "no s'ha pogut trobar cap comissió de NOTES_MERGE_PARTIAL." +#: builtin/notes.c msgid "could not parse commit from NOTES_MERGE_PARTIAL." msgstr "no s'ha pogut analitzar la comissió de NOTES_MERGE_PARTIAL." +#: builtin/notes.c msgid "failed to resolve NOTES_MERGE_REF" msgstr "s'ha produït un error en resoldre NOTES_MERGE_REF" +#: builtin/notes.c msgid "failed to finalize notes merge" msgstr "s'ha produït un error en finalitzar la fusió de notes" +#: builtin/notes.c #, c-format msgid "unknown notes merge strategy %s" msgstr "estratègia de fusió de notes desconeguda %s" +#: builtin/notes.c msgid "General options" msgstr "Opcions generals" +#: builtin/notes.c msgid "Merge options" msgstr "Opcions de fusió" +#: builtin/notes.c msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" @@ -9013,38 +11560,48 @@ msgstr "" "resol els conflictes de nota usant l'estratègia donada (manual/ours/theirs/" "union/cat_sort_uniq)" +#: builtin/notes.c msgid "Committing unmerged notes" msgstr "S'estan cometent les notes sense fusionar" +#: builtin/notes.c msgid "finalize notes merge by committing unmerged notes" msgstr "finalitza la fusió de notes cometent les notes sense fusionar" +#: builtin/notes.c msgid "Aborting notes merge resolution" msgstr "S'està avortant la resolució de fusió de notes" +#: builtin/notes.c msgid "abort notes merge" msgstr "avorta la fusió de notes" +#: builtin/notes.c msgid "cannot mix --commit, --abort or -s/--strategy" msgstr "no es pot combinar --commit, --abort i -s/--strategy" +#: builtin/notes.c msgid "must specify a notes ref to merge" msgstr "cal especificar una referència de notes a fusionar" +#: builtin/notes.c #, c-format msgid "unknown -s/--strategy: %s" msgstr "-s/--strategy desconeguda: %s" +#: builtin/notes.c #, c-format msgid "a notes merge into %s is already in-progress at %s" msgstr "una fusió de notes a %s ja està en curs a %s" +#: builtin/notes.c #, c-format msgid "failed to store link to current notes ref (%s)" msgstr "" "s'ha produït un error en emmagatzemar l'enllaç a la referència de notes " "actual (%s)" +#: builtin/notes.c #, c-format msgid "" "Automatic notes merge failed. Fix conflicts in %s and commit the result with " @@ -9055,44 +11612,56 @@ msgstr "" "cometeu el resultat amb «git notes merge --commit», o avorteu la fusió amb " "«git notes merge --abort».\n" +#: builtin/notes.c builtin/tag.c #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "S'ha produït un error en resoldre «%s» com a referència vàlida." +#: builtin/notes.c #, c-format msgid "Object %s has no note\n" msgstr "L'objecte %s no té cap nota\n" +#: builtin/notes.c msgid "attempt to remove non-existent note is not an error" msgstr "l'intent d'eliminar una nota no existent no és un error" +#: builtin/notes.c msgid "read object names from the standard input" msgstr "llegeix els noms d'objecte des de l'entrada estàndard" +#: builtin/notes.c builtin/prune.c builtin/worktree.c msgid "do not remove, show only" msgstr "no eliminis, només mostra" +#: builtin/notes.c msgid "report pruned notes" msgstr "informa de notes podades" +#: builtin/notes.c msgid "notes-ref" msgstr "referència de notes" +#: builtin/notes.c msgid "use notes from <notes-ref>" msgstr "usa les notes de <referència-de-notes>" +#: builtin/notes.c builtin/remote.c parse-options.c #, c-format msgid "unknown subcommand: `%s'" msgstr "subordre desconeguda: «%s»" +#: builtin/pack-objects.c msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" msgstr "git pack-objects --stdout [<opcions>] [< <ref-list> | < <object-list>]" +#: builtin/pack-objects.c msgid "" "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" msgstr "" "git pack-objects [<opcions>] <base-name> [< <ref-list> | < <object-list>]" +#: builtin/pack-objects.c #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9101,108 +11670,135 @@ msgstr "" "write_reuse_object: no s'ha pogut localitzar %s, s'esperava a la posició " "%<PRIuMAX> al paquet %s" +#: builtin/pack-objects.c #, c-format msgid "bad packed object CRC for %s" msgstr "CRC de l'objecte empaquetat malmès per a %s" +#: builtin/pack-objects.c #, c-format msgid "corrupt packed object for %s" msgstr "objecte empaquetat corrupte per a %s" +#: builtin/pack-objects.c #, c-format msgid "recursive delta detected for object %s" msgstr "diferència recursiva detectada per a l'objecte %s" +#: builtin/pack-objects.c #, c-format msgid "ordered %u objects, expected %<PRIu32>" msgstr "ordenats %u objectes, s'esperaven %<PRIu32>" +#: builtin/pack-objects.c #, c-format msgid "expected object at offset %<PRIuMAX> in pack %s" msgstr "objecte esperat a la posició %<PRIuMAX> al paquet %s" +#: builtin/pack-objects.c msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" msgstr "" "s'està inhabilitant l'escriptura de mapes de bits, es divideixen els paquets " "a causa de pack.packSizeLimit" +#: builtin/pack-objects.c msgid "Writing objects" msgstr "S'estan escrivint els objectes" +#: builtin/pack-objects.c builtin/update-index.c #, c-format msgid "failed to stat %s" msgstr "s'ha produït un error en fer stat a %s" +#: builtin/pack-objects.c object-file.c #, c-format msgid "failed utime() on %s" msgstr "ha fallat utime() a %s" +#: builtin/pack-objects.c msgid "failed to write bitmap index" msgstr "s'ha produït un error en escriure l'índex de mapa de bits" +#: builtin/pack-objects.c #, c-format msgid "wrote %<PRIu32> objects while expecting %<PRIu32>" msgstr "escrits %<PRIu32> objectes mentre s'esperaven %<PRIu32>" +#: builtin/pack-objects.c builtin/repack.c msgid "disabling bitmap writing, as some objects are not being packed" msgstr "" "s'està inhabilitant l'escriptura de mapes de bits, perquè alguns objectes no " "s'empaqueten" +#: builtin/pack-objects.c #, c-format msgid "delta base offset overflow in pack for %s" msgstr "desbordament del desplaçament base de diferències en paquet per a %s" +#: builtin/pack-objects.c #, c-format msgid "delta base offset out of bound for %s" msgstr "desplaçament base de diferències fora dels límits per a %s" +#: builtin/pack-objects.c msgid "Counting objects" msgstr "S'estan comptant els objectes" +#: builtin/pack-objects.c pack-bitmap.c #, c-format msgid "unable to get size of %s" msgstr "no s'ha pogut obtenir la mida de %s" +#: builtin/pack-objects.c #, c-format msgid "unable to parse object header of %s" msgstr "no s'ha pogut analitzar la capçalera de l'objecte de %s" +#: builtin/pack-objects.c #, c-format msgid "object %s cannot be read" msgstr "no es pot llegir l'objecte %s" +#: builtin/pack-objects.c #, c-format msgid "object %s inconsistent object length (%<PRIuMAX> vs %<PRIuMAX>)" msgstr "" "l'objecte %s té una longitud d'objecte inconsistent (%<PRIuMAX> vs " "%<PRIuMAX>)" +#: builtin/pack-objects.c msgid "suboptimal pack - out of memory" msgstr "paquet subòptim - sense memòria" +#: builtin/pack-objects.c #, c-format msgid "Delta compression using up to %d threads" msgstr "Compressió de diferències usant fins a %d fils" +#: builtin/pack-objects.c #, c-format msgid "unable to pack objects reachable from tag %s" msgstr "no s'han pogut empaquetar els objectes abastables des de l'etiqueta %s" +#: builtin/pack-objects.c commit-graph.c #, c-format msgid "unable to get type of object %s" msgstr "no s'ha pogut obtenir el tipus de l'objecte: %s" +#: builtin/pack-objects.c msgid "Compressing objects" msgstr "S'estan comprimint els objectes" +#: builtin/pack-objects.c msgid "inconsistency with delta count" msgstr "inconsistència amb el comptador de diferències" +#: builtin/pack-objects.c #, c-format msgid "invalid pack.allowPackReuse value: '%s'" msgstr "valor pack.allowPackReuse value no vàlid: «%s»" +#: builtin/pack-objects.c #, c-format msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" @@ -9211,6 +11807,7 @@ msgstr "" "el valor de uploadpack.blobpackfileuri ha de tenir la forma «<object-hash> " "<pack-hash> <uri>» (s'ha rebut «%s»)" +#: builtin/pack-objects.c #, c-format msgid "" "object already configured in another uploadpack.blobpackfileuri (got '%s')" @@ -9218,27 +11815,34 @@ msgstr "" "l'objecte ja està configurat en un altre uploadpack.blobpackfileuri (s'ha " "rebut «%s»)" +#: builtin/pack-objects.c #, c-format msgid "could not get type of object %s in pack %s" msgstr "no s'ha pogut obtenir el tipus de l'objecte %s al paquet %s" +#: builtin/pack-objects.c #, c-format msgid "could not find pack '%s'" msgstr "no s'ha pogut trobar el paquet «%s»" +#: builtin/pack-objects.c #, c-format msgid "packfile %s cannot be accessed" msgstr "no es pot accedir al fitxer de paquet %s" +#: builtin/pack-objects.c msgid "Enumerating cruft objects" msgstr "S'estan enumerant els objectes superflus" +#: builtin/pack-objects.c msgid "unable to add cruft objects" msgstr "no s'han pogut afegir els objectes superflus" +#: builtin/pack-objects.c msgid "Traversing cruft objects" msgstr "S'estan recorrent els objectes superflus" +#: builtin/pack-objects.c #, c-format msgid "" "expected edge object ID, got garbage:\n" @@ -9247,6 +11851,7 @@ msgstr "" "s'esperava un identificador vora de l'objecte, s'ha rebut brossa:\n" " %s" +#: builtin/pack-objects.c #, c-format msgid "" "expected object ID, got garbage:\n" @@ -9255,216 +11860,280 @@ msgstr "" "s'esperava un identificador d'objecte, s'ha rebut brossa:\n" " %s" +#: builtin/pack-objects.c reachable.c msgid "could not load cruft pack .mtimes" msgstr "no s'ha pogut carregar superflus del paquet superflu" +#: builtin/pack-objects.c msgid "cannot open pack index" msgstr "no s'ha pogut obrir l'índex del paquet" +#: builtin/pack-objects.c #, c-format msgid "loose object at %s could not be examined" msgstr "no s'ha pogut examinar l'objecte solt a %s" +#: builtin/pack-objects.c msgid "unable to force loose object" msgstr "no s'ha pogut forçar l'objecte solt" +#: builtin/pack-objects.c #, c-format msgid "not a rev '%s'" msgstr "«%s» no és una revisió" +#: builtin/pack-objects.c builtin/rev-parse.c #, c-format msgid "bad revision '%s'" msgstr "revisió incorrecta «%s»" +#: builtin/pack-objects.c msgid "unable to add recent objects" msgstr "no s'han pogut afegir els objectes recents" +#: builtin/pack-objects.c #, c-format msgid "unsupported index version %s" msgstr "versió d'índex no compatible %s" +#: builtin/pack-objects.c #, c-format msgid "bad index version '%s'" msgstr "versió d'índex incorrecta «%s»" +#: builtin/pack-objects.c msgid "show progress meter during object writing phase" msgstr "mostra l'indicador de progrés durant la fase d'escriptura d'objectes" +#: builtin/pack-objects.c msgid "similar to --all-progress when progress meter is shown" msgstr "similar a --all-progress quan l'indicador de progrés es mostra" +#: builtin/pack-objects.c msgid "<version>[,<offset>]" msgstr "<versió>[,<desplaçament>]" +#: builtin/pack-objects.c msgid "write the pack index file in the specified idx format version" msgstr "" "escriu el fitxer d'índex de paquet en la versió de format d'índex " "especificada" +#: builtin/pack-objects.c msgid "maximum size of each output pack file" msgstr "mida màxima de cada fitxer empaquetat de sortida" +#: builtin/pack-objects.c msgid "ignore borrowed objects from alternate object store" msgstr "" "ignora els objectes manllevats d'un emmagatzematge d'objectes alternatiu" +#: builtin/pack-objects.c msgid "ignore packed objects" msgstr "ignora els objectes empaquetats" +#: builtin/pack-objects.c msgid "limit pack window by objects" msgstr "limita la finestra d'empaquetament per objectes" +#: builtin/pack-objects.c msgid "limit pack window by memory in addition to object limit" msgstr "" "limita la finestra d'empaquetament per memòria a més del límit d'objectes" +#: builtin/pack-objects.c msgid "maximum length of delta chain allowed in the resulting pack" msgstr "" "longitud màxima de la cadena de diferències permesa en el paquet resultant" +#: builtin/pack-objects.c msgid "reuse existing deltas" msgstr "reusa les diferències existents" +#: builtin/pack-objects.c msgid "reuse existing objects" msgstr "reusa els objectes existents" +#: builtin/pack-objects.c msgid "use OFS_DELTA objects" msgstr "usa objectes OFS_DELTA" +#: builtin/pack-objects.c msgid "use threads when searching for best delta matches" msgstr "usa fils en cercar les millors coincidències de diferències" +#: builtin/pack-objects.c msgid "do not create an empty pack output" msgstr "no creïs una emissió de paquet buit" +#: builtin/pack-objects.c msgid "read revision arguments from standard input" msgstr "llegeix els arguments de revisió des de l'entrada estàndard" +#: builtin/pack-objects.c msgid "limit the objects to those that are not yet packed" msgstr "limita els objectes a aquells que encara no estan empaquetats" +#: builtin/pack-objects.c msgid "include objects reachable from any reference" msgstr "inclou els objectes abastables de qualsevol referència" +#: builtin/pack-objects.c msgid "include objects referred by reflog entries" msgstr "" "inclou els objectes als quals facin referència les entrades del registre de " "referències" +#: builtin/pack-objects.c msgid "include objects referred to by the index" msgstr "inclou els objectes als quals faci referència l'índex" +#: builtin/pack-objects.c msgid "read packs from stdin" msgstr "llegeix els paquets des de stdin" +#: builtin/pack-objects.c msgid "output pack to stdout" msgstr "emet el paquet a stdout" +#: builtin/pack-objects.c msgid "include tag objects that refer to objects to be packed" msgstr "" "inclou els objectes d'etiqueta que facin referència als objectes a empaquetar" +#: builtin/pack-objects.c msgid "keep unreachable objects" msgstr "retén els objectes inabastables" +#: builtin/pack-objects.c msgid "pack loose unreachable objects" msgstr "empaqueta els objectes inabastables solts" +#: builtin/pack-objects.c msgid "unpack unreachable objects newer than <time>" msgstr "desempaqueta els objectes inabastables més nous que <data>" +#: builtin/pack-objects.c msgid "create a cruft pack" msgstr "crea un paquet superflu" +#: builtin/pack-objects.c msgid "expire cruft objects older than <time>" msgstr "fes caducar els objectes superflus més antics que <data>" +#: builtin/pack-objects.c msgid "use the sparse reachability algorithm" msgstr "utilitza l'algorisme d'accessibilitat dispers" +#: builtin/pack-objects.c msgid "create thin packs" msgstr "crea paquets prims" +#: builtin/pack-objects.c msgid "create packs suitable for shallow fetches" msgstr "crea paquets adequats per a les obtencions superficials" +#: builtin/pack-objects.c msgid "ignore packs that have companion .keep file" msgstr "ignora els paquets que tinguin un fitxer .keep corresponent" +#: builtin/pack-objects.c msgid "ignore this pack" msgstr "ignora aquest paquet" +#: builtin/pack-objects.c msgid "pack compression level" msgstr "nivell de compressió de paquet" +#: builtin/pack-objects.c msgid "do not hide commits by grafts" msgstr "no amaguis les comissions per empelt" +#: builtin/pack-objects.c msgid "use a bitmap index if available to speed up counting objects" msgstr "" "usa un índex de mapa de bits, si està disponible, per a accelerar el " "recompte d'objectes" +#: builtin/pack-objects.c msgid "write a bitmap index together with the pack index" msgstr "escriu un índex de mapa de bits juntament amb l'índex de paquet" +#: builtin/pack-objects.c msgid "write a bitmap index if possible" msgstr "escriu un índex de mapa de bits si és possible" +#: builtin/pack-objects.c msgid "handling for missing objects" msgstr "gestió dels objectes absents" +#: builtin/pack-objects.c msgid "do not pack objects in promisor packfiles" msgstr "no empaquetis els objectes als fitxers de paquet «promisor»" +#: builtin/pack-objects.c msgid "respect islands during delta compression" msgstr "respecta les illes durant la compressió delta" +#: builtin/pack-objects.c msgid "protocol" msgstr "protocol" +#: builtin/pack-objects.c msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "" "exclou qualsevol uploadpack.blobpackfileuri configurat amb aquest protocol" +#: builtin/pack-objects.c #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "la profunditat de la cadena delta %d és massa profunda, forçant %d" +#: builtin/pack-objects.c #, c-format msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit és massa alt, forçant %d" +#: builtin/pack-objects.c config.c #, c-format msgid "bad pack compression level %d" msgstr "nivell de compressió de paquet %d erroni" +#: builtin/pack-objects.c msgid "--max-pack-size cannot be used to build a pack for transfer" msgstr "" "--max-pack-size no es pot utilitzar per a construir un paquet per a la " "transferència" +#: builtin/pack-objects.c msgid "minimum pack size limit is 1 MiB" msgstr "el límit mínim de mida del paquet és 1 MiB" +#: builtin/pack-objects.c msgid "--thin cannot be used to build an indexable pack" msgstr "--thin no es pot utilitzar per a construir un paquet indexable" +#: builtin/pack-objects.c msgid "cannot use --filter with --stdin-packs" msgstr "no es pot utilitzar --filter sense --stdin-packs" +#: builtin/pack-objects.c msgid "cannot use internal rev list with --stdin-packs" msgstr "no es pot utilitzar la llista de revisió interna amb --stdin-packs" +#: builtin/pack-objects.c msgid "cannot use internal rev list with --cruft" msgstr "no es pot utilitzar la llista de revisió interna amb --cruft" +#: builtin/pack-objects.c msgid "cannot use --stdin-packs with --cruft" msgstr "no es pot --stdin-packs amb --cruft" +#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "S'estan enumerant els objectes" +#: builtin/pack-objects.c #, c-format msgid "" "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" @@ -9473,6 +12142,7 @@ msgstr "" "Total %<PRIu32> (%<PRIu32> diferències), reusats %<PRIu32> (%<PRIu32> " "diferències), paquets reusats %<PRIu32> (de %<PRIuMAX>)" +#: builtin/pack-redundant.c msgid "" "'git pack-redundant' is nominated for removal.\n" "If you still use this command, please add an extra\n" @@ -9486,91 +12156,124 @@ msgstr "" "i feu-nos saber que encara l'useu enviant un correu electrònic\n" "a <git@vger.kernel.org>. Gràcies.\n" +#: builtin/pack-redundant.c msgid "refusing to run without --i-still-use-this" msgstr "es rebutja a executar sense --i-still-use-this" +#: builtin/pack-refs.c msgid "" -"git pack-refs [--all] [--no-prune] [--include <pattern>] [--exclude " +"git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" -"git pack-refs [--all] [--no-prune] [--include <patró>] [--exclude <patró>]" +"git pack-refs [--all] [--no-prune] [--auto] [--include <patró>] [--exclude " +"<patró>]" +#: builtin/pack-refs.c msgid "pack everything" msgstr "empaqueta-ho tot" +#: builtin/pack-refs.c msgid "prune loose refs (default)" msgstr "poda les referències soltes (per defecte)" +#: builtin/pack-refs.c +msgid "auto-pack refs as needed" +msgstr "auto-empaqueta referències si cal" + +#: builtin/pack-refs.c msgid "references to include" msgstr "referències a incloure" +#: builtin/pack-refs.c msgid "references to exclude" msgstr "referències a excloure" +#: builtin/patch-id.c msgid "git patch-id [--stable | --unstable | --verbatim]" msgstr "git patch-id [--stable | --unstable | --verbatim]" +#: builtin/patch-id.c msgid "use the unstable patch-id algorithm" msgstr "utilitza l'algorisme inestable de patch-id" +#: builtin/patch-id.c msgid "use the stable patch-id algorithm" msgstr "utilitza l'algorisme estable de patch-id" +#: builtin/patch-id.c msgid "don't strip whitespace from the patch" msgstr "no eliminis els espais en blanc del pedaç" +#: builtin/prune.c msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]" -msgstr "git prune [-n] [-v] [--progress] [--expire <data>] [--] [<head>...]" +msgstr "git prune [-n] [-v] [--progress] [--expire <data>] [--] [<cap>...]" +#: builtin/prune.c msgid "report pruned objects" msgstr "informa d'objectes podats" +#: builtin/prune.c msgid "expire objects older than <time>" msgstr "fes caducar els objectes més antics que <data>" +#: builtin/prune.c msgid "limit traversal to objects outside promisor packfiles" msgstr "" "limita el recorregut als objectes fora dels fitxers de paquet «promisor»" +#: builtin/prune.c msgid "cannot prune in a precious-objects repo" msgstr "no es pot podar en un repositori d'objectes preciosos" +#: builtin/pull.c msgid "git pull [<options>] [<repository> [<refspec>...]]" -msgstr "git pull [<opcions>] [<repositori> [<especificació-de-referència>...]]" +msgstr "git pull [<opcions>] [<repositori> [<especificació-referència>...]]" +#: builtin/pull.c msgid "control for recursive fetching of submodules" msgstr "controla l'obtenció recursiva de submòduls" +#: builtin/pull.c msgid "Options related to merging" msgstr "Opcions relacionades amb fusionar" +#: builtin/pull.c msgid "incorporate changes by rebasing rather than merging" msgstr "incorpora els canvis fent «rebase» en lloc de fusionar" +#: builtin/pull.c builtin/revert.c msgid "allow fast-forward" msgstr "permet l'avanç ràpid" +#: builtin/pull.c msgid "control use of pre-merge-commit and commit-msg hooks" msgstr "controla l'ús dels lligams pre-merge-commit i commit-msg" +#: builtin/pull.c parse-options.h msgid "automatically stash/stash pop before and after" msgstr "fes «stash» i «stash pop» automàticament abans i després" +#: builtin/pull.c msgid "Options related to fetching" msgstr "Opcions relacionades amb obtenir" +#: builtin/pull.c msgid "force overwrite of local branch" msgstr "força la sobreescriptura de la branca local" +#: builtin/pull.c msgid "number of submodules pulled in parallel" msgstr "nombre de submòduls baixats en paral·lel" +#: builtin/pull.c parse-options.h msgid "use IPv4 addresses only" msgstr "usa només adreces IPv4" +#: builtin/pull.c parse-options.h msgid "use IPv6 addresses only" msgstr "usa només adreces IPv6" +#: builtin/pull.c msgid "" "There is no candidate for rebasing against among the refs that you just " "fetched." @@ -9578,11 +12281,13 @@ msgstr "" "No hi ha cap candidat sobre el qual fer «rebase» entre les referències que " "acabeu d'obtenir." +#: builtin/pull.c msgid "" "There are no candidates for merging among the refs that you just fetched." msgstr "" "No hi ha candidats per a fusionar entre les referències que acabeu d'obtenir." +#: builtin/pull.c msgid "" "Generally this means that you provided a wildcard refspec which had no\n" "matches on the remote end." @@ -9590,6 +12295,7 @@ msgstr "" "Generalment això vol dir que heu proveït una especificació de\n" "referència de comodí que no tenia cap coincidència en el costat remot." +#: builtin/pull.c #, c-format msgid "" "You asked to pull from the remote '%s', but did not specify\n" @@ -9600,33 +12306,42 @@ msgstr "" "Perquè aquest no és el remot configurat per defecte per a la vostra\n" "branca actual, heu d'especificar una branca en la línia d'ordres." +#: builtin/pull.c builtin/rebase.c msgid "You are not currently on a branch." msgstr "Actualment no sou en cap branca." +#: builtin/pull.c msgid "Please specify which branch you want to rebase against." msgstr "Especifiqueu sobre quina branca voleu fer «rebase»." +#: builtin/pull.c msgid "Please specify which branch you want to merge with." msgstr "Especifiqueu amb quina branca voleu fusionar." +#: builtin/pull.c msgid "See git-pull(1) for details." msgstr "Vegeu git-pull(1) per a més informació." +#: builtin/pull.c builtin/rebase.c msgid "<remote>" msgstr "<remot>" +#: builtin/pull.c scalar.c msgid "<branch>" msgstr "<branca>" +#: builtin/pull.c builtin/rebase.c msgid "There is no tracking information for the current branch." msgstr "No hi ha cap informació de seguiment per a la branca actual." +#: builtin/pull.c msgid "" "If you wish to set tracking information for this branch you can do so with:" msgstr "" "Si voleu establir la informació de seguiment per a aquesta branca, podeu fer-" "ho amb:" +#: builtin/pull.c #, c-format msgid "" "Your configuration specifies to merge with the ref '%s'\n" @@ -9635,13 +12350,16 @@ msgstr "" "La vostra configuració especifica fusionar amb la referència «%s»\n" "del remot, però no s'ha obtingut tal referència." +#: builtin/pull.c #, c-format msgid "unable to access commit %s" msgstr "no s'ha pogut accedir a la comissió %s" +#: builtin/pull.c msgid "ignoring --verify-signatures for rebase" msgstr "s'està ignorant --verify-signatures en fer «rebase»" +#: builtin/pull.c msgid "" "You have divergent branches and need to specify how to reconcile them.\n" "You can do so by running one of the following commands sometime before\n" @@ -9671,26 +12389,31 @@ msgstr "" "--no-rebase o --ff-only en la línia d'ordres per a sobreescriure el valor\n" "per defecte de la configuració en aquesta execució.\n" +#: builtin/pull.c msgid "Updating an unborn branch with changes added to the index." msgstr "" "S'està actualitzant una branca no nascuda amb canvis afegits a l'índex." +#: builtin/pull.c msgid "pull with rebase" msgstr "baixar fent «rebase»" +#: builtin/pull.c builtin/rebase.c msgid "Please commit or stash them." msgstr "Cometeu-los o emmagatzemeu-los." +#: builtin/pull.c #, c-format msgid "" "fetch updated the current branch head.\n" "fast-forwarding your working tree from\n" "commit %s." msgstr "" -"l'obtenció ha actualitzat HEAD de la branca actual.\n" +"l'obtenció ha actualitzat el HEAD de la branca actual.\n" "s'està avançant ràpidament el vostre arbre de treball des de\n" "la comissió %s." +#: builtin/pull.c #, c-format msgid "" "Cannot fast-forward your working tree.\n" @@ -9708,32 +12431,41 @@ msgstr "" "$ git reset --hard\n" "per a recuperar." +#: builtin/pull.c msgid "Cannot merge multiple branches into empty head." msgstr "No es poden fusionar múltiples branques a una HEAD buida." +#: builtin/pull.c msgid "Cannot rebase onto multiple branches." msgstr "No es pot fer «rebase» sobre múltiples branques." +#: builtin/pull.c msgid "Cannot fast-forward to multiple branches." msgstr "No es pot fer un avançament ràpid a branques múltiples." +#: builtin/pull.c msgid "Need to specify how to reconcile divergent branches." msgstr "Cal especificar com reconciliar les branques divergents." +#: builtin/pull.c msgid "cannot rebase with locally recorded submodule modifications" msgstr "" "no es pot fer «rebase» amb modificacions als submòduls enregistrades " "localment" +#: builtin/push.c msgid "git push [<options>] [<repository> [<refspec>...]]" -msgstr "git push [<opcions>] [<repositori> [<especificació-de-referència>...]]" +msgstr "git push [<opcions>] [<repositori> [<especificació-referència>...]]" +#: builtin/push.c msgid "tag shorthand without <tag>" -msgstr "abreviatura d'etiqueta sense <tag>" +msgstr "abreviatura d'etiqueta sense <etiqueta>" +#: builtin/push.c msgid "--delete only accepts plain target ref names" msgstr "--delete només accepta noms de referència de destí senzills" +#: builtin/push.c msgid "" "\n" "To choose either option permanently, see push.default in 'git help config'.\n" @@ -9742,6 +12474,7 @@ msgstr "" "Per a triar qualsevol de les opcions permanentment, vegeu push.default a " "«git help config».\n" +#: builtin/push.c msgid "" "\n" "To avoid automatically configuring an upstream branch when its name\n" @@ -9753,6 +12486,7 @@ msgstr "" "no coincideix amb el de la branca local, vegeu l'opció «simple» de\n" "«branch.autoSetupMerge» a «git help config».\n" +#: builtin/push.c #, c-format msgid "" "The upstream branch of your current branch does not match\n" @@ -9777,6 +12511,7 @@ msgstr "" " git push %s HEAD\n" "%s%s" +#: builtin/push.c #, c-format msgid "" "You are not currently on a branch.\n" @@ -9791,6 +12526,7 @@ msgstr "" "\n" " git push %s HEAD:<nom-de-branca-remota>\n" +#: builtin/push.c msgid "" "\n" "To have this happen automatically for branches without a tracking\n" @@ -9801,6 +12537,7 @@ msgstr "" "seguiment\n" "font, vegeu «push.autoSetupRemote» a «git help config».\n" +#: builtin/push.c #, c-format msgid "" "The current branch %s has no upstream branch.\n" @@ -9815,17 +12552,20 @@ msgstr "" " git push --set-upstream %s %s\n" "%s" +#: builtin/push.c #, c-format msgid "The current branch %s has multiple upstream branches, refusing to push." msgstr "" "La branca actual %s té múltiples branques fonts, s'està refusant pujar." +#: builtin/push.c msgid "" "You didn't specify any refspecs to push, and push.default is \"nothing\"." msgstr "" "No heu especificat cap especificació de referència a pujar, i push.default " "és «nothing»." +#: builtin/push.c #, c-format msgid "" "You are pushing to remote '%s', which is not the upstream of\n" @@ -9836,6 +12576,7 @@ msgstr "" "branca actual «%s», sense dir-me què pujar per a actualitzar\n" "quina branca remota." +#: builtin/push.c msgid "" "Updates were rejected because the tip of your current branch is behind\n" "its remote counterpart. If you want to integrate the remote changes,\n" @@ -9847,6 +12588,7 @@ msgstr "" "remots useu «git pull» abans de tornar a pujar.\n" "Vegeu «Note about fast-forwards» a «git push --help» per a més detalls." +#: builtin/push.c msgid "" "Updates were rejected because a pushed branch tip is behind its remote\n" "counterpart. If you want to integrate the remote changes, use 'git pull'\n" @@ -9858,6 +12600,7 @@ msgstr "" "utilitzeu «git pull» abans de tornar a pujar.\n" "Vegeu «Note about fast-forwards» a «git push --help» per a més detalls." +#: builtin/push.c msgid "" "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" @@ -9867,15 +12610,17 @@ msgid "" msgstr "" "Les actualitzacions s'han rebutjat perquè el remot conté canvis que no " "teniu\n" -"localment. Això sol ser causat per un altre repositori que a pujat a\n" +"localment. Això sol ser causat per un altre repositori que ha pujat a\n" "la mateixa referència. Si voleu integrar els canvis remots, utilitzeu\n" "«git pull» abans de tornar a pujar.\n" "Vegeu «Note about fast-forwards» a «git push --help» per a més detalls." +#: builtin/push.c msgid "Updates were rejected because the tag already exists in the remote." msgstr "" "S'han rebutjat les actualitzacions perquè l'etiqueta ja existeix en el remot." +#: builtin/push.c msgid "" "You cannot update a remote ref that points at a non-commit object,\n" "or update a remote ref to make it point at a non-commit object,\n" @@ -9886,6 +12631,7 @@ msgstr "" "a fer que assenyali un objecte no de comissió, sense usar l'opció\n" "«--force».\n" +#: builtin/push.c msgid "" "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" @@ -9897,14 +12643,17 @@ msgstr "" "canvis remots, utilitzeu «git pull» abans de tornar a pujar.\n" "Vegeu «Note about fast-forwards» a «git push --help» per a més detalls." +#: builtin/push.c #, c-format msgid "Pushing to %s\n" msgstr "S'està pujant a %s\n" +#: builtin/push.c #, c-format msgid "failed to push some refs to '%s'" msgstr "s'ha produït un error en pujar algunes referències a «%s»" +#: builtin/push.c msgid "" "recursing into submodule with push.recurseSubmodules=only; using on-demand " "instead" @@ -9912,71 +12661,93 @@ msgstr "" "cerca recursivament en el submòdul amb push.recurseSubmodules=only; " "utilitzant «on-demand» en el seu lloc" +#: builtin/push.c builtin/send-pack.c submodule-config.c #, c-format msgid "invalid value for '%s'" msgstr "valor no vàlid per a «%s»" +#: builtin/push.c builtin/submodule--helper.c msgid "repository" msgstr "repositori" +#: builtin/push.c msgid "push all branches" msgstr "puja totes les referències" +#: builtin/push.c builtin/send-pack.c msgid "mirror all refs" msgstr "reflecteix totes les referències" +#: builtin/push.c msgid "delete refs" msgstr "suprimeix les referències" +#: builtin/push.c msgid "push tags (can't be used with --all or --branches or --mirror)" msgstr "puja les etiquetes (no es pot usar amb --all, --branches o --mirror)" +#: builtin/push.c builtin/send-pack.c msgid "force updates" msgstr "força les actualitzacions" +#: builtin/push.c builtin/send-pack.c msgid "<refname>:<expect>" -msgstr "<nom-de-referència>:<esperat>" +msgstr "<nom-referència>:<esperat>" +#: builtin/push.c builtin/send-pack.c msgid "require old value of ref to be at this value" msgstr "requereix que el valor antic de la referència sigui d'aquest valor" +#: builtin/push.c builtin/send-pack.c msgid "require remote updates to be integrated locally" msgstr "requereix que les actualitzacions remotes s'integrin localment" +#: builtin/push.c msgid "control recursive pushing of submodules" msgstr "controla la pujada recursiva dels submòduls" +#: builtin/push.c builtin/send-pack.c msgid "use thin pack" msgstr "usa el paquet prim" +#: builtin/push.c builtin/send-pack.c msgid "receive pack program" msgstr "programa que rep els paquets" +#: builtin/push.c msgid "set upstream for git pull/status" msgstr "estableix la font per a git pull/status" +#: builtin/push.c msgid "prune locally removed refs" msgstr "poda les referències eliminades localment" +#: builtin/push.c msgid "bypass pre-push hook" msgstr "evita el lligam de prepujada" +#: builtin/push.c msgid "push missing but relevant tags" msgstr "puja les etiquetes absents però rellevants" +#: builtin/push.c builtin/send-pack.c msgid "GPG sign the push" msgstr "signa la pujada amb GPG" +#: builtin/push.c builtin/send-pack.c msgid "request atomic transaction on remote side" msgstr "demana una transacció atòmica al costat remot" +#: builtin/push.c msgid "--delete doesn't make sense without any refs" msgstr "--delete no té sentit sense referències" +#: builtin/push.c t/helper/test-bundle-uri.c #, c-format msgid "bad repository '%s'" msgstr "repositori incorrecte «%s»" +#: builtin/push.c msgid "" "No configured push destination.\n" "Either specify the URL from the command-line or configure a remote " @@ -9998,54 +12769,70 @@ msgstr "" "\n" " git push <nom>\n" +#: builtin/push.c msgid "--all can't be combined with refspecs" msgstr "--all no es pot combinar amb especificacions de referència" +#: builtin/push.c msgid "--mirror can't be combined with refspecs" msgstr "--mirror no es pot combinar amb especificacions de referència" +#: builtin/push.c msgid "push options must not have new line characters" msgstr "les opcions de pujada no han de tenir caràcters de línia nova" +#: builtin/range-diff.c msgid "git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>" msgstr "git range-diff [<opcions>] <old-base>..<old-tip> <new-base>..<new-tip>" +#: builtin/range-diff.c msgid "git range-diff [<options>] <old-tip>...<new-tip>" msgstr "git range-diff [<opcions>] <old-tip>...<new-tip>" +#: builtin/range-diff.c msgid "git range-diff [<options>] <base> <old-tip> <new-tip>" msgstr "git range-diff [<opcions>] <base> <old-tip> <new-tip>" +#: builtin/range-diff.c msgid "use simple diff colors" msgstr "utilitza colors simples de diff" +#: builtin/range-diff.c msgid "notes" msgstr "notes" +#: builtin/range-diff.c msgid "passed to 'git log'" msgstr "passa-ho a «git log»" +#: builtin/range-diff.c msgid "only emit output related to the first range" msgstr "emet només la sortida relacionada amb el primer interval" +#: builtin/range-diff.c msgid "only emit output related to the second range" msgstr "emet només la sortida relacionada amb el segon interval" +#: builtin/range-diff.c #, c-format msgid "not a revision: '%s'" msgstr "«%s» no és una revisió" +#: builtin/range-diff.c #, c-format msgid "not a commit range: '%s'" msgstr "no és un rang de comissions: «%s»" +#: builtin/range-diff.c #, c-format msgid "not a symmetric range: '%s'" msgstr "no és un rang simètric: «%s»" +#: builtin/range-diff.c msgid "need two commit ranges" msgstr "calen dos rangs de comissió" +#: builtin/read-tree.c msgid "" "git read-tree [(-m [--trivial] [--aggressive] | --reset | --" "prefix=<prefix>)\n" @@ -10057,60 +12844,79 @@ msgstr "" " [-u | -i]] [--index-output=<fitxer>] [--no-sparse-checkout]\n" " (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])" +#: builtin/read-tree.c msgid "write resulting index to <file>" msgstr "escriu l'índex resultant al <fitxer>" +#: builtin/read-tree.c msgid "only empty the index" msgstr "només buida l'índex" +#: builtin/read-tree.c msgid "Merging" msgstr "S'està fusionant" +#: builtin/read-tree.c msgid "perform a merge in addition to a read" msgstr "realitza una fusió a més d'una lectura" +#: builtin/read-tree.c msgid "3-way merge if no file level merging required" msgstr "fusió de 3 vies si no cal fusió a nivell de fitxers" +#: builtin/read-tree.c msgid "3-way merge in presence of adds and removes" msgstr "fusió de 3 vies en presència d'afegiments i eliminacions" +#: builtin/read-tree.c msgid "same as -m, but discard unmerged entries" msgstr "el mateix que -m, però descarta les entrades no fusionades" +#: builtin/read-tree.c msgid "<subdirectory>/" msgstr "<subdirectori>/" +#: builtin/read-tree.c msgid "read the tree into the index under <subdirectory>/" msgstr "llegeix l'arbre a l'índex sota <subdirectori>/" +#: builtin/read-tree.c msgid "update working tree with merge result" msgstr "actualitza l'arbre de treball amb el resultat de fusió" +#: builtin/read-tree.c msgid "gitignore" msgstr "gitignore" +#: builtin/read-tree.c msgid "allow explicitly ignored files to be overwritten" msgstr "permet que els fitxers explícitament ignorats se sobreescriguin" +#: builtin/read-tree.c msgid "don't check the working tree after merging" msgstr "no comprovis l'arbre de treball després de fusionar" +#: builtin/read-tree.c msgid "don't update the index or the work tree" msgstr "no actualitzis l'índex ni l'arbre de treball" +#: builtin/read-tree.c msgid "skip applying sparse checkout filter" msgstr "omet l'aplicació del filtre d'agafament parcial" +#: builtin/read-tree.c msgid "debug unpack-trees" msgstr "depura unpack-trees" +#: builtin/read-tree.c msgid "suppress feedback messages" msgstr "suprimeix els missatges de retroacció" +#: builtin/read-tree.c msgid "You need to resolve your current index first" msgstr "Primer heu de resoldre el vostre índex actual" +#: builtin/rebase.c msgid "" "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase> | --keep-base] " "[<upstream> [<branch>]]" @@ -10118,64 +12924,61 @@ msgstr "" "git rebase [-i] [options] [--exec <ordre>] [--onto <newbase> | --keep-base] " "[<upstream> [<branca>]]" +#: builtin/rebase.c msgid "" "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]" msgstr "" "git rebase [-i] [options] [--exec <ordre>] [--onto <newbase>] --root " "[<branca>]" +#: builtin/rebase.c sequencer.c #, c-format msgid "could not read '%s'." msgstr "no s'ha pogut llegir «%s»." +#: builtin/rebase.c #, c-format msgid "could not create temporary %s" msgstr "no s'ha pogut crear el fitxer temporal %s" +#: builtin/rebase.c msgid "could not mark as interactive" msgstr "no s'ha pogut marcar com a interactiu" +#: builtin/rebase.c msgid "could not generate todo list" msgstr "no s'ha pogut generar la llista per a fer" +#: builtin/rebase.c msgid "a base commit must be provided with --upstream or --onto" msgstr "s'ha de proporcionar una comissió base amb --upstream o --onto" +#: builtin/rebase.c #, c-format msgid "%s requires the merge backend" msgstr "%s requereix un rerefons de fusió" +#: builtin/rebase.c #, c-format msgid "invalid onto: '%s'" msgstr "no vàlid a: «%s»" +#: builtin/rebase.c #, c-format msgid "invalid orig-head: '%s'" msgstr "orig-head no és vàlid: «%s»" +#: builtin/rebase.c #, c-format msgid "ignoring invalid allow_rerere_autoupdate: '%s'" msgstr "s'ignora allow_rerere_autoupdate no vàlid: «%s»" +#: builtin/rebase.c builtin/rm.c sequencer.c #, c-format msgid "could not remove '%s'" msgstr "no s'ha pogut eliminar «%s»" -msgid "" -"Resolve all conflicts manually, mark them as resolved with\n" -"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n" -"You can instead skip this commit: run \"git rebase --skip\".\n" -"To abort and get back to the state before \"git rebase\", run \"git rebase --" -"abort\"." -msgstr "" -"Resoleu tots els conflictes manualment, marqueu-los com a resolts amb\n" -"«git add/rm <fitxers_amb_conflicte>», llavors executeu «git rebase --" -"continue».\n" -"Alternativament podeu ometre aquesta comissió: executeu «git rebase --" -"skip».\n" -"Per a avortar i tornar a l'estat anterior abans de l'ordre «git rebase», " -"executeu «git rebase --abort»." - +#: builtin/rebase.c #, c-format msgid "" "\n" @@ -10194,24 +12997,34 @@ msgstr "" "\n" "Com a resultat, git no pot fer un «rebase» d'elles." +#: builtin/rebase.c #, c-format msgid "Unknown rebase-merges mode: %s" msgstr "Mode de fusió de rebase desconegut: %s" +#: builtin/rebase.c #, c-format msgid "could not switch to %s" msgstr "no s'ha pogut commutar a %s" +#: builtin/rebase.c msgid "apply options and merge options cannot be used together" msgstr "les opcions apply i merge no es poden usar juntes" +#: builtin/rebase.c +msgid "--empty=ask is deprecated; use '--empty=stop' instead." +msgstr "--empty=ask és obslolet; utilitzeu '--empty=stop' en el seu lloc." + +#: builtin/rebase.c #, c-format msgid "" "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and " -"\"ask\"." +"\"stop\"." msgstr "" -"tipus buit no reconegut «%s»; els valors vàlids són «drop», «keep» i «ask»." +"tipus buit «%s» no reconegut; els valors vàlids són \"drop\", \"keep\" i " +"\"stop\"." +#: builtin/rebase.c msgid "" "--rebase-merges with an empty string argument is deprecated and will stop " "working in a future version of Git. Use --rebase-merges without an argument " @@ -10221,6 +13034,7 @@ msgstr "" "funcionar en una versió futura del Git. Utilitzeu --rebase-merges sense un " "argument, que fa el mateix." +#: builtin/rebase.c #, c-format msgid "" "%s\n" @@ -10237,6 +13051,7 @@ msgstr "" " git rebase '<branca>'\n" "\n" +#: builtin/rebase.c #, c-format msgid "" "If you wish to set tracking information for this branch you can do so with:\n" @@ -10250,128 +13065,169 @@ msgstr "" " git branch --set-upstream-to=%s/<branca> %s\n" "\n" +#: builtin/rebase.c msgid "exec commands cannot contain newlines" msgstr "les ordres exec no poden contenir línies noves" +#: builtin/rebase.c msgid "empty exec command" msgstr "ordre exec buida" +#: builtin/rebase.c msgid "rebase onto given branch instead of upstream" msgstr "fes un «rebase» en la branca donada en comptes de la font" +#: builtin/rebase.c msgid "use the merge-base of upstream and branch as the current base" msgstr "utilitza la base de fusió de la font i la branca com a base actual" +#: builtin/rebase.c msgid "allow pre-rebase hook to run" msgstr "permet al lligam pre-rebase executar-se" +#: builtin/rebase.c msgid "be quiet. implies --no-stat" msgstr "silenciós. Implica --no-stat" +#: builtin/rebase.c msgid "display a diffstat of what changed upstream" msgstr "mostra un «diffstat» del que ha canviat a la font" +#: builtin/rebase.c msgid "do not show diffstat of what changed upstream" msgstr "no mostris «diffstat» del que ha canviat a la font" +#: builtin/rebase.c msgid "add a Signed-off-by trailer to each commit" msgstr "afegeix un «trailer» tipus «Signed-off-by» a cada comissió" +#: builtin/rebase.c msgid "make committer date match author date" msgstr "fes que la data del «committer» coincideixi amb la data de l'autor" +#: builtin/rebase.c msgid "ignore author date and use current date" msgstr "ignora la data de l'autor i utilitza la data actual" +#: builtin/rebase.c msgid "synonym of --reset-author-date" msgstr "sinònim de --reset-author-date" +#: builtin/rebase.c msgid "passed to 'git apply'" msgstr "passa-ho a «git apply»" +#: builtin/rebase.c msgid "ignore changes in whitespace" msgstr "ignora els canvis d'espais en blanc" +#: builtin/rebase.c msgid "cherry-pick all commits, even if unchanged" msgstr "«cherry pick» totes les comissions, inclús les no canviades" +#: builtin/rebase.c msgid "continue" msgstr "continua" +#: builtin/rebase.c msgid "skip current patch and continue" msgstr "omet el pedaç actual i continua" +#: builtin/rebase.c msgid "abort and check out the original branch" msgstr "interromp i agafa la branca original" +#: builtin/rebase.c msgid "abort but keep HEAD where it is" msgstr "interromp però manté HEAD on és" +#: builtin/rebase.c msgid "edit the todo list during an interactive rebase" msgstr "edita la llista de coses a fer durant un «rebase» interactiu" +#: builtin/rebase.c msgid "show the patch file being applied or merged" msgstr "mostra el pedaç que s'està aplicant o fusionant" +#: builtin/rebase.c msgid "use apply strategies to rebase" msgstr "utilitza estratègies d'aplicació per a fer «rebase»" +#: builtin/rebase.c msgid "use merging strategies to rebase" msgstr "utilitza estratègies de fusió per a fer «rebase»" +#: builtin/rebase.c msgid "let the user edit the list of commits to rebase" msgstr "permet a l'usuari editar la llista de comissions a fer «rebase»" +#: builtin/rebase.c msgid "(REMOVED) was: try to recreate merges instead of ignoring them" msgstr "(SUPRIMIT) era: intenta recrear fusions en lloc d'ignorar-les" +#: builtin/rebase.c builtin/revert.c msgid "how to handle commits that become empty" msgstr "com gestionar les comissions que queden buides" +#: builtin/rebase.c msgid "keep commits which start empty" msgstr "manté les comissions que comencen en blanc" +#: builtin/rebase.c msgid "move commits that begin with squash!/fixup! under -i" msgstr "mou les comissions que comencen amb squash!/fixup! sota -i" +#: builtin/rebase.c msgid "update branches that point to commits that are being rebased" msgstr "" "actualitza les branques que apunten a comissions a les quals se'ls està fent " "«rebase»" +#: builtin/rebase.c msgid "add exec lines after each commit of the editable list" msgstr "afegeix línies d'exec després de cada comissió de la llista editable" +#: builtin/rebase.c msgid "allow rebasing commits with empty messages" msgstr "permet fer «rebase» de les comissions amb missatges buits" +#: builtin/rebase.c msgid "try to rebase merges instead of skipping them" msgstr "intenta fer «rebase» de les fusions en comptes d'ometre-les" +#: builtin/rebase.c msgid "use 'merge-base --fork-point' to refine upstream" msgstr "usa «merge-base --fork-point» per a refinar la font" +#: builtin/rebase.c msgid "use the given merge strategy" msgstr "utilitza l'estratègia de fusió donada" +#: builtin/rebase.c builtin/revert.c msgid "option" msgstr "opció" +#: builtin/rebase.c msgid "pass the argument through to the merge strategy" msgstr "passa l'argument a l'estratègia de fusió" +#: builtin/rebase.c msgid "rebase all reachable commits up to the root(s)" msgstr "fes «rebase» de totes les comissions accessibles fins a l'arrel" +#: builtin/rebase.c msgid "automatically re-schedule any `exec` that fails" msgstr "torna a planificar automàticament qualsevol «exec» que falli" +#: builtin/rebase.c msgid "apply all changes, even those already present upstream" msgstr "aplica tots els canvis, fins i tot els que ja estan a la font" +#: builtin/rebase.c msgid "It looks like 'git am' is in progress. Cannot rebase." msgstr "Sembla que «git am» està en curs. No es pot fer «rebase»." +#: builtin/rebase.c msgid "" "`rebase --preserve-merges` (-p) is no longer supported.\n" "Use `git rebase --abort` to terminate current rebase.\n" @@ -10381,6 +13237,7 @@ msgstr "" "Utilitzeu «git rebase --abort» per a finalitzar el «rebase» actual.\n" "O bé baixeu a la versió v2.33, o anterior, per a completar el «rebase»." +#: builtin/rebase.c msgid "" "--preserve-merges was replaced by --rebase-merges\n" "Note: Your `pull.rebase` configuration may also be set to 'preserve',\n" @@ -10390,15 +13247,19 @@ msgstr "" "Nota: la configuració «pull.rebase» també podria estar establerta a\n" "+-«preserve», que ja no s'admet; utilitzeu «merge» en el seu lloc" -msgid "No rebase in progress?" -msgstr "No hi ha un «rebase» en curs?" +#: builtin/rebase.c +msgid "no rebase in progress" +msgstr "no hi ha cap «rebase» en curs" +#: builtin/rebase.c msgid "The --edit-todo action can only be used during interactive rebase." msgstr "L'acció --edit-todo només es pot usar durant un «rebase» interactiu." +#: builtin/rebase.c msgid "Cannot read HEAD" msgstr "No es pot llegir HEAD" +#: builtin/rebase.c msgid "" "You must edit all merge conflicts and then\n" "mark them as resolved using git add" @@ -10406,13 +13267,16 @@ msgstr "" "Heu d'editar tots els conflictes de fusió i després\n" "marcar-los com a resolts fent servir git add" +#: builtin/rebase.c msgid "could not discard worktree changes" msgstr "no s'han pogut descartar els canvis de l'arbre de treball" +#: builtin/rebase.c #, c-format msgid "could not move back to %s" msgstr "no s'ha pogut tornar a %s" +#: builtin/rebase.c #, c-format msgid "" "It seems that there is already a %s directory, and\n" @@ -10432,9 +13296,11 @@ msgstr "" "i després executeu aquesta ordre de nou. S'atura l'operació en cas que\n" "tingueu quelcom valuós.\n" +#: builtin/rebase.c msgid "switch `C' expects a numerical value" msgstr "«switch» «c» espera un valor numèric" +#: builtin/rebase.c msgid "" "apply options are incompatible with rebase.rebaseMerges. Consider adding --" "no-rebase-merges" @@ -10442,6 +13308,7 @@ msgstr "" "les opcions «apply» són incompatibles amb rebase.rebaseMerges. Considereu " "afegir-hi --no-rebase-merges" +#: builtin/rebase.c msgid "" "apply options are incompatible with rebase.updateRefs. Consider adding --no-" "update-refs" @@ -10449,84 +13316,106 @@ msgstr "" "les opcions «apply» són incompatibles amb rebase.updateRefs. Considereu " "afegir-hi --no-update-refs" +#: builtin/rebase.c #, c-format msgid "Unknown rebase backend: %s" msgstr "Rerefons de «rebase» desconegut: %s" +#: builtin/rebase.c msgid "--reschedule-failed-exec requires --exec or --interactive" msgstr "--reschedule-failed-exec requereix --exec o --interactive" +#: builtin/rebase.c #, c-format msgid "invalid upstream '%s'" msgstr "font no vàlida: «%s»" +#: builtin/rebase.c msgid "Could not create new root commit" msgstr "No s'ha pogut crear una comissió arrel nova" +#: builtin/rebase.c #, c-format msgid "no such branch/commit '%s'" msgstr "no existeix aquesta branca o comissió «%s»" +#: builtin/rebase.c builtin/submodule--helper.c #, c-format msgid "No such ref: %s" msgstr "No hi ha tal referència: %s" +#: builtin/rebase.c msgid "Could not resolve HEAD to a commit" msgstr "No s'ha pogut resoldre HEAD com a una comissió" +#: builtin/rebase.c #, c-format msgid "'%s': need exactly one merge base with branch" msgstr "«%s»: necessita exactament una base de fusió amb branca" +#: builtin/rebase.c #, c-format msgid "'%s': need exactly one merge base" msgstr "«%s»: necessita exactament una base de fusió" +#: builtin/rebase.c #, c-format msgid "Does not point to a valid commit '%s'" msgstr "No apunta a una comissió vàlida «%s»" +#: builtin/rebase.c msgid "HEAD is up to date." msgstr "HEAD està al dia." +#: builtin/rebase.c #, c-format msgid "Current branch %s is up to date.\n" msgstr "La branca actual %s està al dia.\n" +#: builtin/rebase.c msgid "HEAD is up to date, rebase forced." msgstr "La branca actual està al dia, «rebase» forçat." +#: builtin/rebase.c #, c-format msgid "Current branch %s is up to date, rebase forced.\n" msgstr "La branca actual %s està al dia; «rebase» forçat.\n" +#: builtin/rebase.c msgid "The pre-rebase hook refused to rebase." msgstr "El lligam pre-rebase ha refusat a fer «rebase»." +#: builtin/rebase.c #, c-format msgid "Changes to %s:\n" msgstr "Canvis a %s:\n" +#: builtin/rebase.c #, c-format msgid "Changes from %s to %s:\n" msgstr "Canvis de %s a %s:\n" +#: builtin/rebase.c #, c-format msgid "First, rewinding head to replay your work on top of it...\n" msgstr "" "Primer, s'està rebobinant HEAD per a reproduir el vostre treball al " "damunt...\n" +#: builtin/rebase.c msgid "Could not detach HEAD" msgstr "No s'ha pogut separar HEAD" +#: builtin/rebase.c #, c-format msgid "Fast-forwarded %s to %s.\n" msgstr "Avanç ràpid %s a %s.\n" +#: builtin/receive-pack.c msgid "git receive-pack <git-dir>" msgstr "git receive-pack <git-dir>" +#: builtin/receive-pack.c msgid "" "By default, updating the current branch in a non-bare repository\n" "is denied, because it will make the index and work tree inconsistent\n" @@ -10557,6 +13446,7 @@ msgstr "" "per defecte, establiu la variable de configuració\n" "«receive.denyCurrentBranch» a «refuse»." +#: builtin/receive-pack.c msgid "" "By default, deleting the current branch is denied, because the next\n" "'git clone' won't result in any file checked out, causing confusion.\n" @@ -10578,15 +13468,23 @@ msgstr "" "\n" "Per a silenciar aquest missatge, podeu establir-la a «refuse»." +#: builtin/receive-pack.c msgid "quiet" msgstr "silenciós" +#: builtin/receive-pack.c msgid "you must specify a directory" msgstr "heu d'especificar un directori" +#: builtin/reflog.c msgid "git reflog [show] [<log-options>] [<ref>]" -msgstr "git reflog [show] [<log-options>] [<ref>]" +msgstr "git reflog [show] [<opcions-registre>] [<referència>]" + +#: builtin/reflog.c +msgid "git reflog list" +msgstr "git reflog list" +#: builtin/reflog.c msgid "" "git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" " [--rewrite] [--updateref] [--stale-fix]\n" @@ -10598,39 +13496,57 @@ msgstr "" " [--dry-run | -n] [--verbose] [--all [--single-worktree] | " "<refs>...]" +#: builtin/reflog.c msgid "" "git reflog delete [--rewrite] [--updateref]\n" " [--dry-run | -n] [--verbose] <ref>@{<specifier>}..." msgstr "" "git reflog delete [--rewrite] [--updateref]\n" -" [--dry-run | -n] [--verbose] <ref>@{<specifier>}..." +" [--dry-run | -n] [--verbose] " +"<referència>@{<especificador>}..." +#: builtin/reflog.c msgid "git reflog exists <ref>" msgstr "git reflog exists <referència>" +#: builtin/reflog.c #, c-format msgid "invalid timestamp '%s' given to '--%s'" msgstr "marca de temps «%s» donada a «--%s» no és vàlida" +#: builtin/reflog.c sequencer.c +#, c-format +msgid "%s does not accept arguments: '%s'" +msgstr "%s no accepta arguments: «%s»" + +#: builtin/reflog.c msgid "do not actually prune any entries" msgstr "no eliminis cap entrada" +#: builtin/reflog.c msgid "" "rewrite the old SHA1 with the new SHA1 of the entry that now precedes it" msgstr "reescriu l'antic SHA1 amb el nou SHA1 de l'entrada que ara precedeix" +#: builtin/reflog.c msgid "update the reference to the value of the top reflog entry" -msgstr "actualitza la referència al valor de l'entrada de reflog superior" +msgstr "" +"actualitza la referència al valor de l'entrada de registre de referència " +"superior" +#: builtin/reflog.c msgid "print extra information on screen" msgstr "imprimeix informació extra a la pantalla" +#: builtin/reflog.c msgid "timestamp" msgstr "marca de temps" +#: builtin/reflog.c msgid "prune entries older than the specified time" msgstr "poda les entrades més antigues que el temps especificat" +#: builtin/reflog.c msgid "" "prune entries older than <time> that are not reachable from the current tip " "of the branch" @@ -10638,30 +13554,75 @@ msgstr "" "poda les entrades més antigues de <data> que no es poden accedir des de la " "punta actual de la branca" +#: builtin/reflog.c msgid "prune any reflog entries that point to broken commits" -msgstr "poda qualsevol entrada de reflog que apunti a comissions trencades" +msgstr "" +"poda qualsevol entrada del registre de referències que apunti a comissions " +"trencades" +#: builtin/reflog.c msgid "process the reflogs of all references" -msgstr "processa els reflogs de totes les referències" +msgstr "processa els registres de referències de totes les referències" +#: builtin/reflog.c msgid "limits processing to reflogs from the current worktree only" -msgstr "limita el processament a reflogs només de l'arbre de treball actual" +msgstr "" +"limita el processament només a registres de referències de l'arbre de " +"treball actual" +#: builtin/reflog.c #, c-format msgid "Marking reachable objects..." msgstr "S'estan marcant els objectes abastables..." +#: builtin/reflog.c #, c-format msgid "%s points nowhere!" msgstr "%s no apunta a enlloc" +#: builtin/reflog.c msgid "no reflog specified to delete" -msgstr "no s'ha especificat cap registre de referència per a suprimir" +msgstr "no s'ha especificat cap registre de referències per a suprimir" +#: builtin/reflog.c #, c-format msgid "invalid ref format: %s" msgstr "format de referència no vàlid: %s" +#: builtin/refs.c +msgid "git refs migrate --ref-format=<format> [--dry-run]" +msgstr "git refs migrate --ref-format=<format> [--dry-run]" + +#: builtin/refs.c +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" + +#: builtin/refs.c +msgid "specify the reference format to convert to" +msgstr "especifiqueu el format de referència al qual voleu convertir" + +#: builtin/refs.c +msgid "perform a non-destructive dry-run" +msgstr "fes una prova no destructiva" + +#: builtin/refs.c +msgid "missing --ref-format=<format>" +msgstr "falta --ref-format=<format>" + +#: builtin/refs.c +#, c-format +msgid "repository already uses '%s' format" +msgstr "el repositori ja usa el format «%s»" + +#: builtin/refs.c +msgid "enable strict checking" +msgstr "habilita la comprovació estricta" + +#: builtin/refs.c +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' no accepta arguments" + +#: builtin/remote.c msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -10669,67 +13630,87 @@ msgstr "" "git remote add [-t <branca>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <nom> <url>" +#: builtin/remote.c msgid "git remote rename [--[no-]progress] <old> <new>" -msgstr "git remote rename [--[no-]progress] <old> <new>" +msgstr "git remote rename [--[no-]progress] <vell> <nou>" +#: builtin/remote.c msgid "git remote remove <name>" msgstr "git remote remove <nom>" +#: builtin/remote.c msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)" msgstr "git remote set-head <nom> (-a | --auto | -d | --delete | <branca>)" +#: builtin/remote.c msgid "git remote [-v | --verbose] show [-n] <name>" msgstr "git remote [-v | --verbose] show [-n] <nom>" +#: builtin/remote.c msgid "git remote prune [-n | --dry-run] <name>" msgstr "git remote prune [-n | --dry-run] <nom>" +#: builtin/remote.c msgid "" "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]" msgstr "" "git remote [-v | --verbose] update [-p | --prune] [(<grup> | <remot>)...]" +#: builtin/remote.c msgid "git remote set-branches [--add] <name> <branch>..." msgstr "git remote set-branches [--add] <nom> <branca>..." +#: builtin/remote.c msgid "git remote get-url [--push] [--all] <name>" msgstr "git remote get-url [--push] [--all] <nom>" +#: builtin/remote.c msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]" -msgstr "git remote set-url [--push] <nom> <url-nou> [<url-antic>]" +msgstr "<git remote set-url [--push] <nom> <url-nou> [<url-vell>]" +#: builtin/remote.c msgid "git remote set-url --add <name> <newurl>" msgstr "git remote set-url --add <nom> <url-nou>" +#: builtin/remote.c msgid "git remote set-url --delete <name> <url>" msgstr "git remote set-url --delete <nom> <url>" +#: builtin/remote.c msgid "git remote add [<options>] <name> <url>" msgstr "git remote add [<opcions>] <nom> <url>" +#: builtin/remote.c msgid "git remote set-branches <name> <branch>..." msgstr "git remote set-branches <nom> <branca>..." +#: builtin/remote.c msgid "git remote set-branches --add <name> <branch>..." msgstr "git remote set-branches --add <nom> <branca>..." +#: builtin/remote.c msgid "git remote show [<options>] <name>" msgstr "git remote show [<opcions>] <nom>" +#: builtin/remote.c msgid "git remote prune [<options>] <name>" msgstr "git remote prune [<opcions>] <nom>" +#: builtin/remote.c msgid "git remote update [<options>] [<group> | <remote>]..." msgstr "git remote update [<opcions>] [<grup> | <remot>]..." +#: builtin/remote.c #, c-format msgid "Updating %s" msgstr "S'està actualitzant %s" +#: builtin/remote.c #, c-format msgid "Could not fetch %s" msgstr "No s'ha pogut obtenir %s" +#: builtin/remote.c msgid "" "--mirror is dangerous and deprecated; please\n" "\t use --mirror=fetch or --mirror=push instead" @@ -10738,13 +13719,16 @@ msgstr "" "\t useu --mirror=fetch o\n" "\t --mirror=push en lloc d'això" +#: builtin/remote.c #, c-format -msgid "unknown mirror argument: %s" -msgstr "argument de «mirror» desconegut: %s" +msgid "unknown --mirror argument: %s" +msgstr "argument de «--mirror» desconegut: %s" +#: builtin/remote.c msgid "fetch the remote branches" msgstr "obtén les branques remotes" +#: builtin/remote.c msgid "" "import all tags and associated objects when fetching\n" "or do not fetch any tag at all (--no-tags)" @@ -10752,57 +13736,72 @@ msgstr "" "importa totes les etiquetes i objectes associats en obtenir\n" "o no obtingueu cap etiqueta (--no-tags)" +#: builtin/remote.c msgid "branch(es) to track" msgstr "branques a seguir" +#: builtin/remote.c msgid "master branch" msgstr "branca mestra" +#: builtin/remote.c msgid "set up remote as a mirror to push to or fetch from" msgstr "estableix el remot com a mirall al qual pujar o del qual obtenir" +#: builtin/remote.c msgid "specifying a master branch makes no sense with --mirror" msgstr "especificar una branca mestra no té sentit amb --mirror" +#: builtin/remote.c msgid "specifying branches to track makes sense only with fetch mirrors" msgstr "" "especificar les branques a seguir té sentit només amb miralls d'obtenció" +#: builtin/remote.c #, c-format msgid "remote %s already exists." msgstr "el remot %s ja existeix." +#: builtin/remote.c #, c-format msgid "Could not setup master '%s'" msgstr "No s'ha pogut configurar la mestra «%s»" +#: builtin/remote.c trailer.c #, c-format msgid "more than one %s" msgstr "més d'un %s" +#: builtin/remote.c #, c-format msgid "unhandled branch.%s.rebase=%s; assuming 'true'" msgstr "no s'ha gestionat branch.%s.rebase=%s; assumint «true»" +#: builtin/remote.c #, c-format msgid "Could not get fetch map for refspec %s" msgstr "" "No s'ha pogut obtenir el mapa d'obtenció de l'especificació de referència %s" +#: builtin/remote.c msgid "(matching)" msgstr "(coincident)" +#: builtin/remote.c msgid "(delete)" msgstr "(suprimir)" +#: builtin/remote.c #, c-format msgid "could not set '%s'" msgstr "no s'ha pogut establir «%s»" +#: builtin/remote.c config.c #, c-format msgid "could not unset '%s'" msgstr "no s'ha pogut desassignar «%s»" +#: builtin/remote.c #, c-format msgid "" "The %s configuration remote.pushDefault in:\n" @@ -10813,14 +13812,17 @@ msgstr "" "\t%s:%d\n" "ara anomena un remot no existent «%s»" +#: builtin/remote.c #, c-format msgid "No such remote: '%s'" msgstr "No existeix el remot «%s»" +#: builtin/remote.c #, c-format msgid "Could not rename config section '%s' to '%s'" msgstr "No s'ha pogut canviar el nom de la secció de configuració «%s» a «%s»" +#: builtin/remote.c #, c-format msgid "" "Not updating non-default fetch refspec\n" @@ -10832,17 +13834,21 @@ msgstr "" "\t%s\n" "\tActualitzeu la configuració manualment si és necessari." +#: builtin/remote.c msgid "Renaming remote references" msgstr "S'està canviant el nom de les referències remotes" +#: builtin/remote.c #, c-format msgid "deleting '%s' failed" msgstr "la supressió de «%s» ha fallat" +#: builtin/remote.c #, c-format msgid "creating '%s' failed" msgstr "la creació de «%s» ha fallat" +#: builtin/remote.c msgid "" "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n" "to delete it, use:" @@ -10857,246 +13863,307 @@ msgstr[1] "" "eliminat;\n" "per a suprimir-les, useu:" +#: builtin/remote.c #, c-format msgid "Could not remove config section '%s'" msgstr "No s'ha pogut eliminar la secció de configuració «%s»" +#: builtin/remote.c #, c-format msgid " new (next fetch will store in remotes/%s)" msgstr " nou (la pròxima obtenció emmagatzemarà a remotes/%s)" +#: builtin/remote.c msgid " tracked" msgstr " seguit" +#: builtin/remote.c msgid " skipped" msgstr " omès" +#: builtin/remote.c msgid " stale (use 'git remote prune' to remove)" msgstr " estancat (useu «git remote prune» per a eliminar)" +#: builtin/remote.c msgid " ???" msgstr " ???" +#: builtin/remote.c #, c-format msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch" msgstr "branch.%s.merge no vàlid; no es pot fer «rebase» sobre > 1 branca" +#: builtin/remote.c #, c-format msgid "rebases interactively onto remote %s" msgstr "es fa «rebase» interactivament sobre el remot %s" +#: builtin/remote.c #, c-format msgid "rebases interactively (with merges) onto remote %s" msgstr "es fa «rebase» interactivament (amb fusions) sobre el remot %s" +#: builtin/remote.c #, c-format msgid "rebases onto remote %s" msgstr "es fa «rebase» sobre el remot %s" +#: builtin/remote.c #, c-format msgid " merges with remote %s" msgstr " es fusiona amb el remot %s" +#: builtin/remote.c #, c-format msgid "merges with remote %s" msgstr "es fusiona amb el remot %s" +#: builtin/remote.c #, c-format msgid "%-*s and with remote %s\n" msgstr "%-*s i amb el remot %s\n" +#: builtin/remote.c msgid "create" msgstr "crea" +#: builtin/remote.c msgid "delete" msgstr "suprimeix" +#: builtin/remote.c msgid "up to date" msgstr "al dia" +#: builtin/remote.c msgid "fast-forwardable" msgstr "avanç ràpid possible" +#: builtin/remote.c msgid "local out of date" msgstr "local no actualitzat" +#: builtin/remote.c #, c-format msgid " %-*s forces to %-*s (%s)" msgstr " %-*s força a %-*s (%s)" +#: builtin/remote.c #, c-format msgid " %-*s pushes to %-*s (%s)" msgstr " %-*s puja a %-*s (%s)" +#: builtin/remote.c #, c-format msgid " %-*s forces to %s" msgstr " %-*s força a %s" +#: builtin/remote.c #, c-format msgid " %-*s pushes to %s" msgstr " %-*s puja a %s" +#: builtin/remote.c msgid "do not query remotes" msgstr "no consultis els remots" +#: builtin/remote.c #, c-format msgid "* remote %s" msgstr "* remot %s" +#: builtin/remote.c #, c-format msgid " Fetch URL: %s" msgstr " URL d'obtenció: %s" -msgid "(no URL)" -msgstr "(sense URL)" - #. TRANSLATORS: the colon ':' should align #. with the one in " Fetch URL: %s" #. translation. #. +#: builtin/remote.c #, c-format msgid " Push URL: %s" msgstr " URL de pujada: %s" +#: builtin/remote.c +msgid "(no URL)" +msgstr "(sense URL)" + +#: builtin/remote.c #, c-format msgid " HEAD branch: %s" msgstr " Branca de HEAD: %s" +#: builtin/remote.c msgid "(not queried)" msgstr "(no consultat)" +#: builtin/remote.c msgid "(unknown)" msgstr "(desconegut)" +#: builtin/remote.c #, c-format msgid "" " HEAD branch (remote HEAD is ambiguous, may be one of the following):\n" msgstr "" " Branca de HEAD (la HEAD remot és ambigua, pot ser un dels següents):\n" +#: builtin/remote.c #, c-format msgid " Remote branch:%s" msgid_plural " Remote branches:%s" msgstr[0] " Branca remota:%s" msgstr[1] " Branques remotes:%s" +#: builtin/remote.c msgid " (status not queried)" msgstr " (estat no consultat)" +#: builtin/remote.c msgid " Local branch configured for 'git pull':" msgid_plural " Local branches configured for 'git pull':" msgstr[0] " Branca local configurada per a «git pull»:" msgstr[1] " Branques locals configurades per a «git pull»:" +#: builtin/remote.c msgid " Local refs will be mirrored by 'git push'" msgstr " «git push» reflectirà les referències locals" +#: builtin/remote.c #, c-format msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Referència local configurada per a «git push»%s:" msgstr[1] " Referències locals configurades per a «git push»%s:" +#: builtin/remote.c msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "estableix refs/remotes/<nom>/HEAD segons el remot" +#: builtin/remote.c msgid "delete refs/remotes/<name>/HEAD" msgstr "suprimeix refs/remotes/<nom>/HEAD" +#: builtin/remote.c msgid "Cannot determine remote HEAD" msgstr "No es pot determinar la HEAD remota" +#: builtin/remote.c msgid "Multiple remote HEAD branches. Please choose one explicitly with:" msgstr "Múltiples branques de HEAD remotes. Trieu-ne una explícitament amb:" +#: builtin/remote.c #, c-format msgid "Could not delete %s" msgstr "No s'ha pogut suprimir %s" +#: builtin/remote.c #, c-format msgid "Not a valid ref: %s" msgstr "No és una referència vàlida: %s" +#: builtin/remote.c #, c-format msgid "Could not setup %s" msgstr "No s'ha pogut configurar %s" +#: builtin/remote.c #, c-format msgid " %s will become dangling!" -msgstr " %s es tornarà penjant!" +msgstr " %s es quedara despenjat!" +#: builtin/remote.c #, c-format msgid " %s has become dangling!" -msgstr " %s s'ha tornat penjant!" +msgstr " %s s'ha quedat despenjat!" +#: builtin/remote.c #, c-format msgid "Pruning %s" msgstr "S'està podant %s" +#: builtin/remote.c #, c-format msgid "URL: %s" msgstr "URL: %s" +#: builtin/remote.c #, c-format msgid " * [would prune] %s" msgstr " * [podaria] %s" +#: builtin/remote.c #, c-format msgid " * [pruned] %s" msgstr " * [podat] %s" +#: builtin/remote.c msgid "prune remotes after fetching" msgstr "poda els remots després d'obtenir-los" +#: builtin/remote.c #, c-format msgid "No such remote '%s'" msgstr "No hi ha tal remot «%s»" +#: builtin/remote.c msgid "add branch" msgstr "afegeix branca" +#: builtin/remote.c msgid "no remote specified" msgstr "cap remot especificat" +#: builtin/remote.c msgid "query push URLs rather than fetch URLs" msgstr "consulta els URL de pujada en lloc dels URL d'obtenció" +#: builtin/remote.c msgid "return all URLs" msgstr "retorna tots els URL" -#, c-format -msgid "no URLs configured for remote '%s'" -msgstr "cap URL configurat per al remot «%s»" - +#: builtin/remote.c msgid "manipulate push URLs" msgstr "manipula els URL de pujada" +#: builtin/remote.c msgid "add URL" msgstr "afegeix URL" +#: builtin/remote.c msgid "delete URLs" msgstr "suprimeix els URL" +#: builtin/remote.c msgid "--add --delete doesn't make sense" msgstr "--add --delete no té sentit" +#: builtin/remote.c #, c-format msgid "Invalid old URL pattern: %s" msgstr "Patró d'URL antic no vàlid: %s" +#: builtin/remote.c #, c-format msgid "No such URL found: %s" msgstr "No s'ha trobat tal URL: %s" +#: builtin/remote.c msgid "Will not delete all non-push URLs" msgstr "No se suprimiran tots els URL no de pujada" +#: builtin/remote.c msgid "be verbose; must be placed before a subcommand" msgstr "sigues detallat; s'ha de col·locar abans d'una subordre" +#: builtin/repack.c msgid "git repack [<options>]" msgstr "git repack [<opcions>]" +#: builtin/repack.c msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" "--no-write-bitmap-index or disable the pack.writeBitmaps configuration." @@ -11106,173 +14173,225 @@ msgstr "" "--no-write-bitmap-index o inhabiliteu el paràmetre de configuració pack." "writeBitmaps." +#: builtin/repack.c msgid "could not start pack-objects to repack promisor objects" msgstr "" "no s'ha pogut iniciar pack-objects per a tornar a empaquetar els objectes " "«promisor»" +#: builtin/repack.c +msgid "failed to feed promisor objects to pack-objects" +msgstr "no s'ha pogut alimentar pack-objects amb objectes «promisor»" + +#: builtin/repack.c msgid "repack: Expecting full hex object ID lines only from pack-objects." msgstr "" "repack: s'esperen només línies amb l'id d'objecte hexadecimal complet des de " "pack-objects." +#: builtin/repack.c msgid "could not finish pack-objects to repack promisor objects" msgstr "" "no s'ha pogut finalitzar pack-objects per a tornar a empaquetar els objectes " "«promisor»" +#: builtin/repack.c #, c-format msgid "cannot open index for %s" msgstr "no s'ha pogut obrir l'índex per a %s" +#: builtin/repack.c #, c-format msgid "pack %s too large to consider in geometric progression" msgstr "" "el paquet %s és massa gran per a considerar-ho en progressió geomètrica" +#: builtin/repack.c #, c-format msgid "pack %s too large to roll up" msgstr "el paquet %s és massa gran per a enrotllar-lo" +#: builtin/repack.c #, c-format msgid "could not open tempfile %s for writing" msgstr "no s'ha pogut obrir el fitxer temporal «%s» per a escriptura" +#: builtin/repack.c msgid "could not close refs snapshot tempfile" msgstr "" "no s'ha pogut tancar el fitxer temporal amb la instantània de referències" +#: builtin/repack.c #, c-format msgid "could not remove stale bitmap: %s" msgstr "no s'ha pogut eliminar el mapa de bits estancat: %s" +#: builtin/repack.c #, c-format msgid "pack prefix %s does not begin with objdir %s" msgstr "el prefix de paquet %s no comença amb objdir %s" +#: builtin/repack.c msgid "pack everything in a single pack" msgstr "empaqueta-ho tot en un únic paquet" +#: builtin/repack.c msgid "same as -a, and turn unreachable objects loose" msgstr "el mateix que -a, i solta els objectes inabastables" +#: builtin/repack.c msgid "same as -a, pack unreachable cruft objects separately" msgstr "" "el mateix que -a, empaqueta els objectes superflus inabastables de forma " "separada" +#: builtin/repack.c msgid "approxidate" msgstr "data aproximada" +#: builtin/repack.c msgid "with --cruft, expire objects older than this" msgstr "amb --cruft, vencen els objectes més antics que aquest" +#: builtin/repack.c msgid "remove redundant packs, and run git-prune-packed" msgstr "elimina els paquets redundants, i executeu git-prune-packed" +#: builtin/repack.c msgid "pass --no-reuse-delta to git-pack-objects" msgstr "passa --no-reuse-delta a git-pack-objects" +#: builtin/repack.c msgid "pass --no-reuse-object to git-pack-objects" msgstr "passa --no-reuse-object a git-pack-objects" +#: builtin/repack.c msgid "do not run git-update-server-info" msgstr "no executis git-update-server-info" +#: builtin/repack.c msgid "pass --local to git-pack-objects" msgstr "passa --local a git-pack-objects" +#: builtin/repack.c msgid "write bitmap index" msgstr "escriu índex de mapa de bits" +#: builtin/repack.c msgid "pass --delta-islands to git-pack-objects" msgstr "passa --delta-islands a git-pack-objects" +#: builtin/repack.c msgid "with -A, do not loosen objects older than this" msgstr "amb -A, no soltis els objectes més antics que aquest" +#: builtin/repack.c msgid "with -a, repack unreachable objects" msgstr "amb -a, reempaqueta els objectes inabastables" +#: builtin/repack.c msgid "size of the window used for delta compression" msgstr "mida de la finestra que s'usa per a compressió de diferències" +#: builtin/repack.c msgid "bytes" msgstr "octets" +#: builtin/repack.c msgid "same as the above, but limit memory size instead of entries count" msgstr "" "el mateix que l'anterior, però limita la mida de memòria en lloc del nombre " "d'entrades" +#: builtin/repack.c msgid "limits the maximum delta depth" msgstr "limita la profunditat màxima de les diferències" +#: builtin/repack.c msgid "limits the maximum number of threads" msgstr "limita el nombre màxim de fils" +#: builtin/repack.c msgid "maximum size of each packfile" msgstr "mida màxima de cada fitxer de paquet" +#: builtin/repack.c msgid "repack objects in packs marked with .keep" msgstr "reempaqueta els objectes en paquets marcats amb .keep" +#: builtin/repack.c msgid "do not repack this pack" msgstr "no reempaquetis aquest paquet" +#: builtin/repack.c msgid "find a geometric progression with factor <N>" msgstr "troba una progressió geomètrica amb el factor <N>" +#: builtin/repack.c msgid "write a multi-pack index of the resulting packs" msgstr "escriu un índex multipaquet dels paquets resultants" +#: builtin/repack.c msgid "pack prefix to store a pack containing pruned objects" msgstr "" "prefix del paquet per a emmagatzemar un paquet que contingui objectes podats" +#: builtin/repack.c msgid "pack prefix to store a pack containing filtered out objects" msgstr "" "prefix del paquet per a emmagatzemar un paquet que contingui objectes " "filtrats" +#: builtin/repack.c msgid "cannot delete packs in a precious-objects repo" msgstr "no es poden suprimir paquets en un repositori d'objectes preciosos" +#: builtin/repack.c #, c-format msgid "option '%s' can only be used along with '%s'" msgstr "l'opció «%s» només es pot utilitzar juntament amb «%s»" +#: builtin/repack.c msgid "Nothing new to pack." msgstr "Res nou a empaquetar." +#: builtin/repack.c #, c-format msgid "renaming pack to '%s' failed" msgstr "el canvi del nom a «%s» ha fallat" +#: builtin/repack.c #, c-format msgid "pack-objects did not write a '%s' file for pack %s-%s" msgstr "" "els objectes de paquet no han escrit a un fitxer «%s» per al paquet %s-%s" +#: builtin/repack.c sequencer.c #, c-format msgid "could not unlink: %s" msgstr "no s'ha pogut desenllaçar: «%s»" +#: builtin/replace.c msgid "git replace [-f] <object> <replacement>" msgstr "git replace [-f] <objecte> <reemplaçament>" +#: builtin/replace.c msgid "git replace [-f] --edit <object>" msgstr "git replace [-f] --edit <objecte>" +#: builtin/replace.c msgid "git replace [-f] --graft <commit> [<parent>...]" msgstr "git replace [-f] --graft <comissió> [<pare>...]" +#: builtin/replace.c msgid "git replace -d <object>..." msgstr "git replace -d <objecte>..." +#: builtin/replace.c msgid "git replace [--format=<format>] [-l [<pattern>]]" msgstr "git replace [--format=<format>] [-l [<patró>]]" +#: builtin/replace.c #, c-format msgid "" "invalid replace format '%s'\n" @@ -11281,22 +14400,27 @@ msgstr "" "format de reemplaçament no vàlid «%s»\n" "els formats vàlids són «short» «medium» i «long»" +#: builtin/replace.c #, c-format msgid "replace ref '%s' not found" msgstr "no s'ha trobat la referència de reemplaçament '«%s»" +#: builtin/replace.c #, c-format msgid "Deleted replace ref '%s'" msgstr "S'ha suprimit la referència «%s»" +#: builtin/replace.c #, c-format msgid "'%s' is not a valid ref name" msgstr "«%s» no és un nom de referència vàlid" +#: builtin/replace.c #, c-format msgid "replace ref '%s' already exists" msgstr "la referència de reemplaçament «%s» ja existeix" +#: builtin/replace.c #, c-format msgid "" "Objects must be of the same type.\n" @@ -11307,59 +14431,75 @@ msgstr "" "«%s» apunta a un objecte substituït del tipus «%s»\n" "mentre que «%s» apunta a un objecte de substitució del tipus «%s»." +#: builtin/replace.c #, c-format msgid "unable to open %s for writing" msgstr "no s'ha pogut obrir %s per a escriptura" +#: builtin/replace.c msgid "cat-file reported failure" msgstr "cat-file ha informat d'un error" +#: builtin/replace.c #, c-format msgid "unable to open %s for reading" msgstr "no s'ha pogut obrir %s per a lectura" +#: builtin/replace.c msgid "unable to spawn mktree" msgstr "no s'ha pogut engendrar el mktree" +#: builtin/replace.c msgid "unable to read from mktree" msgstr "no s'ha pogut llegir des de mktree" +#: builtin/replace.c msgid "mktree reported failure" msgstr "mktree ha informat d'una fallada" +#: builtin/replace.c msgid "mktree did not return an object name" msgstr "mktree no ha retornat un nom d'objecte" +#: builtin/replace.c #, c-format msgid "unable to fstat %s" msgstr "no s'ha pogut fer fstat %s" +#: builtin/replace.c msgid "unable to write object to database" msgstr "no s'ha pogut escriure l'objecte a la base de dades" +#: builtin/replace.c #, c-format msgid "unable to get object type for %s" msgstr "no s'ha pogut obtenir el tipus d'objecte per a %s" +#: builtin/replace.c msgid "editing object file failed" msgstr "l'edició del fitxer d'objecte ha fallat" +#: builtin/replace.c #, c-format msgid "new object is the same as the old one: '%s'" msgstr "l'objecte nou és el mateix que l'antic: «%s»" +#: builtin/replace.c #, c-format msgid "could not parse %s as a commit" msgstr "no s'ha pogut analitzar %s com a comissió" +#: builtin/replace.c #, c-format msgid "bad mergetag in commit '%s'" msgstr "etiqueta de fusió incorrecta en la comissió «%s»" +#: builtin/replace.c #, c-format msgid "malformed mergetag in commit '%s'" msgstr "etiqueta de fusió mal formada en la comissió «%s»" +#: builtin/replace.c #, c-format msgid "" "original commit '%s' contains mergetag '%s' that is discarded; use --edit " @@ -11368,25 +14508,31 @@ msgstr "" "la comissió original «%s» conté l'etiqueta de fusió «%s» que es descarta; " "useu --edit en lloc de --graft" +#: builtin/replace.c #, c-format msgid "the original commit '%s' has a gpg signature" msgstr "la comissió original «%s» té una signatura gpg" +#: builtin/replace.c msgid "the signature will be removed in the replacement commit!" msgstr "s'eliminarà la signatura en la comissió de reemplaçament!" +#: builtin/replace.c #, c-format msgid "could not write replacement commit for: '%s'" msgstr "no s'ha pogut escriure la comissió de reemplaçament per a: «%s»" +#: builtin/replace.c #, c-format msgid "graft for '%s' unnecessary" msgstr "«graft» per a «%s» innecessari" +#: builtin/replace.c #, c-format msgid "new commit is the same as the old one: '%s'" msgstr "la comissió nova és la mateixa que l'antiga: «%s»" +#: builtin/replace.c #, c-format msgid "" "could not convert the following graft(s):\n" @@ -11395,69 +14541,91 @@ msgstr "" "no s'han pogut convertir els següents «grafts»:\n" "%s" +#: builtin/replace.c msgid "list replace refs" msgstr "llista les referències de reemplaçament" +#: builtin/replace.c msgid "delete replace refs" msgstr "suprimeix les referències de reemplaçament" +#: builtin/replace.c msgid "edit existing object" msgstr "edita un objecte existent" +#: builtin/replace.c msgid "change a commit's parents" msgstr "canvia els pares d'una comissió" +#: builtin/replace.c msgid "convert existing graft file" msgstr "converteix el fitxer «graft» existent" +#: builtin/replace.c msgid "replace the ref if it exists" msgstr "reemplaça la referència si existeix" +#: builtin/replace.c msgid "do not pretty-print contents for --edit" msgstr "no imprimeixis bellament els continguts per a --edit" +#: builtin/replace.c msgid "use this format" msgstr "usa aquest format" +#: builtin/replace.c msgid "--format cannot be used when not listing" msgstr "no es pot utilitzar «--format» quan no s'està llistant" +#: builtin/replace.c msgid "-f only makes sense when writing a replacement" msgstr "-f només té sentit quan s'escriu un reemplaçament" +#: builtin/replace.c msgid "--raw only makes sense with --edit" msgstr "--raw només té sentit amb --edit" +#: builtin/replace.c msgid "-d needs at least one argument" msgstr "-d necessita almenys un argument" +#: builtin/replace.c msgid "bad number of arguments" msgstr "nombre incorrecte d'arguments" +#: builtin/replace.c msgid "-e needs exactly one argument" msgstr "-e necessita exactament un argument" +#: builtin/replace.c msgid "-g needs at least one argument" msgstr "-g necessita almenys un argument" +#: builtin/replace.c msgid "--convert-graft-file takes no argument" msgstr "--convert-graft-file arguments" +#: builtin/replace.c msgid "only one pattern can be given with -l" msgstr "només es pot especificar un patró amb -l" +#: builtin/replay.c msgid "need some commits to replay" msgstr "calen algunes comissions per tornar a reproduir" +#: builtin/replay.c msgid "--onto and --advance are incompatible" msgstr "--onto i --advance són incompatibles" +#: builtin/replay.c msgid "all positive revisions given must be references" msgstr "totes les revisions positives que s'han donat han de ser referències" +#: builtin/replay.c msgid "argument to --advance must be a reference" msgstr "l'argument per a --advance ha de ser una referència" +#: builtin/replay.c msgid "" "cannot advance target with multiple sources because ordering would be ill-" "defined" @@ -11465,12 +14633,14 @@ msgstr "" "no es pot avançar l'objectiu amb múltiples fonts perquè l'ordenació no " "estaria definida correctament" +#: builtin/replay.c 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" +#: builtin/replay.c msgid "" "cannot advance target with multiple source branches because ordering would " "be ill-defined" @@ -11478,9 +14648,11 @@ msgstr "" "no es pot avançar l'objectiu amb múltiples branques d'origen perquè " "l'ordenació no estaria definida correctament" +#: builtin/replay.c msgid "cannot implicitly determine correct base for --onto" msgstr "no es pot determinar implícitament la base correcta per a --onto" +#: builtin/replay.c msgid "" "(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " "<branch>) <revision-range>..." @@ -11488,18 +14660,23 @@ msgstr "" "(EXPERIMENTAL!) git replay ([--contained] --onto <newbase> | --advance " "<branch>) <revision-range>..." +#: builtin/replay.c msgid "make replay advance given branch" msgstr "fes avançar la repetició de la branca donada" +#: builtin/replay.c msgid "replay onto given commit" msgstr "torna a reproduir a la comissió donada" +#: builtin/replay.c msgid "advance all branches contained in revision-range" msgstr "avança totes les branques contingudes a l'interval de revisions" +#: builtin/replay.c msgid "option --onto or --advance is mandatory" msgstr "l'opció --onto o --advance és obligatòria" +#: builtin/replay.c #, c-format msgid "" "some rev walking options will be overridden as '%s' bit in 'struct rev_info' " @@ -11508,124 +14685,159 @@ msgstr "" "algunes opcions de referència se sobreescriuran de forma forçada com a «%s» " "bits a «struct rev_info»" +#: builtin/replay.c msgid "error preparing revisions" msgstr "s'ha produït un error en preparar les revisions" +#: builtin/replay.c msgid "replaying down to root commit is not supported yet!" msgstr "encara no s'admet la reproducció cap avall en una comissió arrel" +#: builtin/replay.c msgid "replaying merge commits is not supported yet!" -msgstr "encara no s'admet la repetició de les comissió de fusió" +msgstr "encara no s'admet la repetició de les comissions de fusió" +#: builtin/rerere.c msgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" msgstr "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" +#: builtin/rerere.c msgid "register clean resolutions in index" msgstr "registra les resolucions netes en l'índex" +#: builtin/rerere.c msgid "'git rerere forget' without paths is deprecated" msgstr "«git rerere forget» sense camins està en desús" +#: builtin/rerere.c #, c-format msgid "unable to generate diff for '%s'" msgstr "no s'ha pogut generar el diff per a «%s»" +#: builtin/reset.c msgid "" "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" msgstr "" "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<comissió>]" +#: builtin/reset.c msgid "git reset [-q] [<tree-ish>] [--] <pathspec>..." msgstr "git reset [-q] [<tree-ish>] [--] <pathspec>..." +#: builtin/reset.c msgid "" "git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]" msgstr "" "git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]" +#: builtin/reset.c msgid "git reset --patch [<tree-ish>] [--] [<pathspec>...]" msgstr "git reset --patch [<tree-ish>] [--] [<pathspec>...]" +#: builtin/reset.c msgid "mixed" msgstr "mixt" +#: builtin/reset.c msgid "soft" msgstr "suau" +#: builtin/reset.c msgid "hard" msgstr "dur" +#: builtin/reset.c msgid "merge" msgstr "fusió" +#: builtin/reset.c msgid "keep" msgstr "reteniment" +#: builtin/reset.c msgid "You do not have a valid HEAD." msgstr "No teniu una HEAD vàlida." +#: builtin/reset.c msgid "Failed to find tree of HEAD." msgstr "S'ha produït un error en trobar l'arbre de HEAD." +#: builtin/reset.c #, c-format msgid "Failed to find tree of %s." msgstr "S'ha produït un error en cercar l'arbre de %s." +#: builtin/reset.c #, c-format msgid "HEAD is now at %s" msgstr "HEAD ara és a %s" +#: builtin/reset.c #, c-format msgid "Cannot do a %s reset in the middle of a merge." msgstr "No es pot fer un restabliment de %s enmig d'una fusió." +#: builtin/reset.c builtin/stash.c msgid "be quiet, only report errors" msgstr "sigues silenciós, només informa d'errors" +#: builtin/reset.c msgid "skip refreshing the index after reset" msgstr "omet l'actualització de l'índex després de reiniciar" +#: builtin/reset.c msgid "reset HEAD and index" msgstr "restableix HEAD i l'índex" +#: builtin/reset.c msgid "reset only HEAD" msgstr "restableix només HEAD" +#: builtin/reset.c msgid "reset HEAD, index and working tree" msgstr "restableix HEAD, l'índex i l'arbre de treball" +#: builtin/reset.c msgid "reset HEAD but keep local changes" msgstr "restableix HEAD però retén els canvis locals" +#: builtin/reset.c msgid "record only the fact that removed paths will be added later" msgstr "registra només el fet que els camins eliminats s'afegiran després" +#: builtin/reset.c #, c-format msgid "Failed to resolve '%s' as a valid revision." msgstr "S'ha produït un error en resoldre «%s» com a revisió vàlida." +#: builtin/reset.c #, c-format msgid "Failed to resolve '%s' as a valid tree." msgstr "S'ha produït un error en resoldre «%s» com a arbre vàlid." +#: builtin/reset.c msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead." msgstr "" "--mixed amb camins està en desús; useu «git reset -- <camins>» en lloc " "d'això." +#: builtin/reset.c #, c-format msgid "Cannot do %s reset with paths." msgstr "No es pot restablir de %s amb camins." +#: builtin/reset.c #, c-format msgid "%s reset is not allowed in a bare repository" msgstr "el restabliment de %s no es permet en un repositori nu" +#: builtin/reset.c msgid "Unstaged changes after reset:" msgstr "Canvis «unstaged» després del restabliment:" +#: builtin/reset.c #, c-format msgid "" "It took %.2f seconds to refresh the index after reset. You can use\n" @@ -11635,52 +14847,67 @@ msgstr "" "usar\n" ".--no-refresh' per a evitar això." +#: builtin/reset.c #, c-format msgid "Could not reset index file to revision '%s'." msgstr "No s'ha pogut restablir el fitxer d'índex a la revisió «%s»." +#: builtin/reset.c msgid "Could not write new index file." msgstr "No s'ha pogut escriure el fitxer d'índex nou." +#: builtin/rev-list.c #, c-format msgid "unable to get disk usage of %s" msgstr "no s'ha pogut obtenir l'ús del disc de %s" +#: builtin/rev-list.c #, c-format msgid "invalid value for '%s': '%s', the only allowed format is '%s'" msgstr "valor no vàlid per a «%s»: «%s», l'únic format permès és «%s»" +#: builtin/rev-list.c msgid "rev-list does not support display of notes" msgstr "el rev-list no permet mostrar notes" +#: builtin/rev-list.c #, c-format msgid "marked counting and '%s' cannot be used together" msgstr "«marked counting» i «%s» no es poden usar junts" +#: builtin/rev-parse.c msgid "git rev-parse --parseopt [<options>] -- [<args>...]" msgstr "git rev-parse --parseopt [<opcions>] -- [<arguments>...]" +#: builtin/rev-parse.c msgid "keep the `--` passed as an arg" msgstr "retén el «--» passat com a argument" +#: builtin/rev-parse.c msgid "stop parsing after the first non-option argument" msgstr "deixa d'analitzar després del primer argument que no sigui d'opció" +#: builtin/rev-parse.c msgid "output in stuck long form" msgstr "emet en forma llarga enganxada" +#: builtin/rev-parse.c msgid "premature end of input" msgstr "final prematur de l'entrada" +#: builtin/rev-parse.c msgid "no usage string given before the `--' separator" msgstr "no s'ha indicat cap cadena d'ús abans del separador «--»" +#: builtin/rev-parse.c msgid "missing opt-spec before option flags" msgstr "manca l'opció opt-spec abans de les altres opcions" +#: builtin/rev-parse.c msgid "Needed a single revision" msgstr "Cal una sola revisió" +#: builtin/rev-parse.c msgid "" "git rev-parse --parseopt [<options>] -- [<args>...]\n" " or: git rev-parse --sq-quote [<arg>...]\n" @@ -11695,46 +14922,68 @@ msgstr "" "Executeu «git rev-parse --parseopt -h» per a més informació sobre el primer " "ús." +#: builtin/rev-parse.c msgid "--resolve-git-dir requires an argument" msgstr "--resolve-git-dir requereix un argument" +#: builtin/rev-parse.c #, c-format msgid "not a gitdir '%s'" msgstr "no és un directori git «%s»" +#: builtin/rev-parse.c msgid "--git-path requires an argument" msgstr "--git-path requereix un argument" +#: builtin/rev-parse.c msgid "-n requires an argument" msgstr "-n requereix un argument" +#: builtin/rev-parse.c msgid "--path-format requires an argument" msgstr "--path-format requereix un argument" +#: builtin/rev-parse.c #, c-format msgid "unknown argument to --path-format: %s" msgstr "argument no vàlid per a --path-format: %s" +#: builtin/rev-parse.c msgid "--default requires an argument" msgstr "--default requereix un argument" +#: builtin/rev-parse.c msgid "--prefix requires an argument" msgstr "--prefix requereix un argument" +#: builtin/rev-parse.c +msgid "no object format specified" +msgstr "no s'ha especificat cap format d'objecte" + +#: builtin/rev-parse.c +#, c-format +msgid "unsupported object format: %s" +msgstr "format d'objecte no compatible: %s" + +#: builtin/rev-parse.c #, c-format msgid "unknown mode for --abbrev-ref: %s" msgstr "mode desconegut per a --abbrev-ref: %s" +#: builtin/rev-parse.c setup.c msgid "this operation must be run in a work tree" msgstr "aquesta operació s'ha d'executar en un arbre de treball" +#: builtin/rev-parse.c msgid "Could not read the index" msgstr "No s'ha pogut llegir l'índex" +#: builtin/rev-parse.c #, c-format msgid "unknown mode for --show-object-format: %s" msgstr "mode desconegut per a --show-object-format: %s" +#: builtin/revert.c msgid "" "git revert [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] " "<commit>..." @@ -11742,9 +14991,11 @@ msgstr "" "git revert [--[no-]edit] [-n] [-m <parent-number>] [-s] [-S[<keyid>]] " "<comissió>..." +#: builtin/revert.c msgid "git revert (--continue | --skip | --abort | --quit)" msgstr "git revert (--continue | --skip | --abort | --quit)" +#: builtin/revert.c msgid "" "git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n" " [-S[<keyid>]] <commit>..." @@ -11752,68 +15003,89 @@ msgstr "" "git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff]\n" " [-S[<keyid>]] <comissió>..." +#: builtin/revert.c msgid "git cherry-pick (--continue | --skip | --abort | --quit)" msgstr "git cherry-pick (--continue | --skip | --abort | --quit)" +#: builtin/revert.c #, c-format msgid "option `%s' expects a number greater than zero" msgstr "l'opció «%s» espera un nombre major que zero" +#: builtin/revert.c #, c-format msgid "%s: %s cannot be used with %s" msgstr "%s: %s no es pot usar amb %s" +#: builtin/revert.c msgid "end revert or cherry-pick sequence" msgstr "acaba la seqüència de reversió o el «cherry pick»" +#: builtin/revert.c msgid "resume revert or cherry-pick sequence" msgstr "reprèn la seqüència de reversió o el «cherry pick»" +#: builtin/revert.c msgid "cancel revert or cherry-pick sequence" msgstr "cancel·la la seqüència de reversió o el «cherry pick»" +#: builtin/revert.c msgid "skip current commit and continue" msgstr "omet la comissió actual i continua" +#: builtin/revert.c msgid "don't automatically commit" msgstr "no cometis automàticament" +#: builtin/revert.c msgid "edit the commit message" msgstr "edita el missatge de comissió" +#: builtin/revert.c msgid "parent-number" msgstr "número del pare" +#: builtin/revert.c msgid "select mainline parent" msgstr "selecciona la línia principal del pare" +#: builtin/revert.c msgid "merge strategy" msgstr "estratègia de fusió" +#: builtin/revert.c msgid "option for merge strategy" msgstr "opció d'estratègia de fusió" +#: builtin/revert.c msgid "append commit name" msgstr "nom de la comissió a annexar" +#: builtin/revert.c msgid "preserve initially empty commits" msgstr "conserva les comissions inicialment buides" +#: builtin/revert.c msgid "allow commits with empty messages" msgstr "permet les comissions amb missatges buits" -msgid "keep redundant, empty commits" -msgstr "retén les comissions redundants i buides" +#: builtin/revert.c +msgid "deprecated: use --empty=keep instead" +msgstr "obsolet: utilitzeu --empty=keep en el seu lloc" +#: builtin/revert.c msgid "use the 'reference' format to refer to commits" msgstr "useu el format «referència» per a referir-vos a les comissions" +#: builtin/revert.c msgid "revert failed" msgstr "la reversió ha fallat" +#: builtin/revert.c msgid "cherry-pick failed" msgstr "el «cherry pick» ha fallat" +#: builtin/rm.c msgid "" "git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]\n" " [--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" @@ -11823,6 +15095,7 @@ msgstr "" " [--quiet] [--pathspec-from-file=<fitxer> [--pathspec-file-nul]]\n" " [--] [<pathspec>...]" +#: builtin/rm.c msgid "" "the following file has staged content different from both the\n" "file and the HEAD:" @@ -11830,12 +15103,13 @@ msgid_plural "" "the following files have staged content different from both the\n" "file and the HEAD:" msgstr[0] "" -"el fitxer següent té contingut «staged» diferent al fitxer\n" -"i a HEAD:" +"el fitxer següent té contingut «staged» diferent del fitxer\n" +"i de HEAD:" msgstr[1] "" "els fitxers següents tenen contingut «staged» diferent al fitxer\n" "i a HEAD:" +#: builtin/rm.c msgid "" "\n" "(use -f to force removal)" @@ -11843,11 +15117,13 @@ msgstr "" "\n" "(useu -f per a forçar l'eliminació)" +#: builtin/rm.c msgid "the following file has changes staged in the index:" msgid_plural "the following files have changes staged in the index:" msgstr[0] "el fitxer següent té canvis «staged» en l'índex:" msgstr[1] "els fitxers següents tenen canvis «staged» en l'índex:" +#: builtin/rm.c msgid "" "\n" "(use --cached to keep the file, or -f to force removal)" @@ -11855,42 +15131,53 @@ msgstr "" "\n" "(useu --cached per a mantenir el fitxer, o -f per a forçar l'eliminació)" +#: builtin/rm.c msgid "the following file has local modifications:" msgid_plural "the following files have local modifications:" msgstr[0] "el fitxer següent té modificacions locals:" msgstr[1] "els fitxers següents tenen modificacions locals:" +#: builtin/rm.c msgid "do not list removed files" msgstr "no llistis els fitxers eliminats" +#: builtin/rm.c msgid "only remove from the index" msgstr "només elimina de l'índex" +#: builtin/rm.c msgid "override the up-to-date check" msgstr "passa per alt la comprovació d'actualitat" +#: builtin/rm.c msgid "allow recursive removal" msgstr "permet l'eliminació recursiva" +#: builtin/rm.c msgid "exit with a zero status even if nothing matched" msgstr "surt amb estat zero encara que res hagi coincidit" +#: builtin/rm.c msgid "No pathspec was given. Which files should I remove?" msgstr "" "No s'ha indicat cap especificació de camí. Quins fitxers s'han de suprimir?" +#: builtin/rm.c msgid "please stage your changes to .gitmodules or stash them to proceed" msgstr "" "feu un «stage» dels canvis a .gitmodules o feu un «stash» per a continuar" +#: builtin/rm.c #, c-format msgid "not removing '%s' recursively without -r" msgstr "no s'eliminarà «%s» recursivament sense -r" +#: builtin/rm.c #, c-format msgid "git rm: unable to remove %s" msgstr "git rm: no s'ha pogut eliminar %s" +#: builtin/send-pack.c msgid "" "git send-pack [--mirror] [--dry-run] [--force]\n" " [--receive-pack=<git-receive-pack>]\n" @@ -11902,69 +15189,89 @@ msgstr "" " [--receive-pack=<git-receive-pack>]\n" " [--verbose] [--thin] [--atomic]\n" " [--[no-]signed | --signed=(true|false|if-asked)]\n" -" [<host>:]<directory> (--all | <ref>...)" +" [<host>:]<directori> (--all | <referència>...)" +#: builtin/send-pack.c msgid "remote name" msgstr "nom del remot" +#: builtin/send-pack.c msgid "push all refs" msgstr "puja totes les referències" +#: builtin/send-pack.c msgid "use stateless RPC protocol" msgstr "usa el protocol RPC sense estat" +#: builtin/send-pack.c msgid "read refs from stdin" msgstr "llegeix les referències des de stdin" +#: builtin/send-pack.c msgid "print status from remote helper" msgstr "imprimeix l'estat des de l'ajudant remot" +#: builtin/shortlog.c msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]" msgstr "git shortlog [<opcions>] [<rang-de-revisions>] [[--] <camí>...]" +#: builtin/shortlog.c msgid "git log --pretty=short | git shortlog [<options>]" msgstr "git log --pretty=short | git shortlog [<opcions>]" +#: builtin/shortlog.c msgid "using multiple --group options with stdin is not supported" msgstr "no s'admet l'ús de múltiples opcions --group amb stdin" +#: builtin/shortlog.c #, c-format msgid "using %s with stdin is not supported" msgstr "no s'admet l'ús de %s amb stdin" +#: builtin/shortlog.c #, c-format msgid "unknown group type: %s" msgstr "tipus de grup desconegut: %s" +#: builtin/shortlog.c msgid "group by committer rather than author" msgstr "agrupa per «committer» en comptes de per autor" +#: builtin/shortlog.c msgid "sort output according to the number of commits per author" msgstr "ordena la sortida segons el nombre de comissions per autor" +#: builtin/shortlog.c msgid "suppress commit descriptions, only provides commit count" msgstr "" "omet les descripcions de les comissions, només proveeix el recompte de " "comissions" +#: builtin/shortlog.c msgid "show the email address of each author" msgstr "mostra l'adreça electrònica de cada autor" +#: builtin/shortlog.c msgid "<w>[,<i1>[,<i2>]]" msgstr "<w>[,<i1>[,<i2>]]" +#: builtin/shortlog.c msgid "linewrap output" msgstr "ajusta les línies de la sortida" +#: builtin/shortlog.c msgid "field" msgstr "camp" +#: builtin/shortlog.c msgid "group by field" msgstr "agrupa per camp" +#: builtin/shortlog.c msgid "too many arguments given outside repository" msgstr "hi ha massa arguments donats fora del repositori" +#: builtin/show-branch.c msgid "" "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n" " [--current] [--color[=<when>] | --no-color] [--sparse]\n" @@ -11976,114 +15283,144 @@ msgstr "" " [--current] [--color[=<when>] | --no-color] [--sparse]\n" " [--more=<n> | --list | --independent | --merge-base]\n" " [--no-name | --sha1-name] [--topics]\n" -" [(<rev> | <glob>)...]" +" [(<revisió> | <glob>)...]" +#: builtin/show-branch.c msgid "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]" msgstr "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<referència>]" +#: builtin/show-branch.c #, c-format msgid "ignoring %s; cannot handle more than %d ref" msgid_plural "ignoring %s; cannot handle more than %d refs" msgstr[0] "s'està ignorant %s; no es pot gestionar més de %d referència" msgstr[1] "s'està ignorant %s; no es poden gestionar més de %d referències" +#: builtin/show-branch.c #, c-format msgid "no matching refs with %s" msgstr "no hi ha referències coincidents amb %s" +#: builtin/show-branch.c msgid "show remote-tracking and local branches" msgstr "mostra les branques amb seguiment remot i les locals" +#: builtin/show-branch.c msgid "show remote-tracking branches" msgstr "mostra les branques amb seguiment remot" +#: builtin/show-branch.c msgid "color '*!+-' corresponding to the branch" msgstr "colora «*!+-» corresponent a la branca" +#: builtin/show-branch.c msgid "show <n> more commits after the common ancestor" msgstr "mostra <n> comissions després de l'avantpassat comú" +#: builtin/show-branch.c msgid "synonym to more=-1" msgstr "sinònim de more=-1" +#: builtin/show-branch.c msgid "suppress naming strings" msgstr "omet anomenar cadenes" +#: builtin/show-branch.c msgid "include the current branch" msgstr "inclou la branca actual" +#: builtin/show-branch.c msgid "name commits with their object names" msgstr "anomena les comissions amb els seus noms d'objecte" +#: builtin/show-branch.c msgid "show possible merge bases" msgstr "mostra les bases de fusió possibles" +#: builtin/show-branch.c msgid "show refs unreachable from any other ref" msgstr "mostra les referències inabastables de qualsevol altra referència" +#: builtin/show-branch.c msgid "show commits in topological order" msgstr "mostra les comissions en ordre topològic" +#: builtin/show-branch.c msgid "show only commits not on the first branch" msgstr "mostra només les comissions que no siguin en la primera branca" +#: builtin/show-branch.c msgid "show merges reachable from only one tip" msgstr "mostra les fusions abastables de només una punta" +#: builtin/show-branch.c msgid "topologically sort, maintaining date order where possible" msgstr "ordena topològicament, mantenint l'ordre de dates on sigui possible" +#: builtin/show-branch.c msgid "<n>[,<base>]" msgstr "<n>[,<base>]" +#: builtin/show-branch.c msgid "show <n> most recent ref-log entries starting at base" msgstr "mostra les <n> entrades més recents començant a la base" +#: builtin/show-branch.c msgid "no branches given, and HEAD is not valid" msgstr "no s'ha donat cap branca, i HEAD no és vàlid" +#: builtin/show-branch.c msgid "--reflog option needs one branch name" msgstr "l'opció --reflog necessita un nom de branca" +#: builtin/show-branch.c #, c-format msgid "only %d entry can be shown at one time." msgid_plural "only %d entries can be shown at one time." msgstr[0] "es pot mostrar només %d entrada a la vegada." msgstr[1] "es poden mostrar només %d entrades a la vegada." +#: builtin/show-branch.c #, c-format msgid "no such ref %s" msgstr "no hi ha tal referència %s" +#: builtin/show-branch.c #, c-format msgid "cannot handle more than %d rev." msgid_plural "cannot handle more than %d revs." msgstr[0] "no es pot gestionar més d'%d revisió." msgstr[1] "no es poden gestionar més de %d revisions." +#: builtin/show-branch.c #, c-format msgid "'%s' is not a valid ref." msgstr "«%s» no és una referència vàlida." +#: builtin/show-branch.c #, c-format msgid "cannot find commit %s (%s)" msgstr "no es pot trobar la comissió %s (%s)" +#: builtin/show-index.c msgid "hash-algorithm" msgstr "algorisme de resum" +#: builtin/show-index.c msgid "Unknown hash algorithm" msgstr "Algorisme de resum desconegut" +#: builtin/show-ref.c msgid "" "git show-ref [--head] [-d | --dereference]\n" -" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" -" [--heads] [--] [<pattern>...]" +" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n" +" [--] [<pattern>...]" msgstr "" "git show-ref [--head] [-d | --dereference]\n" -" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--tags]\n" -" [--heads] [--] [<pattern>...]" +" [-s | --hash[=<n>]] [--abbrev[=<n>]] [--branches] [--tags]\n" +" [--] [<patró>...]" +#: builtin/show-ref.c msgid "" "git show-ref --verify [-q | --quiet] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" @@ -12091,49 +15428,63 @@ msgid "" msgstr "" "git show-ref --verify [-q | --quiet] [-d | --dereference]\n" " [-s | --hash[=<n>]] [--abbrev[=<n>]]\n" -" [--] [<ref>...]" +" [--] [<referència>...]" +#: builtin/show-ref.c msgid "git show-ref --exclude-existing[=<pattern>]" msgstr "git show-ref --exclude-existing[=<patró>]" +#: builtin/show-ref.c msgid "git show-ref --exists <ref>" -msgstr "git show-ref --exists <ref>" +msgstr "git show-ref --exists <referència>" +#: builtin/show-ref.c msgid "reference does not exist" msgstr "la referència no existeix" +#: builtin/show-ref.c 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)" +#: builtin/show-ref.c +msgid "only show tags (can be combined with --branches)" +msgstr "mostra només les etiquetes (es pot combinar amb --branches)" -msgid "only show heads (can be combined with tags)" -msgstr "mostra només els caps (es pot combinar amb tags)" +#: builtin/show-ref.c +msgid "only show branches (can be combined with --tags)" +msgstr "mostra només les branques (es pot combinar amb --tags)" +#: builtin/show-ref.c msgid "check for reference existence without resolving" msgstr "comprova l'existència de referència sense resoldre" +#: builtin/show-ref.c msgid "stricter reference checking, requires exact ref path" msgstr "" "comprovació de referència més estricta, requereix el camí de referència " "exacte" +#: builtin/show-ref.c msgid "show the HEAD reference, even if it would be filtered out" msgstr "mostra la referència HEAD, encara que es filtrés" +#: builtin/show-ref.c msgid "dereference tags into object IDs" msgstr "desreferencia les etiquetes a ID d'objecte" +#: builtin/show-ref.c msgid "only show SHA1 hash using <n> digits" msgstr "mostra el resum SHA1 usant només <n> xifres" +#: builtin/show-ref.c msgid "do not print results to stdout (useful with --verify)" msgstr "no imprimeixis els resultats a stdout (útil amb --verify)" +#: builtin/show-ref.c msgid "show refs from stdin that aren't in local repository" msgstr "mostra les referències de stdin que no siguin en el repositori local" +#: builtin/sparse-checkout.c msgid "" "git sparse-checkout (init | list | set | add | reapply | disable | check-" "rules) [<options>]" @@ -12141,14 +15492,17 @@ msgstr "" "git sparse-checkout (init | list | set | add | reapply | disable | check-" "rules) [<opcions>]" +#: builtin/sparse-checkout.c msgid "this worktree is not sparse" msgstr "aquest arbre de treball no és dispers" +#: builtin/sparse-checkout.c msgid "this worktree is not sparse (sparse-checkout file may not exist)" msgstr "" "aquest arbre de treball no és dispers (pot ser que el fitxer sparse-checkout " "no existeixi)" +#: builtin/sparse-checkout.c #, c-format msgid "" "directory '%s' contains untracked files, but is not in the sparse-checkout " @@ -12157,53 +15511,73 @@ msgstr "" "el directori «%s» conté fitxers no seguits, però no està en el con de sparse-" "checkout" +#: builtin/sparse-checkout.c #, c-format msgid "failed to remove directory '%s'" msgstr "s'ha produït un error en suprimir el directori «%s»" +#: builtin/sparse-checkout.c msgid "failed to create directory for sparse-checkout file" msgstr "no s'ha pogut crear el directori per al fitxer sparse-checkout" +#: builtin/sparse-checkout.c +#, c-format +msgid "unable to fdopen %s" +msgstr "no he pogut fer fdopen de «%s»" + +#: builtin/sparse-checkout.c msgid "failed to initialize worktree config" msgstr "no s'ha pogut inicialitzar la configuració de l'arbre de treball" +#: builtin/sparse-checkout.c msgid "failed to modify sparse-index config" msgstr "no s'ha pogut modificar la configuració de l'índex dispers" +#: builtin/sparse-checkout.c msgid "initialize the sparse-checkout in cone mode" msgstr "inicialitza el «sparse-checkout» en mode con" +#: builtin/sparse-checkout.c msgid "toggle the use of a sparse index" msgstr "commuta l'ús d'un índex dispers" +#: builtin/sparse-checkout.c commit-graph.c midx-write.c sequencer.c #, c-format msgid "unable to create leading directories of %s" msgstr "no s'han pogut crear els directoris inicials de «%s»" +#: builtin/sparse-checkout.c #, c-format msgid "failed to open '%s'" msgstr "s'ha produït un error en obrir «%s»" +#: builtin/sparse-checkout.c #, c-format msgid "could not normalize path %s" msgstr "no s'ha pogut normalitzar el camí %s" +#: builtin/sparse-checkout.c #, c-format msgid "unable to unquote C-style string '%s'" msgstr "no s'han pogut treure les cometes a la cadena amb estil C «%s»" +#: builtin/sparse-checkout.c msgid "unable to load existing sparse-checkout patterns" msgstr "no s'han pogut carregar els patrons de «sparse-checkout» existents" +#: builtin/sparse-checkout.c msgid "existing sparse-checkout patterns do not use cone mode" msgstr "els patrons de «sparse-checkout» existents no usen el mode con" +#: builtin/sparse-checkout.c msgid "please run from the toplevel directory in non-cone mode" msgstr "executeu des del directori de nivell superior en mode que no sigui con" +#: builtin/sparse-checkout.c msgid "specify directories rather than patterns (no leading slash)" msgstr "especifica els directoris en lloc dels patrons (sense barra inclinada)" +#: builtin/sparse-checkout.c msgid "" "specify directories rather than patterns. If your directory starts with a " "'!', pass --skip-checks" @@ -12211,6 +15585,7 @@ msgstr "" "especifica els directoris en lloc dels patrons. Si el vostre directori " "comença amb un «!», passeu --skip-checks" +#: builtin/sparse-checkout.c msgid "" "specify directories rather than patterns. If your directory really has any " "of '*?[]\\' in it, pass --skip-checks" @@ -12218,6 +15593,7 @@ msgstr "" "especifica els directoris en lloc dels patrons. Si el vostre directori " "realment té alguna de «*?[]\\», useu --skip-checks" +#: builtin/sparse-checkout.c #, c-format msgid "" "'%s' is not a directory; to treat it as a directory anyway, rerun with --" @@ -12226,6 +15602,7 @@ msgstr "" "«%s» no és un directori; per a tractar-lo com un directori, torneu a " "executar amb --skip-checks" +#: builtin/sparse-checkout.c #, c-format msgid "" "pass a leading slash before paths such as '%s' if you want a single file " @@ -12234,35 +15611,43 @@ msgstr "" "passa una barra d'inici abans dels camins com ara «%s» si voleu un sol " "fitxer (vegeu «NON-CONE PROBLEMS» al manual de git-sparse-checkout)." +#: builtin/sparse-checkout.c msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)" -msgstr "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)" +msgstr "git sparse-checkout add [--skip-checks] (--stdin | <patrons>)" +#: builtin/sparse-checkout.c msgid "" "skip some sanity checks on the given paths that might give false positives" msgstr "" "omet alguns controls de sanitat en els camins donats que podrien donar " "falsos positius" +#: builtin/sparse-checkout.c msgid "read patterns from standard in" msgstr "llegeix els patrons de l'entrada estàndard" +#: builtin/sparse-checkout.c msgid "no sparse-checkout to add to" msgstr "no hi ha un sparse-checkout a afegir" +#: builtin/sparse-checkout.c msgid "" "git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] " "(--stdin | <patterns>)" msgstr "" "git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] " -"(--stdin | <patterns>)" +"(--stdin | <patrons>)" +#: builtin/sparse-checkout.c msgid "must be in a sparse-checkout to reapply sparsity patterns" msgstr "" "ha d'estar en un sparse-checkout per a tornar a aplicar patrons de dispersió" +#: builtin/sparse-checkout.c msgid "error while refreshing working directory" msgstr "s'ha produït un error en actualitzar el directori de treball" +#: builtin/sparse-checkout.c msgid "" "git sparse-checkout check-rules [-z] [--skip-checks][--[no-]cone] [--rules-" "file <file>]" @@ -12270,20 +15655,25 @@ msgstr "" "git sparse-checkout check-rules [-z] [--skip-checks][--[no-]cone] [--rules-" "file <fitxer>]" +#: builtin/sparse-checkout.c msgid "terminate input and output files by a NUL character" msgstr "acaba els fitxers d'entrada i de sortida amb un caràcter NUL" +#: builtin/sparse-checkout.c msgid "when used with --rules-file interpret patterns as cone mode patterns" msgstr "" "quan s'utilitza amb --rules-file, interpreta els patrons com a patrons del " "mode con" +#: builtin/sparse-checkout.c msgid "use patterns in <file> instead of the current ones." msgstr "utilitza patrons en <file> en lloc dels actuals." +#: builtin/stash.c msgid "git stash list [<log-options>]" -msgstr "git stash list [<log-options>]" +msgstr "git stash list [<opcions-registre>]" +#: builtin/stash.c msgid "" "git stash show [-u | --include-untracked | --only-untracked] [<diff-" "options>] [<stash>]" @@ -12291,22 +15681,28 @@ msgstr "" "git stash show [-u | --include-untracked | --only-untracked] [<diff-" "options>] [<stash>]" +#: builtin/stash.c msgid "git stash drop [-q | --quiet] [<stash>]" msgstr "git stash drop [-q | --quiet] [<stash>]" +#: builtin/stash.c msgid "git stash pop [--index] [-q | --quiet] [<stash>]" msgstr "git stash pop [--index] [-q | --quiet] [<stash>]" +#: builtin/stash.c msgid "git stash apply [--index] [-q | --quiet] [<stash>]" msgstr "git stash apply [--index] [-q | --quiet] [<stash>]" +#: builtin/stash.c msgid "git stash branch <branchname> [<stash>]" msgstr "git stash branch <nom-de-branca> [<stash>]" +#: builtin/stash.c msgid "git stash store [(-m | --message) <message>] [-q | --quiet] <commit>" msgstr "" "git stash store [(-m | --message) <missatge>] [-q | --quiet] <comissió>" +#: builtin/stash.c msgid "" "git stash [push [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q " "| --quiet]\n" @@ -12322,6 +15718,7 @@ msgstr "" " [--pathspec-from-file=<fitxer> [--pathspec-file-nul]]\n" " [--] [<pathspec>...]]" +#: builtin/stash.c msgid "" "git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | " "--quiet]\n" @@ -12331,27 +15728,34 @@ msgstr "" "--quiet]\n" " [-u | --include-untracked] [-a | --all] [<missatge>]" +#: builtin/stash.c msgid "git stash create [<message>]" msgstr "git stash create [<missatge>]" +#: builtin/stash.c #, c-format msgid "'%s' is not a stash-like commit" msgstr "«%s» no és una comissió de tipus «stash»" +#: builtin/stash.c #, c-format msgid "Too many revisions specified:%s" msgstr "S'han especificat massa revisions:%s" +#: builtin/stash.c msgid "No stash entries found." msgstr "No s'ha trobat cap entrada «stash»." +#: builtin/stash.c #, c-format msgid "%s is not a valid reference" msgstr "«%s» no és una referència vàlida" +#: builtin/stash.c msgid "git stash clear with arguments is unimplemented" msgstr "git stash clear amb paràmetres no està implementat" +#: builtin/stash.c #, c-format msgid "" "WARNING: Untracked file in way of tracked file! Renaming\n" @@ -12362,154 +15766,202 @@ msgstr "" " %s -> %s\n" " per a fer-ne espai.\n" +#: builtin/stash.c msgid "cannot apply a stash in the middle of a merge" msgstr "no es pot aplicar un «stash» enmig d'una fusió" +#: builtin/stash.c #, c-format msgid "could not generate diff %s^!." msgstr "no s'ha pogut generar diff %s^!." +#: builtin/stash.c msgid "conflicts in index. Try without --index." msgstr "hi ha conflictes en l'índex. Proveu-ho sense --index." +#: builtin/stash.c msgid "could not save index tree" msgstr "no s'ha pogut desar l'arbre d'índex" +#: builtin/stash.c #, c-format msgid "Merging %s with %s" msgstr "S'està fusionant %s amb %s" +#: builtin/stash.c msgid "Index was not unstashed." msgstr "L'índex no estava «unstashed»." +#: builtin/stash.c msgid "could not restore untracked files from stash" msgstr "no s'han pogut restaurar els fitxers no seguits des del «stash»" +#: builtin/stash.c msgid "attempt to recreate the index" msgstr "intenta tornar a crear l'índex" +#: builtin/stash.c #, c-format msgid "Dropped %s (%s)" msgstr "Descartada %s (%s)" +#: builtin/stash.c #, c-format msgid "%s: Could not drop stash entry" msgstr "%s: no s'ha pogut descartar l'entrada «stash»" +#: builtin/stash.c #, c-format msgid "'%s' is not a stash reference" msgstr "«%s» no és una referència «stash»" +#: builtin/stash.c msgid "The stash entry is kept in case you need it again." -msgstr "Es conserva l'entrada «stash» en cas que la necessiteu altra vegada." +msgstr "" +"Es conserva l'entrada «stash» en cas que la necessiteu una altra vegada." +#: builtin/stash.c msgid "No branch name specified" msgstr "Cap nom de branca especificat" +#: builtin/stash.c msgid "failed to parse tree" msgstr "s'ha produït un error en analitzar l'arbre" +#: builtin/stash.c msgid "failed to unpack trees" msgstr "s'ha produït un error en desempaquetar els arbres" +#: builtin/stash.c msgid "include untracked files in the stash" msgstr "inclou els fitxers no seguits a «stash»" +#: builtin/stash.c msgid "only show untracked files in the stash" msgstr "mostra només els fitxers no seguits a «stash»" +#: builtin/stash.c #, c-format msgid "Cannot update %s with %s" msgstr "No es pot actualitzar %s amb %s" +#: builtin/stash.c msgid "stash message" msgstr "missatge «stash»" +#: builtin/stash.c msgid "\"git stash store\" requires one <commit> argument" msgstr "«git stash store» requereix un argument <comissió>" +#: builtin/stash.c msgid "No staged changes" msgstr "No hi ha canvis a «stage»" +#: builtin/stash.c msgid "No changes selected" msgstr "No hi ha canvis seleccionats" +#: builtin/stash.c msgid "You do not have the initial commit yet" msgstr "Encara no teniu la comissió inicial" +#: builtin/stash.c msgid "Cannot save the current index state" msgstr "No es pot desar l'estat d'índex actual" +#: builtin/stash.c msgid "Cannot save the untracked files" msgstr "No es poden desar els fitxers no seguits" +#: builtin/stash.c msgid "Cannot save the current worktree state" msgstr "No es pot desar l'estat d'arbre de treball actual" +#: builtin/stash.c msgid "Cannot save the current staged state" msgstr "No es pot desar l'estat «stage» actual" +#: builtin/stash.c msgid "Cannot record working tree state" msgstr "No es pot registrar l'estat de l'arbre de treball" +#: builtin/stash.c msgid "Can't use --patch and --include-untracked or --all at the same time" msgstr "No es poden usar --patch i --include-untracked o --all a la vegada" +#: builtin/stash.c msgid "Can't use --staged and --include-untracked or --all at the same time" msgstr "No es poden usar --staged i --include-untracked o --all a la vegada" +#: builtin/stash.c msgid "Did you forget to 'git add'?" msgstr "Heu oblidat de fer «git add»?" +#: builtin/stash.c msgid "No local changes to save" msgstr "No hi ha canvis locals a desar" +#: builtin/stash.c msgid "Cannot initialize stash" msgstr "No es pot inicialitzar el magatzem" +#: builtin/stash.c msgid "Cannot save the current status" msgstr "No es pot desar l'estat actual" +#: builtin/stash.c #, c-format msgid "Saved working directory and index state %s" msgstr "S'han desat el directori de treball i l'estat d'índex %s" +#: builtin/stash.c msgid "Cannot remove worktree changes" msgstr "No es poden eliminar els canvis de l'arbre de treball" +#: builtin/stash.c msgid "keep index" msgstr "mantén l'índex" +#: builtin/stash.c msgid "stash staged changes only" msgstr "fes «stash» només dels canvis «staged»" +#: builtin/stash.c msgid "stash in patch mode" msgstr "fes «stash» en mode pedaç" +#: builtin/stash.c msgid "quiet mode" msgstr "mode silenciós" +#: builtin/stash.c msgid "include untracked files in stash" msgstr "inclou els fitxers no seguits a «stash»" +#: builtin/stash.c msgid "include ignore files" msgstr "inclou els fitxers ignorats" +#: builtin/stripspace.c msgid "skip and remove all lines starting with comment character" msgstr "" "omet i elimina totes les línies que comencin amb el caràcter de comentari" +#: builtin/stripspace.c msgid "prepend comment character and space to each line" msgstr "anteposa el caràcter de comentari i un espai a cada línia" +#: builtin/submodule--helper.c #, c-format msgid "Expecting a full ref name, got %s" msgstr "S'espera un nom de referència ple, s'ha rebut %s" +#: builtin/submodule--helper.c #, c-format msgid "could not get a repository handle for submodule '%s'" msgstr "no s'ha pogut obtenir el gestor del repositori pel submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " @@ -12518,14 +15970,17 @@ msgstr "" "no s'ha pogut trobar la configuració «%s». S'assumeix que aquest repositori " "és el seu repositori font autoritzat." +#: builtin/submodule--helper.c #, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "No s'ha trobat cap url per al camí de submòdul «%s» a .gitmodules" +#: builtin/submodule--helper.c #, c-format msgid "Entering '%s'\n" msgstr "S'està entrant a «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "" "run_command returned non-zero status for %s\n" @@ -12534,6 +15989,7 @@ msgstr "" "run_command ha retornat un estat diferent de zero per a %s\n" "." +#: builtin/submodule--helper.c #, c-format msgid "" "run_command returned non-zero status while recursing in the nested " @@ -12544,56 +16000,70 @@ msgstr "" "recursivament als submòduls imbricats de %s\n" "." +#: builtin/submodule--helper.c msgid "suppress output of entering each submodule command" msgstr "omet la sortida en entrar a cada ordre del submòdul" +#: builtin/submodule--helper.c msgid "recurse into nested submodules" msgstr "cerca recursivament als submòduls imbricats" +#: builtin/submodule--helper.c msgid "git submodule foreach [--quiet] [--recursive] [--] <command>" msgstr "git submodule foreach [--quiet] [--recursive] [--] <ordre>" +#: builtin/submodule--helper.c #, c-format msgid "Failed to register url for submodule path '%s'" msgstr "S'ha produït un error en registrar l'url per al camí de submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Submodule '%s' (%s) registered for path '%s'\n" msgstr "S'ha registrat el submòdul «%s» (%s) per al camí «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "warning: command update mode suggested for submodule '%s'\n" msgstr "" "advertència: se suggereix el mode d'actualització per ordre per al submòdul " "«%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "Failed to register update mode for submodule path '%s'" msgstr "" "S'ha produït un error en registrar el mode d'actualització per al camí de " "submòdul «%s»" +#: builtin/submodule--helper.c msgid "suppress output for initializing a submodule" msgstr "omet la sortida en inicialitzar un submòdul" +#: builtin/submodule--helper.c msgid "git submodule init [<options>] [<path>]" msgstr "git submodule init [<opcions>] [<camí>]" +#: builtin/submodule--helper.c #, c-format msgid "no submodule mapping found in .gitmodules for path '%s'" msgstr "no s'ha trobat cap mapatge de submòdul a .gitmodules per al camí «%s»" +#: builtin/submodule--helper.c #, c-format msgid "could not resolve HEAD ref inside the submodule '%s'" msgstr "no s'ha pogut resoldre la referència a HEAD dins del submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "failed to recurse into submodule '%s'" msgstr "s'ha produït un error en cercar recursivament al submòdul «%s»" +#: builtin/submodule--helper.c msgid "suppress submodule status output" msgstr "suprimeix la sortida de l'estat del submòdul" +#: builtin/submodule--helper.c msgid "" "use commit stored in the index instead of the one stored in the submodule " "HEAD" @@ -12601,69 +16071,87 @@ msgstr "" "utilitza la comissió emmagatzemada a l'índex en lloc de l'emmagatzemada al " "HEAD del submòdul" +#: builtin/submodule--helper.c msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]" msgstr "git submodule status [--quiet] [--cached] [--recursive] [<camí>...]" +#: builtin/submodule--helper.c #, c-format msgid "* %s %s(blob)->%s(submodule)" msgstr "* %s %s(blob)->%s(submòdul)" +#: builtin/submodule--helper.c #, c-format msgid "* %s %s(submodule)->%s(blob)" msgstr "* %s %s(submòdul)->%s(blob)" +#: builtin/submodule--helper.c #, c-format msgid "%s" msgstr "%s" +#: builtin/submodule--helper.c #, c-format msgid "couldn't hash object from '%s'" msgstr "no s'ha pogut fer el resum de l'objecte de «%s»" +#: builtin/submodule--helper.c #, c-format -msgid "unexpected mode %o\n" -msgstr "mode inesperat %o\n" +msgid "unexpected mode %o" +msgstr "mode %o inesperat" +#: builtin/submodule--helper.c msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "" "utilitza la comissió emmagatzemada a l'índex en lloc de l'emmagatzemada al " "HEAD del submòdul" +#: builtin/submodule--helper.c msgid "compare the commit in the index with that in the submodule HEAD" msgstr "" "compara la comissió emmagatzemada a l'índex en lloc de l'emmagatzemada al " "HEAD del submòdul" +#: builtin/submodule--helper.c msgid "skip submodules with 'ignore_config' value set to 'all'" msgstr "omet els submòduls amb el valor «ignore_config» establert a «all»" +#: builtin/submodule--helper.c msgid "limit the summary size" msgstr "limita la mida del resum" +#: builtin/submodule--helper.c msgid "git submodule summary [<options>] [<commit>] [--] [<path>]" msgstr "git submodule summary [<opcions>] [<comissió>] [--] [<camí>]" +#: builtin/submodule--helper.c msgid "could not fetch a revision for HEAD" msgstr "no s'ha pogut obtenir una revisió per a HEAD" +#: builtin/submodule--helper.c #, c-format msgid "Synchronizing submodule url for '%s'\n" msgstr "S'està sincronitzant l'url del submòdul per a «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "failed to register url for submodule path '%s'" msgstr "s'ha produït un error en registrar l'url per al camí del submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "failed to update remote for submodule '%s'" msgstr "s'ha produït un error en actualitzar el remot pel submòdul «%s»" +#: builtin/submodule--helper.c msgid "suppress output of synchronizing submodule url" msgstr "omet la sortida de la sincronització de l'URL del submòdul" +#: builtin/submodule--helper.c msgid "git submodule sync [--quiet] [--recursive] [<path>]" msgstr "git submodule sync [--quiet] [--recursive] [<camí>]" +#: builtin/submodule--helper.c #, c-format msgid "" "Submodule work tree '%s' contains a .git directory. This will be replaced " @@ -12672,6 +16160,7 @@ msgstr "" "L'arbre de treball del submòdul «%s» conté un directori .git. Aquest es " "reemplaçarà amb un fitxer a .git mitjançant l'ús d'«absorbgitdirs»." +#: builtin/submodule--helper.c #, c-format msgid "" "Submodule work tree '%s' contains local modifications; use '-f' to discard " @@ -12680,38 +16169,47 @@ msgstr "" "L'arbre de treball del submòdul «%s» conté modificacions locals; useu «-f» " "per a descartar-les" +#: builtin/submodule--helper.c #, c-format msgid "Cleared directory '%s'\n" msgstr "S'ha esborrat el directori «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "Could not remove submodule work tree '%s'\n" msgstr "No s'ha pogut eliminar l'arbre de treball de submòdul «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "could not create empty submodule directory %s" msgstr "no s'ha pogut crear el directori de submòdul buit %s" +#: builtin/submodule--helper.c #, c-format msgid "Submodule '%s' (%s) unregistered for path '%s'\n" msgstr "S'ha desregistrat el submòdul «%s» (%s) per al camí «%s»\n" +#: builtin/submodule--helper.c msgid "remove submodule working trees even if they contain local changes" msgstr "" "elimina els arbres de treball dels submòduls fins i tot si contenen canvis " "locals" +#: builtin/submodule--helper.c msgid "unregister all submodules" msgstr "desregistra tots els submòduls" +#: builtin/submodule--helper.c msgid "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]" msgstr "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<camí>...]]" +#: builtin/submodule--helper.c msgid "Use '--all' if you really want to deinitialize all submodules" msgstr "Useu «--all» si realment voleu desinicialitzar tots els submòduls" +#: builtin/submodule--helper.c msgid "" "An alternate computed from a superproject's alternate is invalid.\n" "To allow Git to clone without an alternate in such a case, set\n" @@ -12724,138 +16222,172 @@ msgstr "" "submodule.alternateErrorStrategy a «info» o bé cloneu amb\n" "«--reference-if-able' en comptes de «--reference»." +#: builtin/submodule--helper.c #, c-format msgid "could not get a repository handle for gitdir '%s'" msgstr "no s'ha pogut obtenir el gestor del repositori per al gitdir «%s»" +#: builtin/submodule--helper.c #, c-format msgid "submodule '%s' cannot add alternate: %s" msgstr "el submòdul «%s» no pot afegir un alternatiu: %s" +#: builtin/submodule--helper.c #, c-format msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized" msgstr "No es reconeix el valor «%s» per a submodule.alternateErrorStrategy" +#: builtin/submodule--helper.c #, c-format msgid "Value '%s' for submodule.alternateLocation is not recognized" msgstr "No es reconeix el valor «%s» per a submodule.alternateLocation" +#: builtin/submodule--helper.c submodule.c #, c-format msgid "refusing to create/use '%s' in another submodule's git dir" msgstr "s'ha rebutjat crear/usar «%s» en el directori git d'un altre submòdul" -#, c-format -msgid "clone of '%s' into submodule path '%s' failed" -msgstr "el clonatge de «%s» al camí de submòdul «%s» ha fallat" - +#: builtin/submodule--helper.c #, c-format msgid "directory not empty: '%s'" msgstr "directori no buit: «%s»" +#: builtin/submodule--helper.c +#, c-format +msgid "clone of '%s' into submodule path '%s' failed" +msgstr "el clonatge de «%s» al camí de submòdul «%s» ha fallat" + +#: builtin/submodule--helper.c #, c-format msgid "could not get submodule directory for '%s'" msgstr "no s'ha pogut obtenir el directori de submòdul per a «%s»" +#: builtin/submodule--helper.c msgid "alternative anchor for relative paths" msgstr "àncora alternativa per als camins relatius" +#: builtin/submodule--helper.c msgid "where the new submodule will be cloned to" msgstr "a on es clonarà el submòdul nou" +#: builtin/submodule--helper.c msgid "name of the new submodule" msgstr "nom del submòdul nou" +#: builtin/submodule--helper.c msgid "url where to clone the submodule from" msgstr "url del qual clonar el submòdul" +#: builtin/submodule--helper.c msgid "depth for shallow clones" msgstr "profunditat dels clons superficials" +#: builtin/submodule--helper.c msgid "force cloning progress" msgstr "força el progrés del clonatge" +#: builtin/submodule--helper.c msgid "disallow cloning into non-empty directory" msgstr "no permetis clonar en un directori no buit" +#: builtin/submodule--helper.c msgid "" "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference " "<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter " "<filter-spec>] --url <url> --path <path>" msgstr "" "git submodule--helper clone [--prefix=<camí>] [--quiet] [--reference " -"<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter " +"<repositori>] [--name <nom>] [--depth <depth>] [--single-branch] [--filter " "<filter-spec>] --url <url> --path <camí>" +#: builtin/submodule--helper.c #, c-format msgid "Invalid update mode '%s' configured for submodule path '%s'" msgstr "" "Mode d'actualització «%s» configurat no vàlid per al camí de submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Submodule path '%s' not initialized" msgstr "El camí de submòdul «%s» no està inicialitzat" +#: builtin/submodule--helper.c msgid "Maybe you want to use 'update --init'?" msgstr "Potser voleu usar «update --init»?" +#: builtin/submodule--helper.c #, c-format msgid "Skipping unmerged submodule %s" msgstr "S'està ometent el submòdul no fusionat %s" +#: builtin/submodule--helper.c #, c-format msgid "Skipping submodule '%s'" msgstr "S'està ometent el submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "cannot clone submodule '%s' without a URL" msgstr "no es pot clonar el submòdul «%s» sense un URL" +#: builtin/submodule--helper.c #, c-format msgid "Failed to clone '%s'. Retry scheduled" msgstr "S'ha produït un error en clonar «%s». S'ha programat un reintent" +#: builtin/submodule--helper.c #, c-format msgid "Failed to clone '%s' a second time, aborting" msgstr "S'ha produït un error per segon cop en clonar «%s», s'està avortant" +#: builtin/submodule--helper.c #, c-format msgid "Unable to checkout '%s' in submodule path '%s'" msgstr "No s'ha pogut agafar «%s» en el camí de submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Unable to rebase '%s' in submodule path '%s'" msgstr "No s'ha pogut fer «rebase» «%s» en el camí de submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Unable to merge '%s' in submodule path '%s'" msgstr "No s'ha pogut fusionar «%s» en el camí de submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Execution of '%s %s' failed in submodule path '%s'" msgstr "L'execució de «%s %s» ha fallat en el camí de submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Submodule path '%s': checked out '%s'\n" msgstr "Camí de submòdul «%s»: s'ha agafat «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "Submodule path '%s': rebased into '%s'\n" msgstr "Camí de submòdul «%s»: s'ha fet «rebase» en «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "Submodule path '%s': merged in '%s'\n" msgstr "Camí de submòdul «%s»: s'ha fusionat en «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "Submodule path '%s': '%s %s'\n" msgstr "El camí de submòdul «%s»: '%s %s'\n" +#: builtin/submodule--helper.c #, c-format msgid "Unable to fetch in submodule path '%s'; trying to directly fetch %s:" msgstr "" "No s'ha pogut obtenir en el camí de submòdul «$%s»; s'està intentant obtenir " "directament %s:" +#: builtin/submodule--helper.c #, c-format msgid "" "Fetched in submodule path '%s', but it did not contain %s. Direct fetching " @@ -12864,10 +16396,12 @@ msgstr "" "S'ha obtingut en un camí de submòdul «%s», però no contenia %s. L'obtenció " "directa d'aquesta comissió ha fallat." +#: builtin/submodule--helper.c #, c-format msgid "could not initialize submodule at path '%s'" msgstr "no s'ha pogut inicialitzar el submòdul al camí «%s»" +#: builtin/submodule--helper.c #, c-format msgid "" "Submodule (%s) branch configured to inherit branch from superproject, but " @@ -12876,62 +16410,80 @@ msgstr "" "La branca de submòdul (%s) està configurada per a heretar la branca del " "superprojecte, però el superprojecte no és en cap branca" +#: builtin/submodule--helper.c #, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "No s'ha pogut trobar la revisió actual al camí del submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Unable to fetch in submodule path '%s'" msgstr "No s'ha pogut obtenir el camí del submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Unable to find %s revision in submodule path '%s'" msgstr "No s'ha pogut trobar la revisió %s en el camí del submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Failed to recurse into submodule path '%s'" msgstr "" "s'ha produït un error en cercar recursivament al camí del submòdul «%s»" +#: builtin/submodule--helper.c msgid "force checkout updates" msgstr "força les actualitzacions" +#: builtin/submodule--helper.c msgid "initialize uninitialized submodules before update" msgstr "inicialitza els submòduls sense inicialitzar abans d'actualitzar" +#: builtin/submodule--helper.c msgid "use SHA-1 of submodule's remote tracking branch" msgstr "usa el SHA-1 de la branca de seguiment remota del submòdul" +#: builtin/submodule--helper.c msgid "traverse submodules recursively" msgstr "recorre els submòduls recursivament" +#: builtin/submodule--helper.c msgid "don't fetch new objects from the remote site" msgstr "no obtinguis els objectes nous del lloc remot" +#: builtin/submodule--helper.c msgid "use the 'checkout' update strategy (default)" msgstr "utilitza l'estratègia d'actualització «checkout» (predeterminada)" +#: builtin/submodule--helper.c msgid "use the 'merge' update strategy" msgstr "utilitza l'estratègia d'actualització de «merge»" +#: builtin/submodule--helper.c msgid "use the 'rebase' update strategy" msgstr "utilitza l'estratègia d'actualització de «rebase»" +#: builtin/submodule--helper.c msgid "create a shallow clone truncated to the specified number of revisions" msgstr "crea un clon superficial truncat al nombre de revisions especificat" +#: builtin/submodule--helper.c msgid "parallel jobs" msgstr "tasques paral·leles" +#: builtin/submodule--helper.c msgid "whether the initial clone should follow the shallow recommendation" msgstr "si el clonatge inicial ha de seguir la recomanació de superficialitat" +#: builtin/submodule--helper.c msgid "don't print cloning progress" msgstr "no imprimeixis el progrés del clonatge" +#: builtin/submodule--helper.c msgid "disallow cloning into non-empty directory, implies --init" msgstr "no permetis clonar en un directori no buit, implica --init" +#: builtin/submodule--helper.c msgid "" "git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] " "[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-" @@ -12940,68 +16492,86 @@ msgid "" msgstr "" "git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] " "[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-" -"shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] " +"shallow] [--reference <repositori>] [--recursive] [--[no-]single-branch] " "[--] [<camí>...]" +#: builtin/submodule--helper.c submodule.c 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." +#: builtin/submodule--helper.c msgid "git submodule absorbgitdirs [<options>] [<path>...]" msgstr "git submodule absorbgitdirs [<opcions>] [<camí>...]" +#: builtin/submodule--helper.c msgid "suppress output for setting url of a submodule" msgstr "omet la sortida en configurar un URL d'un submòdul" +#: builtin/submodule--helper.c msgid "git submodule set-url [--quiet] <path> <newurl>" -msgstr "git submodule set-url [--quiet] <camí> <newurl>" +msgstr "git submodule set-url [--quiet] <camí> <url-nou>" +#: builtin/submodule--helper.c msgid "set the default tracking branch to master" msgstr "estableix la branca de seguiment per defecte a «master»" +#: builtin/submodule--helper.c msgid "set the default tracking branch" msgstr "estableix la branca de seguiment per defecte" +#: builtin/submodule--helper.c msgid "git submodule set-branch [-q|--quiet] (-d|--default) <path>" msgstr "git submodule set-branch [-q|--quiet] (-d|--default) <camí>" +#: builtin/submodule--helper.c msgid "git submodule set-branch [-q|--quiet] (-b|--branch) <branch> <path>" msgstr "git submodule set-branch [-q|--quiet] (-b|--branch) <branca> <camí>" +#: builtin/submodule--helper.c msgid "--branch or --default required" msgstr "cal --branch o --default" +#: builtin/submodule--helper.c msgid "print only error messages" msgstr "mostra només els missatges d'error" +#: builtin/submodule--helper.c msgid "force creation" msgstr "força la creació" +#: builtin/submodule--helper.c msgid "show whether the branch would be created" msgstr "mostra si es crearà la branca" +#: builtin/submodule--helper.c msgid "" "git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--" "quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>" msgstr "" "git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--" -"quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>" +"quiet] [-t|--track] [-n|--dry-run] <nom> <oid-inicial> <nom-inicial>" +#: builtin/submodule--helper.c #, c-format msgid "creating branch '%s'" msgstr "s'està creant la branca «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Adding existing repo at '%s' to the index\n" msgstr "S'està afegint el repositori existent a «%s» a l'índex\n" +#: builtin/submodule--helper.c #, c-format msgid "'%s' already exists and is not a valid git repo" msgstr "«%s» ja existeix i no és un repositori de git vàlid" +#: builtin/submodule--helper.c #, c-format msgid "A git directory for '%s' is found locally with remote(s):\n" msgstr "S'ha trobat un directori de git per a «%s» localment amb els remots:\n" +#: builtin/submodule--helper.c #, c-format msgid "" "If you want to reuse this local git directory instead of cloning again from\n" @@ -13019,46 +16589,58 @@ msgstr "" "o no esteu segur de què vol dir això, trieu un altre nom amb l'opció «--" "name»." +#: builtin/submodule--helper.c #, c-format msgid "Reactivating local git directory for submodule '%s'\n" msgstr "S'està reactivant el directori de git local per al submòdul «%s»\n" +#: builtin/submodule--helper.c #, c-format msgid "unable to checkout submodule '%s'" msgstr "no s'ha pogut agafar el submòdul «%s»" +#: builtin/submodule--helper.c msgid "please make sure that the .gitmodules file is in the working tree" msgstr "assegureu-vos que el fitxer .gitmodules és a l'arbre de treball" +#: builtin/submodule--helper.c #, c-format msgid "Failed to add submodule '%s'" msgstr "S'ha produït un error en afegir el submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "Failed to register submodule '%s'" msgstr "S'ha produït un error en registrar el submòdul «%s»" +#: builtin/submodule--helper.c #, c-format msgid "'%s' already exists in the index" msgstr "«%s» ja existeix en l'índex" +#: builtin/submodule--helper.c #, c-format msgid "'%s' already exists in the index and is not a submodule" msgstr "«%s» ja existeix en l'índex i no és submòdul" +#: builtin/submodule--helper.c read-cache.c #, c-format msgid "'%s' does not have a commit checked out" msgstr "«%s» no té una comissió comprovada" +#: builtin/submodule--helper.c msgid "branch of repository to add as submodule" msgstr "la branca del repositori a afegir com a submòdul" +#: builtin/submodule--helper.c msgid "allow adding an otherwise ignored submodule path" msgstr "permet afegir un camí de submòdul que si no s'hagués ignorat" +#: builtin/submodule--helper.c msgid "borrow the objects from reference repositories" msgstr "manlleva els objectes dels repositoris de referències" +#: builtin/submodule--helper.c msgid "" "sets the submodule's name to the given string instead of defaulting to its " "path" @@ -13066,62 +16648,81 @@ msgstr "" "estableix el nom del submòdul a la cadena donada en lloc de per defecte al " "seu camí" +#: builtin/submodule--helper.c msgid "git submodule add [<options>] [--] <repository> [<path>]" -msgstr "git submodule add [<opcions>] [--] <repository> [<camí>]" +msgstr "git submodule add [<opcions>] [--] <repositori> [<camí>]" +#: builtin/submodule--helper.c msgid "Relative path can only be used from the toplevel of the working tree" msgstr "" "El camí relatiu només es pot usar des del nivell superior de l'arbre de " "treball" +#: builtin/submodule--helper.c #, c-format msgid "repo URL: '%s' must be absolute or begin with ./|../" msgstr "URL de repositori: «%s» ha de ser absolut o començar amb ./|../" +#: builtin/submodule--helper.c #, c-format msgid "'%s' is not a valid submodule name" msgstr "«%s» no és un nom de submòdul vàlid" +#: builtin/submodule--helper.c msgid "git submodule--helper <command>" -msgstr "git submodule--helper <command>" +msgstr "git submodule--helper <ordre>" +#: builtin/symbolic-ref.c msgid "git symbolic-ref [-m <reason>] <name> <ref>" -msgstr "git symbolic-ref [-m <reason>] <name> <ref>" +msgstr "git symbolic-ref [-m <raó>] <nom> <referència>" +#: builtin/symbolic-ref.c msgid "git symbolic-ref [-q] [--short] [--no-recurse] <name>" -msgstr "git symbolic-ref [-q] [--short] [--no-recurse] <name>" +msgstr "git symbolic-ref [-q] [--short] [--no-recurse] <nom>" +#: builtin/symbolic-ref.c msgid "git symbolic-ref --delete [-q] <name>" -msgstr "git symbolic-ref --delete [-q] <name>" +msgstr "git symbolic-ref --delete [-q] <nom>" +#: builtin/symbolic-ref.c msgid "suppress error message for non-symbolic (detached) refs" msgstr "omet el missatge d'error de referències no simbòliques (separades)" +#: builtin/symbolic-ref.c msgid "delete symbolic ref" msgstr "suprimeix la referència simbòlica" +#: builtin/symbolic-ref.c msgid "shorten ref output" msgstr "escurça la sortida de referències" +#: builtin/symbolic-ref.c msgid "recursively dereference (default)" msgstr "desreferencia recursivament (per defecte)" +#: builtin/symbolic-ref.c builtin/update-ref.c msgid "reason" msgstr "raó" +#: builtin/symbolic-ref.c builtin/update-ref.c msgid "reason of the update" msgstr "raó de l'actualització" +#: builtin/tag.c msgid "" "git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n" +" [(--trailer <token>[(=|:)<value>])...]\n" " <tagname> [<commit> | <object>]" msgstr "" -"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <fitxer>] [-e]\n" -" <tagname> [<comissió> | <objecte>]" +"git tag [-a | -s | -u <id-clau>] [-f] [-m <missatge> | -F <fitxer>] [-e]\n" +" [(--trailer <token>[(=|:)<valor>])...]\n" +" <nom-etiqueta> [<comissió> | <objecte>]" +#: builtin/tag.c msgid "git tag -d <tagname>..." -msgstr "git tag -d <nom-d'etiqueta>..." +msgstr "git tag -d <nom-etiqueta>..." +#: builtin/tag.c msgid "" "git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n" " [--points-at <object>] [--column[=<options>] | --no-column]\n" @@ -13130,49 +16731,56 @@ msgid "" msgstr "" "git tag [-n[<num>]] -l [--contains <comissió>] [--no-contains <comissió>]\n" " [--points-at <objecte>] [--column[=<opcions>] | --no-column]\n" -" [--create-reflog] [--sort=<key>] [--format=<format>]\n" +" [--create-reflog] [--sort=<clau>] [--format=<format>]\n" " [--merged <comissió>] [--no-merged <comissió>] [<patró>...]" +#: builtin/tag.c msgid "git tag -v [--format=<format>] <tagname>..." -msgstr "git tag -v [--format=<format>] <nom-d'etiqueta>..." +msgstr "git tag -v [--format=<format>] <nom-etiqueta>..." +#: builtin/tag.c #, c-format msgid "tag '%s' not found." msgstr "no s'ha trobat l'etiqueta «%s»." +#: builtin/tag.c #, c-format msgid "Deleted tag '%s' (was %s)\n" msgstr "S'ha suprimit l'etiqueta «%s» (era %s)\n" +#: builtin/tag.c #, c-format msgid "" "\n" "Write a message for tag:\n" " %s\n" -"Lines starting with '%c' will be ignored.\n" +"Lines starting with '%s' will be ignored.\n" msgstr "" "\n" -"Escriviu el missatge de l'etiqueta:\n" +"Escriviu un missatge per a l'etiqueta:\n" " %s\n" -"Les línies que comencin amb «%c» s'ignoraran.\n" +"S'ignoraran les línies que comencen amb «%s».\n" +#: builtin/tag.c #, c-format msgid "" "\n" "Write a message for tag:\n" " %s\n" -"Lines starting with '%c' will be kept; you may remove them yourself if you " +"Lines starting with '%s' will be kept; you may remove them yourself if you " "want to.\n" msgstr "" "\n" -"Escriviu el missatge de l'etiqueta:\n" +"Escriviu un missatge per a l'etiqueta:\n" " %s\n" -"Les línies que comencin amb «%c» es retindran; podeu eliminar-les per vós " -"mateix si voleu.\n" +"Es mantindran les línies que comencin amb «%s»; les podeu eliminar si " +"voleu.\n" +#: builtin/tag.c msgid "unable to sign the tag" msgstr "no s'ha pogut signar l'etiqueta" +#: builtin/tag.c #, c-format msgid "" "You have created a nested tag. The object referred to by your new tag is\n" @@ -13186,275 +16794,361 @@ msgstr "" "\n" "\tgit tag -f %s %s^{}" +#: builtin/tag.c msgid "bad object type." msgstr "el tipus d'objecte és incorrecte." +#: builtin/tag.c msgid "no tag message?" msgstr "no hi ha cap missatge d'etiqueta?" +#: builtin/tag.c #, c-format msgid "The tag message has been left in %s\n" msgstr "S'ha deixat el missatge de l'etiqueta en %s\n" +#: builtin/tag.c msgid "list tag names" msgstr "llista els noms d'etiqueta" +#: builtin/tag.c msgid "print <n> lines of each tag message" msgstr "imprimeix <n> línies de cada missatge d'etiqueta" +#: builtin/tag.c msgid "delete tags" msgstr "suprimeix les etiquetes" +#: builtin/tag.c msgid "verify tags" msgstr "verifica les etiquetes" +#: builtin/tag.c msgid "Tag creation options" msgstr "Opcions de creació d'etiquetes" +#: builtin/tag.c msgid "annotated tag, needs a message" msgstr "etiqueta anotada, necessita un missatge" +#: builtin/tag.c msgid "tag message" msgstr "missatge d'etiqueta" +#: builtin/tag.c msgid "force edit of tag message" msgstr "força l'edició del missatge de l'etiqueta" +#: builtin/tag.c msgid "annotated and GPG-signed tag" msgstr "etiqueta anotada i signada per GPG" +#: builtin/tag.c msgid "use another key to sign the tag" msgstr "usa una altra clau per a signar l'etiqueta" +#: builtin/tag.c msgid "replace the tag if exists" msgstr "reemplaça l'etiqueta si existeix" +#: builtin/tag.c builtin/update-ref.c msgid "create a reflog" msgstr "crea un registre de referències" +#: builtin/tag.c msgid "Tag listing options" msgstr "Opcions de llistat d'etiquetes" +#: builtin/tag.c msgid "show tag list in columns" msgstr "mostra la llista d'etiquetes en columnes" +#: builtin/tag.c msgid "print only tags that contain the commit" msgstr "imprimeix només les etiquetes que continguin la comissió" +#: builtin/tag.c msgid "print only tags that don't contain the commit" msgstr "imprimeix només les etiquetes que no continguin la comissió" +#: builtin/tag.c msgid "print only tags that are merged" msgstr "imprimeix només les etiquetes que s'han fusionat" +#: builtin/tag.c msgid "print only tags that are not merged" msgstr "imprimeix només les etiquetes que no s'han fusionat" +#: builtin/tag.c msgid "print only tags of the object" msgstr "imprimeix només les etiquetes de l'objecte" +#: builtin/tag.c +msgid "could not start 'git column'" +msgstr "no s'ha pogut iniciar «git column»" + +#: builtin/tag.c #, c-format msgid "the '%s' option is only allowed in list mode" msgstr "l'opció «%s» només està permesa en mode de llista" +#: builtin/tag.c #, c-format msgid "'%s' is not a valid tag name." msgstr "«%s» no és un nom d'etiqueta vàlid." +#: builtin/tag.c #, c-format msgid "tag '%s' already exists" msgstr "l'etiqueta «%s» ja existeix" +#: builtin/tag.c sequencer.c #, c-format msgid "Invalid cleanup mode %s" msgstr "Mode de neteja no vàlid %s" +#: builtin/tag.c #, c-format msgid "Updated tag '%s' (was %s)\n" msgstr "Etiqueta «%s» actualitzada (era %s)\n" +#: builtin/unpack-objects.c msgid "pack exceeds maximum allowed size" msgstr "el paquet supera la mida màxima permesa" +#: builtin/unpack-objects.c msgid "failed to write object in stream" msgstr "no s'ha pogut escriure l'objecte al flux" +#: builtin/unpack-objects.c #, c-format msgid "inflate returned (%d)" msgstr "inflate ha retornat (%d)" +#: builtin/unpack-objects.c msgid "invalid blob object from stream" msgstr "l'objecte blob del flux no és vàlid" +#: builtin/unpack-objects.c msgid "Unpacking objects" msgstr "S'estan desempaquetant els objectes" +#: builtin/update-index.c #, c-format msgid "failed to create directory %s" msgstr "s'ha produït un error en crear el directori %s" +#: builtin/update-index.c #, c-format msgid "failed to delete file %s" msgstr "s'ha produït un error en suprimir el fitxer %s" +#: builtin/update-index.c #, c-format msgid "failed to delete directory %s" msgstr "s'ha produït un error en suprimir el directori %s" +#: builtin/update-index.c #, c-format msgid "Testing mtime in '%s' " msgstr "S'està provant mtime en «%s» " +#: builtin/update-index.c msgid "directory stat info does not change after adding a new file" msgstr "" "la informació de stat de directori no canvia després d'afegir un fitxer nou" +#: builtin/update-index.c msgid "directory stat info does not change after adding a new directory" msgstr "" "la informació de stat de directori no canvia després d'afegir un directori " "nou" +#: builtin/update-index.c msgid "directory stat info changes after updating a file" msgstr "" "la informació de stat de directori canvia després d'actualitzar un fitxer" +#: builtin/update-index.c msgid "directory stat info changes after adding a file inside subdirectory" msgstr "" "la informació de stat de directori canvia després d'afegir un fitxer dins " "d'un subdirectori" +#: builtin/update-index.c msgid "directory stat info does not change after deleting a file" msgstr "" "la informació de stat de directori no canvia després de suprimir un fitxer" +#: builtin/update-index.c msgid "directory stat info does not change after deleting a directory" msgstr "" "la informació de stat de directori no canvia després de suprimir un directori" +#: builtin/update-index.c msgid " OK" msgstr " D'acord" +#: builtin/update-index.c msgid "git update-index [<options>] [--] [<file>...]" msgstr "git update-index [<opcions>] [--] [<fitxer>...]" +#: builtin/update-index.c msgid "continue refresh even when index needs update" msgstr "" "continua l'actualització encara que l'índex necessiti una actualització" +#: builtin/update-index.c msgid "refresh: ignore submodules" msgstr "actualitza: ignora els submòduls" +#: builtin/update-index.c msgid "do not ignore new files" msgstr "no ignoris els fitxers nous" +#: builtin/update-index.c msgid "let files replace directories and vice-versa" msgstr "deixa que els fitxers reemplacin els directoris i viceversa" +#: builtin/update-index.c msgid "notice files missing from worktree" msgstr "tingues en compte els fitxers absents de l'arbre de treball" +#: builtin/update-index.c msgid "refresh even if index contains unmerged entries" msgstr "actualitza encara que l'índex contingui entrades no fusionades" +#: builtin/update-index.c msgid "refresh stat information" msgstr "actualitza la informació d'estadístiques" +#: builtin/update-index.c msgid "like --refresh, but ignore assume-unchanged setting" msgstr "com --refresh, però ignora el paràmetre assume-unchanged" +#: builtin/update-index.c msgid "<mode>,<object>,<path>" msgstr "<mode>,<objecte>,<camí>" +#: builtin/update-index.c msgid "add the specified entry to the index" msgstr "afegeix l'entrada especificada a l'índex" +#: builtin/update-index.c msgid "mark files as \"not changing\"" msgstr "marca els fitxers com a «no canviant»" +#: builtin/update-index.c msgid "clear assumed-unchanged bit" msgstr "esborra el bit assumed-unchanged" +#: builtin/update-index.c msgid "mark files as \"index-only\"" msgstr "marca els fitxers com a «només índex»" +#: builtin/update-index.c msgid "clear skip-worktree bit" msgstr "esborra el bit skip-worktree" +#: builtin/update-index.c msgid "do not touch index-only entries" msgstr "no toquis les entrades de només índex" +#: builtin/update-index.c msgid "add to index only; do not add content to object database" msgstr "" "només afegeix a l'índex; no afegeixis el contingut a la base de dades " "d'objectes" +#: builtin/update-index.c msgid "remove named paths even if present in worktree" msgstr "" "elimina els camins anomenats encara que estiguin presents en l'arbre de " "treball" +#: builtin/update-index.c msgid "with --stdin: input lines are terminated by null bytes" msgstr "amb --stdin: les línies d'entrada acaben amb octets nuls" +#: builtin/update-index.c msgid "read list of paths to be updated from standard input" msgstr "llegeix la llista de camins a actualitzar des de l'entrada estàndard" +#: builtin/update-index.c msgid "add entries from standard input to the index" msgstr "afegeix les entrades de l'entrada estàndard a l'índex" +#: builtin/update-index.c msgid "repopulate stages #2 and #3 for the listed paths" msgstr "reemplena les «stage» #2 i #3 per als camins llistats" +#: builtin/update-index.c msgid "only update entries that differ from HEAD" msgstr "només actualitza les entrades que difereixin de HEAD" +#: builtin/update-index.c msgid "ignore files missing from worktree" msgstr "ignora els fitxers absents de l'arbre de treball" +#: builtin/update-index.c msgid "report actions to standard output" msgstr "informa de les accions en la sortida estàndard" +#: builtin/update-index.c msgid "(for porcelains) forget saved unresolved conflicts" msgstr "(per a porcellanes) oblida't dels conflictes no resolts ni desats" +#: builtin/update-index.c msgid "write index in this format" msgstr "escriu l'índex en aquest format" +#: builtin/update-index.c msgid "report on-disk index format version" msgstr "informa sobre la versió del format de l'índex del disc" +#: builtin/update-index.c msgid "enable or disable split index" msgstr "habilita o inhabilita l'índex dividit" +#: builtin/update-index.c msgid "enable/disable untracked cache" msgstr "habilita/inhabilita la memòria cau no seguida" +#: builtin/update-index.c msgid "test if the filesystem supports untracked cache" msgstr "prova si el sistema de fitxers admet la memòria cau no seguida" +#: builtin/update-index.c msgid "enable untracked cache without testing the filesystem" msgstr "habilita la memòria cau no seguida sense provar el sistema de fitxers" +#: builtin/update-index.c msgid "write out the index even if is not flagged as changed" msgstr "escriu l'índex encara que no estigui marcat com a canviat" +#: builtin/update-index.c msgid "enable or disable file system monitor" msgstr "habilita o inhabilita el monitor del sistema de fitxers" +#: builtin/update-index.c msgid "mark files as fsmonitor valid" msgstr "marca els fitxers com a vàlids pel fsmonitor" +#: builtin/update-index.c msgid "clear fsmonitor valid bit" msgstr "esborra el bit de validesa del 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: era %d, s'ha establert a %d" +#: builtin/update-index.c msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -13462,6 +17156,7 @@ msgstr "" "core.splitIndex està establert a fals; elimineu-lo o canviar-lo, si realment " "voleu habilitar l'índex dividit" +#: builtin/update-index.c msgid "" "core.splitIndex is set to true; remove or change it, if you really want to " "disable split index" @@ -13469,6 +17164,7 @@ msgstr "" "core.splitIndex està establert a cert; elimineu-lo o canvieu-lo, si realment " "voleu inhabilitar l'índex dividit" +#: builtin/update-index.c msgid "" "core.untrackedCache is set to true; remove or change it, if you really want " "to disable the untracked cache" @@ -13476,9 +17172,11 @@ msgstr "" "core.untrackedCache està establert a cert; elimineu-lo o canvieu-lo, si " "realment voleu inhabilitar el cau no seguit" +#: builtin/update-index.c msgid "Untracked cache disabled" msgstr "La memòria cau no seguida està inhabilitada" +#: builtin/update-index.c msgid "" "core.untrackedCache is set to false; remove or change it, if you really want " "to enable the untracked cache" @@ -13486,96 +17184,124 @@ msgstr "" "core.untrackedCache està establert a fals; elimineu-lo o canviar-lo, si " "realment voleu habilitar el cau no seguit" +#: builtin/update-index.c #, c-format msgid "Untracked cache enabled for '%s'" msgstr "La memòria cau no seguida està habilitada per a «%s»" +#: builtin/update-index.c msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor" msgstr "" "core.fsmonitor està establert a fals; establiu-lo a cert si realment voleu " "habilitar fsmonitor" +#: builtin/update-index.c msgid "fsmonitor enabled" msgstr "fsmonitor habilitat" +#: builtin/update-index.c msgid "" "core.fsmonitor is set; remove it if you really want to disable fsmonitor" msgstr "" "core.fsmonitor està establert a cert; elimineu-lo si realment voleu " "inhabilitar fsmonitor" +#: builtin/update-index.c msgid "fsmonitor disabled" msgstr "fsmonitor inhabilitat" -msgid "git update-ref [<options>] -d <refname> [<old-val>]" -msgstr "git update-ref [<opcions>] -d <nom-de-referència> [<valor-antic>]" +#: builtin/update-ref.c +msgid "git update-ref [<options>] -d <refname> [<old-oid>]" +msgstr "git update-ref [<opcions>] -d <nom-referència> [<oid-vell>]" -msgid "git update-ref [<options>] <refname> <new-val> [<old-val>]" -msgstr "" -"git update-ref [<opcions>] <nom-de-referència> <valor-nou> [<valor-antic>]" +#: builtin/update-ref.c +msgid "git update-ref [<options>] <refname> <new-oid> [<old-oid>]" +msgstr "git update-ref [<opcions>] <nom-referència> <oid-nou> [<oid-vell>]" +#: builtin/update-ref.c msgid "git update-ref [<options>] --stdin [-z]" msgstr "git update-ref [<opcions>] --stdin [-z]" +#: builtin/update-ref.c msgid "delete the reference" msgstr "suprimeix la referència" +#: builtin/update-ref.c msgid "update <refname> not the one it points to" -msgstr "actualitza <nom de referència>, no la que apunti" +msgstr "actualitza <nom-referència>, no la que apunti" +#: builtin/update-ref.c msgid "stdin has NUL-terminated arguments" msgstr "stdin té arguments acabats amb NUL" +#: builtin/update-ref.c msgid "read updates from stdin" msgstr "llegeix les actualitzacions des de stdin" +#: builtin/update-server-info.c msgid "update the info files from scratch" msgstr "actualitza els fitxers d'informació des de zero" +#: builtin/upload-pack.c msgid "" "git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n" " [--advertise-refs] <directory>" msgstr "" "git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n" -" [--advertise-refs] <directory>" +" [--advertise-refs] <directori>" +#: builtin/upload-pack.c t/helper/test-serve-v2.c msgid "quit after a single request/response exchange" msgstr "surt després d'un sol intercanvi de sol·licitud/resposta" +#: builtin/upload-pack.c msgid "serve up the info/refs for git-http-backend" msgstr "serveix les info/refs per a git-http-backend" +#: builtin/upload-pack.c msgid "do not try <directory>/.git/ if <directory> is no Git directory" msgstr "" "no intentis <directori>/.git/ si <directori> no és cap directori del Git" +#: builtin/upload-pack.c msgid "interrupt transfer after <n> seconds of inactivity" msgstr "interromp la transferència després de <n> segons d'inactivitat" +#: builtin/verify-commit.c msgid "git verify-commit [-v | --verbose] [--raw] <commit>..." msgstr "git verify-commit [-v | --verbose] [--raw] <comissió>..." +#: builtin/verify-commit.c msgid "print commit contents" msgstr "imprimeix els continguts de la comissió" +#: builtin/verify-commit.c builtin/verify-tag.c msgid "print raw gpg status output" msgstr "imprimeix la sortida crua de l'estat gpg" +#: builtin/verify-pack.c msgid "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idx..." -msgstr "git verify-pack [-v | --verbose] [-s | --stat-only] [--] <pack>.idx..." +msgstr "" +"git verify-pack [-v | --verbose] [-s | --stat-only] [--] <paquet>.idx..." +#: builtin/verify-pack.c msgid "verbose" msgstr "detallat" +#: builtin/verify-pack.c msgid "show statistics only" msgstr "mostra només estadístiques" +#: builtin/verify-tag.c msgid "git verify-tag [-v | --verbose] [--format=<format>] [--raw] <tag>..." -msgstr "git verify-tag [-v | --verbose] [--format=<format>] [--raw] <tag>..." +msgstr "" +"git verify-tag [-v | --verbose] [--format=<format>] [--raw] <etiqueta>..." +#: builtin/verify-tag.c msgid "print tag contents" msgstr "imprimeix els continguts de l'etiqueta" +#: builtin/worktree.c msgid "" "git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]]\n" " [--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>]" @@ -13583,30 +17309,39 @@ msgstr "" "git worktree add [-f] [--detach] [--checkout] [--lock [--reason <cadena>]]\n" " [--orphan] [(-b | -B) <new-branch>] <camí> [<commit-ish>]" +#: builtin/worktree.c msgid "git worktree list [-v | --porcelain [-z]]" msgstr "git worktree list [-v | --porcelain [-z]]" +#: builtin/worktree.c msgid "git worktree lock [--reason <string>] <worktree>" -msgstr "git worktree lock [--reason <string>] <worktree>" +msgstr "git worktree lock [--reason <cadena>] <arbre-treball>" +#: builtin/worktree.c msgid "git worktree move <worktree> <new-path>" -msgstr "git worktree move <arbre de treball> <camí-nou>" +msgstr "git worktree move <arbre-treball> <camí-nou>" +#: builtin/worktree.c msgid "git worktree prune [-n] [-v] [--expire <expire>]" msgstr "git worktree prune [-n] [-v] [--expire <expire>]" +#: builtin/worktree.c msgid "git worktree remove [-f] <worktree>" -msgstr "git worktree remove [-f] <worktree>" +msgstr "git worktree remove [-f] <arbre-treball>" +#: builtin/worktree.c msgid "git worktree repair [<path>...]" msgstr "git worktree repair [<camí>...]" +#: builtin/worktree.c msgid "git worktree unlock <worktree>" -msgstr "git worktree unlock <worktree>" +msgstr "git worktree unlock <arbre-treball>" +#: builtin/worktree.c msgid "No possible source branch, inferring '--orphan'" msgstr "No hi ha cap branca d'origen possible, inferint «--orphan»" +#: builtin/worktree.c #, c-format msgid "" "If you meant to create a worktree containing a new unborn branch\n" @@ -13621,6 +17356,7 @@ msgstr "" "\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 unborn branch\n" @@ -13635,24 +17371,30 @@ msgstr "" "\n" " git worktree add --orphan %s\n" +#: builtin/worktree.c #, c-format msgid "Removing %s/%s: %s" msgstr "S'està eliminant %s/%s: %s" +#: builtin/worktree.c msgid "report pruned working trees" msgstr "informa dels arbres de treball podats" +#: builtin/worktree.c msgid "expire working trees older than <time>" msgstr "fes caducar els arbres de treball més antics que <data>" +#: builtin/worktree.c #, c-format msgid "'%s' already exists" msgstr "«%s» ja existeix" +#: builtin/worktree.c #, c-format msgid "unusable worktree destination '%s'" msgstr "destinació de l'arbre de treball no utilitzable «%s»" +#: builtin/worktree.c #, c-format msgid "" "'%s' is a missing but locked worktree;\n" @@ -13662,6 +17404,7 @@ msgstr "" "useu «%s -f -f» per a sobreescriure-ho, o «unlock» i «prune» o «remove» per " "a netejar" +#: builtin/worktree.c #, c-format msgid "" "'%s' is a missing but already registered worktree;\n" @@ -13670,54 +17413,66 @@ msgstr "" "manca «%s» però ja està registrat a l'arbre de treball;\n" "useu «%s» per a sobreescriure-ho, o «prune» o «remove» per a netejar" +#: builtin/worktree.c #, c-format msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly" msgstr "" "no s'ha pogut copiar «%s» a «%s»; «sparse-checkout» pot no funcionar " "correctament" +#: builtin/worktree.c #, c-format msgid "failed to copy worktree config from '%s' to '%s'" msgstr "" "no s'ha pogut copiar la configuració de l'arbre de treball de «%s» a «%s»" +#: builtin/worktree.c #, c-format msgid "failed to unset '%s' in '%s'" msgstr "no s'ha pogut desassignar «%s» a «%s»" +#: builtin/worktree.c #, c-format msgid "could not create directory of '%s'" msgstr "no s'ha pogut crear directori de «%s»" +#: builtin/worktree.c msgid "initializing" msgstr "s'està inicialitzant" +#: builtin/worktree.c #, c-format msgid "could not find created worktree '%s'" msgstr "no s'ha pogut trobar l'arbre de treball creat «%s»" +#: builtin/worktree.c #, c-format msgid "Preparing worktree (new branch '%s')" msgstr "S'està preparant l'arbre de treball (branca nova «%s»)" +#: builtin/worktree.c #, c-format msgid "Preparing worktree (resetting branch '%s'; was at %s)" msgstr "" "S'està preparant l'arbre de treball (s'està reiniciant la branca «%s»; " "estava a %s)" +#: builtin/worktree.c #, c-format msgid "Preparing worktree (checking out '%s')" msgstr "S'està preparant l'arbre de treball (s'està agafant «%s»)" +#: builtin/worktree.c #, c-format msgid "unreachable: invalid reference: %s" msgstr "no accessible: referència no vàlida: %s" +#: builtin/worktree.c #, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "S'està preparant l'arbre de treball (HEAD %s separat)" +#: builtin/worktree.c #, c-format msgid "" "HEAD points to an invalid (or orphaned) reference.\n" @@ -13728,6 +17483,7 @@ msgstr "" "Camí HEAD: «%s»\n" "Contingut HEAD: «%s»" +#: builtin/worktree.c 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" @@ -13735,94 +17491,120 @@ msgstr "" "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" +#: builtin/worktree.c msgid "checkout <branch> even if already checked out in other worktree" msgstr "agafa <branca> encara que sigui agafada en altre arbre de treball" +#: builtin/worktree.c msgid "create a new branch" msgstr "crea una branca nova" +#: builtin/worktree.c msgid "create or reset a branch" msgstr "crea o restableix una branca" +#: builtin/worktree.c msgid "create unborn branch" msgstr "crea una branca no nascuda" +#: builtin/worktree.c msgid "populate the new working tree" msgstr "emplena l'arbre de treball nou" +#: builtin/worktree.c msgid "keep the new working tree locked" msgstr "mantén l'arbre de treball nou bloquejat" +#: builtin/worktree.c msgid "reason for locking" msgstr "raó per a bloquejar" +#: builtin/worktree.c msgid "set up tracking mode (see git-branch(1))" msgstr "configura el mode de seguiment (vegeu git-branch(1))" +#: builtin/worktree.c msgid "try to match the new branch name with a remote-tracking branch" msgstr "" "prova de fer coincidir el nom de la branca nova amb una branca amb seguiment " "remot" +#: builtin/worktree.c diff.c parse-options.c #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "les opcions «%s», «%s», i «%s» no es poden usar juntes" +#: builtin/worktree.c #, c-format msgid "option '%s' and commit-ish cannot be used together" msgstr "opció «%s» i les de comissió no es poden usar juntes" +#: builtin/worktree.c msgid "added with --lock" msgstr "afegit amb --lock" +#: builtin/worktree.c msgid "--[no-]track can only be used if a new branch is created" msgstr "--[no-]track només es pot usar si es crea una branca nova" +#: builtin/worktree.c msgid "show extended annotations and reasons, if available" msgstr "mostra les anotacions esteses i les raons, si estan disponibles" +#: builtin/worktree.c msgid "add 'prunable' annotation to worktrees older than <time>" msgstr "" "afegeix l'anotació «prunable» als arbres de treball més antics que <data>" +#: builtin/worktree.c msgid "terminate records with a NUL character" msgstr "finalitza els registres amb un caràcter NUL" +#: builtin/worktree.c #, c-format msgid "'%s' is not a working tree" msgstr "«%s» no és un arbre de treball" +#: builtin/worktree.c msgid "The main working tree cannot be locked or unlocked" msgstr "No es pot bloquejar ni desbloquejar l'arbre de treball principal" +#: builtin/worktree.c #, c-format msgid "'%s' is already locked, reason: %s" msgstr "«%s» ja està bloquejat, raó: «%s»" +#: builtin/worktree.c #, c-format msgid "'%s' is already locked" msgstr "«%s» ja està bloquejat" +#: builtin/worktree.c #, c-format msgid "'%s' is not locked" msgstr "«%s» no està bloquejat" +#: builtin/worktree.c msgid "working trees containing submodules cannot be moved or removed" msgstr "" "els arbres de treball que contenen submòduls no es poden moure ni eliminar" +#: builtin/worktree.c msgid "force move even if worktree is dirty or locked" msgstr "" "força el moviment encara que l'arbre de treball estigui brut o bloquejat" +#: builtin/worktree.c #, c-format msgid "'%s' is a main working tree" msgstr "«%s» és un arbre de treball principal" +#: builtin/worktree.c #, c-format msgid "could not figure out destination name from '%s'" msgstr "no s'ha pogut deduir el nom de destí des de «%s»" +#: builtin/worktree.c #, c-format msgid "" "cannot move a locked working tree, lock reason: %s\n" @@ -13831,6 +17613,7 @@ msgstr "" "no es pot moure un arbre de treball bloquejat, raó del bloqueig: %s\n" "useu primer «move -f -f» per a sobreescriure'l o desbloquejar-lo primer" +#: builtin/worktree.c msgid "" "cannot move a locked working tree;\n" "use 'move -f -f' to override or unlock first" @@ -13838,31 +17621,38 @@ msgstr "" "no es pot moure un arbre de treball bloquejat;\n" "useu primer «move -f -f» per a sobreescriure'l o desbloquejar-lo primer" +#: builtin/worktree.c #, c-format msgid "validation failed, cannot move working tree: %s" msgstr "la validació ha fallat, no es pot moure l'arbre de treball: %s" +#: builtin/worktree.c #, c-format msgid "failed to move '%s' to '%s'" msgstr "s'ha produït un error en moure «%s» a «%s»" +#: builtin/worktree.c #, c-format msgid "failed to run 'git status' on '%s'" msgstr "no s'ha pogut executar «git status» a «%s»" +#: builtin/worktree.c #, c-format msgid "'%s' contains modified or untracked files, use --force to delete it" msgstr "" "«%s» conté fitxers modificats o no seguits, useu --force per a suprimir-los" +#: builtin/worktree.c #, c-format msgid "failed to run 'git status' on '%s', code %d" msgstr "no s'ha pogut executar «git status» a «%s», codi %d" +#: builtin/worktree.c msgid "force removal even if worktree is dirty or locked" msgstr "" "força l'eliminació encara que l'arbre de treball estigui brut o bloquejat" +#: builtin/worktree.c #, c-format msgid "" "cannot remove a locked working tree, lock reason: %s\n" @@ -13871,6 +17661,7 @@ msgstr "" "no es pot suprimir un arbre de treball bloquejat, raó del bloqueig: %s\n" "useu primer «remove -f -f» per a sobreescriure'l o desbloquejar-lo" +#: builtin/worktree.c msgid "" "cannot remove a locked working tree;\n" "use 'remove -f -f' to override or unlock first" @@ -13878,109 +17669,135 @@ msgstr "" "no es pot suprimir un arbre de treball bloquejat;\n" "useu primer «remove -f -f» per a sobreescriure'l o desbloquejar-lo" +#: builtin/worktree.c #, c-format msgid "validation failed, cannot remove working tree: %s" msgstr "la validació ha fallat, no es pot suprimir l'arbre de treball: %s" +#: builtin/worktree.c #, c-format msgid "repair: %s: %s" msgstr "repara: %s: %s" +#: builtin/worktree.c #, c-format msgid "error: %s: %s" msgstr "error: %s: %s" +#: builtin/write-tree.c msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]" msgstr "git write-tree [--missing-ok] [--prefix=<prefix>/]" +#: builtin/write-tree.c msgid "<prefix>/" msgstr "<prefix>/" +#: builtin/write-tree.c msgid "write tree object for a subdirectory <prefix>" msgstr "escriu l'objecte d'arbre per a un subdirectori <prefix>" +#: builtin/write-tree.c msgid "only useful for debugging" msgstr "només útil per a la depuració" +#: bulk-checkin.c msgid "core.fsyncMethod = batch is unsupported on this platform" msgstr "core.fsyncMethod = batch no és compatible amb aquesta plataforma" +#: bundle-uri.c #, c-format msgid "could not parse bundle list key %s with value '%s'" msgstr "" "no s'ha pogut analitzar la clau de llista de paquets %s amb el valor «%s»" +#: bundle-uri.c #, c-format msgid "bundle list at '%s' has no mode" msgstr "la llista de farcells a «%s» no té mode" +#: bundle-uri.c msgid "failed to create temporary file" msgstr "no s'ha pogut crear un fitxer temporal" +#: bundle-uri.c msgid "insufficient capabilities" msgstr "capacitats insuficients" +#: bundle-uri.c #, c-format msgid "file downloaded from '%s' is not a bundle" msgstr "el fitxer baixat de «%s» no és un paquet" +#: bundle-uri.c msgid "failed to store maximum creation token" msgstr "no s'ha pogut emmagatzemar el testimoni de creació màxim" +#: bundle-uri.c #, c-format msgid "unrecognized bundle mode from URI '%s'" msgstr "no s'ha reconegut el model del farcell de l'URI «%s»" +#: bundle-uri.c #, c-format msgid "exceeded bundle URI recursion limit (%d)" msgstr "s'ha excedit el límit de recursió URI del paquet (%d)" +#: bundle-uri.c #, c-format msgid "failed to download bundle from URI '%s'" msgstr "no s'ha pogut baixar el paquet de l'URI «%s»" +#: bundle-uri.c #, c-format msgid "file at URI '%s' is not a bundle or bundle list" msgstr "el fitxer a l'URI «%s» no és farcell o una llista de farcells" +#: bundle-uri.c #, c-format msgid "bundle-uri: unexpected argument: '%s'" msgstr "bundle-uri: argument inesperat: «%s»" +#: bundle-uri.c msgid "bundle-uri: expected flush after arguments" msgstr "bundle-uri: s'esperava una neteja després dels arguments" +#: bundle-uri.c msgid "bundle-uri: got an empty line" msgstr "bundle-uri: té una línia buida" +#: bundle-uri.c msgid "bundle-uri: line is not of the form 'key=value'" msgstr "bundle-uri: la línia no és de la forma «key=value»" +#: bundle-uri.c msgid "bundle-uri: line has empty key or value" msgstr "bundle-uri: la línia té una clau o un valor buit" +#: bundle.c #, c-format msgid "unrecognized bundle hash algorithm: %s" msgstr "algoritme de resum del farcell desconegut: %s" +#: bundle.c #, c-format msgid "unknown capability '%s'" msgstr "funcionalitat «%s» desconeguda" +#: bundle.c #, c-format msgid "'%s' does not look like a v2 or v3 bundle file" msgstr "«%s» no sembla un fitxer de farcell v2 o v3" +#: bundle.c #, c-format msgid "unrecognized header: %s%s (%d)" msgstr "capçalera no reconeguda: %s%s (%d)" +#: bundle.c msgid "Repository lacks these prerequisite commits:" msgstr "Al repositori li manquen aquestes comissions prerequerides:" -msgid "need a repository to verify a bundle" -msgstr "cal un repositori per a verificar un farcell" - +#: bundle.c msgid "" "some prerequisite commits exist in the object store, but are not connected " "to the repository's history" @@ -13988,685 +17805,904 @@ msgstr "" "hi ha algunes comissions requerides al magatzem d'objectes, però no estan " "connectades a l'historial del repositori" +#: bundle.c #, c-format msgid "The bundle contains this ref:" msgid_plural "The bundle contains these %<PRIuMAX> refs:" msgstr[0] "El farcell conté aquesta referència:" msgstr[1] "El farcell conté aquestes %<PRIuMAX> referències:" +#: bundle.c msgid "The bundle records a complete history." msgstr "El farcell registra una història completa." +#: bundle.c #, c-format msgid "The bundle requires this ref:" msgid_plural "The bundle requires these %<PRIuMAX> refs:" msgstr[0] "El farcell requereix aquesta referència:" msgstr[1] "El farcell requereix aquestes %<PRIuMAX> referències:" +#: bundle.c #, c-format msgid "The bundle uses this hash algorithm: %s" msgstr "El farcell utilitza aquest algoritme de resum: %s" +#: bundle.c #, c-format msgid "The bundle uses this filter: %s" msgstr "El farcell utilitza aquest filtre: %s" +#: bundle.c msgid "unable to dup bundle descriptor" msgstr "no s'ha pogut duplicar el descriptor del farcell" +#: bundle.c msgid "Could not spawn pack-objects" msgstr "No s'ha pogut engendrar el pack-objects" +#: bundle.c msgid "pack-objects died" msgstr "el pack-objects s'ha mort" +#: bundle.c #, c-format msgid "ref '%s' is excluded by the rev-list options" msgstr "les opcions de la llista de revisions exclouen la referència «%s»" +#: bundle.c #, c-format msgid "unsupported bundle version %d" msgstr "versió del farcell no compatible %d" +#: bundle.c #, c-format msgid "cannot write bundle version %d with algorithm %s" msgstr "no es pot escriure la versió del farcell %d amb l'algorisme %s" +#: bundle.c msgid "Refusing to create empty bundle." msgstr "S'està refusant crear un farcell buit." +#: bundle.c #, c-format msgid "cannot create '%s'" msgstr "no es pot crear «%s»" +#: bundle.c msgid "index-pack died" msgstr "l'index-pack s'ha mort" +#: chunk-format.c msgid "terminating chunk id appears earlier than expected" msgstr "" "l'identificador de fragment de finalització apareix abans del que s'esperava" +#: chunk-format.c #, c-format msgid "chunk id %<PRIx32> not %d-byte aligned" -msgstr "ID del fragment %<PRIx32> no alineat %d-byte" +msgstr "ID del fragment %<PRIx32> no alineat a %d-octets" +#: chunk-format.c #, c-format msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" msgstr "desplaçament incorrecte del fragment %<PRIx64> i %<PRIx64>" +#: chunk-format.c #, c-format msgid "duplicate chunk ID %<PRIx32> found" msgstr "s'ha trobat un ID del fragment %<PRIx32> duplicat" +#: chunk-format.c #, c-format msgid "final chunk has non-zero id %<PRIx32>" msgstr "el fragment final té un id %<PRIx32> que no és zero" +#: chunk-format.c msgid "invalid hash version" msgstr "especificació de resum no vàlida" +#: color.c #, c-format msgid "invalid color value: %.*s" msgstr "valor de color no vàlid: %.*s" +#: command-list.h msgid "Add file contents to the index" msgstr "Afegeix els continguts dels fitxers a l'índex" +#: command-list.h msgid "Apply a series of patches from a mailbox" msgstr "Aplica una sèrie de pedaços des d'una bústia de correu" +#: command-list.h msgid "Annotate file lines with commit information" msgstr "Anota les línies del fitxer amb la informació de la comissió" +#: command-list.h msgid "Apply a patch to files and/or to the index" msgstr "Aplica un pedaç a fitxer i/o a l'índex" +#: command-list.h msgid "Import a GNU Arch repository into Git" msgstr "Importa un repositori GNU Arch a Git" +#: command-list.h msgid "Create an archive of files from a named tree" msgstr "Crea un arxiu de fitxers des d'un arbre amb nom" +#: command-list.h msgid "Use binary search to find the commit that introduced a bug" msgstr "Troba per cerca binària el canvi que hagi introduït un defecte" +#: command-list.h msgid "Show what revision and author last modified each line of a file" msgstr "" "Mostra quina revisió i autor ha modificat per últim cop cada línia d'un " "fitxer" +#: command-list.h msgid "List, create, or delete branches" msgstr "Llista, crea o suprimeix branques" +#: command-list.h msgid "Collect information for user to file a bug report" msgstr "Recopila la informació per a l'usuari per a enviar un informe d'error" +#: command-list.h msgid "Move objects and refs by archive" msgstr "Mou els objectes i les referències per arxiu" +#: command-list.h msgid "Provide contents or details of repository objects" msgstr "Proporcioneu el contingut o els detalls dels objectes del repositori" +#: command-list.h msgid "Display gitattributes information" msgstr "Mostra la informació de .gitattributes" +#: command-list.h msgid "Debug gitignore / exclude files" msgstr "Depura gitignore / fitxers d'exclusió" +#: command-list.h msgid "Show canonical names and email addresses of contacts" msgstr "Mostra els noms canònics i les adreces electròniques dels contactes" +#: command-list.h msgid "Ensures that a reference name is well formed" msgstr "Assegura que un nom de referència està ben format" +#: command-list.h msgid "Switch branches or restore working tree files" msgstr "Canvia de branca o restaura els fitxers de l'arbre de treball" +#: command-list.h msgid "Copy files from the index to the working tree" msgstr "Copia fitxers des de l'índex a l'arbre de treball" +#: command-list.h msgid "Find commits yet to be applied to upstream" msgstr "Troba les comissions que encara s'han d'aplicar a la font" +#: command-list.h msgid "Apply the changes introduced by some existing commits" msgstr "Aplica els canvis introduïts per algunes comissions existents" +#: command-list.h msgid "Graphical alternative to git-commit" msgstr "Alternativa gràfica a git-commit" +#: command-list.h msgid "Remove untracked files from the working tree" msgstr "Elimina els fitxers no seguits de l'arbre de treball" +#: command-list.h msgid "Clone a repository into a new directory" msgstr "Clona un repositori a un directori nou" +#: command-list.h msgid "Display data in columns" msgstr "Mostra les dades en columnes" +#: command-list.h msgid "Record changes to the repository" msgstr "Registra els canvis al repositori" +#: command-list.h msgid "Write and verify Git commit-graph files" msgstr "Escriu i verifica els fitxers commit-graph de Git" +#: command-list.h msgid "Create a new commit object" msgstr "Crea un objecte de comissió nou" +#: command-list.h msgid "Get and set repository or global options" msgstr "Obté o estableix opcions de repositori o globals" +#: command-list.h msgid "Count unpacked number of objects and their disk consumption" msgstr "Compta el nombre d'objectes desempaquetats i el seu consum de disc" +#: command-list.h msgid "Retrieve and store user credentials" msgstr "Recupera i desa les credencials d'usuari" +#: command-list.h msgid "Helper to temporarily store passwords in memory" msgstr "Ajudant per a emmagatzemar temporalment les contrasenyes en memòria" +#: command-list.h msgid "Helper to store credentials on disk" msgstr "Ajudant per a emmagatzemar credencials a disc" +#: command-list.h msgid "Export a single commit to a CVS checkout" msgstr "Exporta en una sola comissió a CVS checkout" +#: command-list.h msgid "Salvage your data out of another SCM people love to hate" msgstr "Salveu les vostres dades d'un altre SMC al que la gent li agrada odiar" +#: command-list.h msgid "A CVS server emulator for Git" msgstr "Un emulador de servidor CVS per al Git" +#: command-list.h msgid "A really simple server for Git repositories" msgstr "Un servidor realment senzill per a repositoris Git" +#: command-list.h msgid "Give an object a human readable name based on an available ref" msgstr "" "Dona un nom llegible per a humans basant-se en les referències disponibles" +#: command-list.h msgid "Generate a zip archive of diagnostic information" msgstr "Genera un arxiu zip d'informació de diagnòstic" +#: command-list.h msgid "Show changes between commits, commit and working tree, etc" msgstr "" "Mostra els canvis entre comissions, la comissió i l'arbre de treball, etc" +#: command-list.h msgid "Compares files in the working tree and the index" msgstr "Compara fitxers en l'arbre de treball i l'índex" +#: command-list.h msgid "Compare a tree to the working tree or index" msgstr "Compara un arbre amb l'arbre de treball o l'índex" +#: command-list.h msgid "Compares the content and mode of blobs found via two tree objects" msgstr "" "Compara el contingut i el mode dels blobs trobats a través de dos objectes " "d'arbre" +#: command-list.h msgid "Show changes using common diff tools" msgstr "Mostra els canvis usant eines diff comunes" +#: command-list.h msgid "Git data exporter" msgstr "Exportador de dades del Git" +#: command-list.h msgid "Backend for fast Git data importers" msgstr "Rerefons per a importadors ràpids de dades de Git" +#: command-list.h msgid "Download objects and refs from another repository" msgstr "Baixa objectes i referències d'un altre repositori" +#: command-list.h msgid "Receive missing objects from another repository" msgstr "Rep els objectes que manquen des d'un altre repositori" +#: command-list.h msgid "Rewrite branches" msgstr "Torna a escriure les branques" +#: command-list.h msgid "Produce a merge commit message" msgstr "Produeix un missatge de comissió de fusió" +#: command-list.h msgid "Output information on each ref" msgstr "Mostra la informació en cada referència" +#: command-list.h msgid "Run a Git command on a list of repositories" msgstr "Executa una ordre Git en una llista de repositoris" +#: command-list.h msgid "Prepare patches for e-mail submission" msgstr "Prepara pedaços per a enviar-los per correu electrònic" +#: command-list.h msgid "Verifies the connectivity and validity of the objects in the database" msgstr "Verifica la connectivitat i validesa dels objectes a la base de dades" +#: command-list.h msgid "Cleanup unnecessary files and optimize the local repository" msgstr "Neteja els fitxers innecessaris i optimitza el repositori local" +#: command-list.h msgid "Extract commit ID from an archive created using git-archive" msgstr "Extreu l'ID de la comissió d'un arxiu creat amb el git-archive" +#: command-list.h msgid "Print lines matching a pattern" msgstr "Imprimeix les línies coincidents amb un patró" +#: command-list.h msgid "A portable graphical interface to Git" msgstr "Una interfície gràfica portable per al Git" +#: command-list.h msgid "Compute object ID and optionally create an object from a file" msgstr "" "Calcula l'ID de l'objecte i opcionalment crea un objecte des del fitxer" +#: command-list.h msgid "Display help information about Git" msgstr "Mostra informació d'ajuda del Git" +#: command-list.h msgid "Run git hooks" msgstr "Executa els lligams del git" +#: command-list.h msgid "Server side implementation of Git over HTTP" msgstr "Implementació al servidor del Git sobre HTTP" +#: command-list.h msgid "Download from a remote Git repository via HTTP" msgstr "Baixa des d'un repositori Git remot via HTTP" +#: command-list.h msgid "Push objects over HTTP/DAV to another repository" msgstr "Pujar objectes sobre HTTP/DAV a un altre repositori" +#: command-list.h msgid "Send a collection of patches from stdin to an IMAP folder" msgstr "" "Envia una col·lecció de pedaços des de l'entrada estàndard a una carpeta IMAP" +#: command-list.h msgid "Build pack index file for an existing packed archive" msgstr "" "Construeix el fitxer d'índex del paquet per a un arxiu empaquetat existent" +#: command-list.h msgid "Create an empty Git repository or reinitialize an existing one" msgstr "Crea un repositori de Git buit o reinicialitza un existent" +#: command-list.h msgid "Instantly browse your working repository in gitweb" msgstr "Navegueu instantàniament pel vostre repositori de treball a gitweb" +#: command-list.h msgid "Add or parse structured information in commit messages" msgstr "" "Afegeix o analitza la informació estructurada en els missatges de comissió" +#: command-list.h msgid "Show commit logs" msgstr "Mostra els registres de comissió" +#: command-list.h msgid "Show information about files in the index and the working tree" msgstr "Mostra informació sobre els fitxers a l'índex i a l'arbre de treball" +#: command-list.h msgid "List references in a remote repository" msgstr "Mostra les referències d'un repositori remot" +#: command-list.h msgid "List the contents of a tree object" msgstr "Mostra els continguts d'un objecte de l'arbre" +#: command-list.h msgid "Extracts patch and authorship from a single e-mail message" msgstr "Extreu el pedaç i l'autoria d'un sol missatge de correu electrònic" +#: command-list.h msgid "Simple UNIX mbox splitter program" msgstr "Programa de divisió mbox simple per a UNIX" +#: command-list.h msgid "Run tasks to optimize Git repository data" msgstr "Executa tasques per a optimitzar les dades del repositori Git" +#: command-list.h msgid "Join two or more development histories together" msgstr "Uneix dues o més històries de desenvolupament" +#: command-list.h msgid "Find as good common ancestors as possible for a merge" msgstr "Troba els millors avantpassats comuns possibles per a una fusió" +#: command-list.h msgid "Run a three-way file merge" msgstr "Executa una fusió de fitxers de tres vies" +#: command-list.h msgid "Run a merge for files needing merging" msgstr "Executa una fusió per als fitxers que cal fusionar" +#: command-list.h msgid "The standard helper program to use with git-merge-index" msgstr "El programa d'ajuda estàndard a utilitzar amb git-merge-index" +#: command-list.h msgid "Perform merge without touching index or working tree" msgstr "Realitza la fusió sense tocar l'índex o l'arbre de treball" +#: command-list.h msgid "Run merge conflict resolution tools to resolve merge conflicts" msgstr "" "Executa eines de resolució de conflictes per a resoldre conflictes de fusió" +#: command-list.h msgid "Creates a tag object with extra validation" msgstr "Crea un objecte etiqueta amb validació addicional" +#: command-list.h msgid "Build a tree-object from ls-tree formatted text" msgstr "Construeix un objecte en arbre a partir de text formatat amb ls-tree" +#: command-list.h msgid "Write and verify multi-pack-indexes" msgstr "Escriu i verifica els índexs multipaquet" +#: command-list.h 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" +#: command-list.h msgid "Find symbolic names for given revs" msgstr "Cerca noms simbòlics per a les revisions donades" +#: command-list.h msgid "Add or inspect object notes" msgstr "Afegeix o inspecciona notes de l'objecte" +#: command-list.h msgid "Import from and submit to Perforce repositories" msgstr "Importa des de i envia a repositoris Perforce" +#: command-list.h msgid "Create a packed archive of objects" msgstr "Crea un arxiu empaquetat d'objectes" +#: command-list.h msgid "Find redundant pack files" msgstr "Troba fitxers empaquetats redundants" +#: command-list.h msgid "Pack heads and tags for efficient repository access" msgstr "" "Empaqueta els caps i les etiquetes per a un accés eficient al repositori" +#: command-list.h msgid "Compute unique ID for a patch" msgstr "Calcula un identificador únic per a cada pedaç" +#: command-list.h msgid "Prune all unreachable objects from the object database" msgstr "Poda tots els objectes no accessibles de la base de dades d'objectes" +#: command-list.h msgid "Remove extra objects that are already in pack files" msgstr "Elimina els objectes extres que ja estan en fitxers empaquetats" +#: command-list.h msgid "Fetch from and integrate with another repository or a local branch" msgstr "Obtén i integra amb un altre repositori o una branca local" +#: command-list.h msgid "Update remote refs along with associated objects" msgstr "" "Actualitza les referències remotes juntament amb els objectes associats" +#: command-list.h msgid "Applies a quilt patchset onto the current branch" msgstr "Aplica un conjunt de pedaços a la branca actual" +#: command-list.h msgid "Compare two commit ranges (e.g. two versions of a branch)" msgstr "Compara dos rangs de comissions (p. ex. dues versions d'una branca)" +#: command-list.h msgid "Reads tree information into the index" msgstr "Llegeix la informació de l'arbre a l'índex" +#: command-list.h msgid "Reapply commits on top of another base tip" msgstr "Torna a aplicar les comissions sobre un altre punt de basament" +#: command-list.h msgid "Receive what is pushed into the repository" msgstr "Rep el que s'envia al repositori" +#: command-list.h msgid "Manage reflog information" msgstr "Gestiona la informació del registre de referències" +# Baix nivell / nivell baix +#: command-list.h +msgid "Low-level access to refs" +msgstr "Accés de baix nivell a referències" + +#: command-list.h msgid "Manage set of tracked repositories" msgstr "Gestiona el conjunt de repositoris seguits" +#: command-list.h msgid "Pack unpacked objects in a repository" msgstr "Empaqueta els objectes desempaquetats en un repositori" +#: command-list.h msgid "Create, list, delete refs to replace objects" msgstr "Crea, llista i esborra referències per a substituir objectes" +#: command-list.h 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" +#: command-list.h msgid "Generates a summary of pending changes" msgstr "Genera un resum dels canvis pendents" +#: command-list.h msgid "Reuse recorded resolution of conflicted merges" msgstr "Reutilitza la resolució registrada dels conflictes de fusió" +#: command-list.h msgid "Reset current HEAD to the specified state" msgstr "Restableix la HEAD actual a l'estat especificat" +#: command-list.h msgid "Restore working tree files" msgstr "Restaura els fitxers de l'arbre de treball" +#: command-list.h msgid "Lists commit objects in reverse chronological order" msgstr "Mostra les comissions en ordre topològic invers" +#: command-list.h msgid "Pick out and massage parameters" msgstr "Trieu i personalitzeu els paràmetres" +#: command-list.h msgid "Revert some existing commits" msgstr "Reverteix comissions existents" +#: command-list.h msgid "Remove files from the working tree and from the index" msgstr "Elimina fitxers de l'arbre de treball i de l'índex" +#: command-list.h msgid "Send a collection of patches as emails" msgstr "Envia una col·lecció de pedaços com a correus electrònics" +#: command-list.h msgid "Push objects over Git protocol to another repository" msgstr "Puja objectes sobre el protocol Git a un altre repositori" +#: command-list.h msgid "Git's i18n setup code for shell scripts" msgstr "" "Codi de configuració i18n del Git per als scripts de l'intèrpret d'ordres" +#: command-list.h msgid "Common Git shell script setup code" msgstr "Codi de scripts de configuració comuns pel Git shell" +#: command-list.h msgid "Restricted login shell for Git-only SSH access" msgstr "Intèrpret d'ordres d'entrada restringit només per a accés SSH al Git" +#: command-list.h msgid "Summarize 'git log' output" msgstr "Resumeix la sortida «git log»" +#: command-list.h msgid "Show various types of objects" msgstr "Mostra diversos tipus d'objectes" +#: command-list.h msgid "Show branches and their commits" msgstr "Mostra les branques i les seves comissions" +#: command-list.h msgid "Show packed archive index" msgstr "Mostra l'índex d'arxius empaquetat" +#: command-list.h msgid "List references in a local repository" msgstr "Llista les referències en un repositori local" +#: command-list.h msgid "Reduce your working tree to a subset of tracked files" msgstr "Redueix l'arbre de treball a un subconjunt de fitxers seguits" +#: command-list.h msgid "Add file contents to the staging area" msgstr "Afegeix el contingut del fitxer a l'àrea de «staging»" +#: command-list.h msgid "Stash the changes in a dirty working directory away" msgstr "Fes «stash» dels canvis en un directori de treball brut" +#: command-list.h msgid "Show the working tree status" msgstr "Mostra l'estat de l'arbre de treball" +#: command-list.h msgid "Remove unnecessary whitespace" msgstr "Elimina l'espai en blanc innecessari" +#: command-list.h msgid "Initialize, update or inspect submodules" msgstr "Inicialitza, actualitza o inspecciona submòduls" +#: command-list.h msgid "Bidirectional operation between a Subversion repository and Git" msgstr "Operació bidireccional entre un repositori a Subversion i Git" +#: command-list.h msgid "Switch branches" msgstr "Commuta entre branques" +#: command-list.h msgid "Read, modify and delete symbolic refs" msgstr "Llegeix, modifica i suprimeix referències simbòliques" +#: command-list.h msgid "Create, list, delete or verify a tag object signed with GPG" msgstr "" "Crea, llista, suprimeix o verifica un objecte d'etiqueta signat amb GPG" +#: command-list.h msgid "Creates a temporary file with a blob's contents" msgstr "Crea un fitxer temporal amb els continguts dels blobs" +#: command-list.h msgid "Unpack objects from a packed archive" msgstr "Desempaqueta objectes d'un arxiu empaquetat" +#: command-list.h msgid "Register file contents in the working tree to the index" msgstr "Registra els continguts del fitxer en l'arbre de treball a l'índex" +#: command-list.h msgid "Update the object name stored in a ref safely" msgstr "" "Actualitza el nom de l'objecte emmagatzemat en una referència de forma segura" +#: command-list.h msgid "Update auxiliary info file to help dumb servers" msgstr "" "Actualitza el fitxer d'informació auxiliar per a ajudar als servidors ximples" +#: command-list.h msgid "Send archive back to git-archive" msgstr "Envia l'arxiu de tornada al git-archive" +#: command-list.h msgid "Send objects packed back to git-fetch-pack" msgstr "Envia els objectes empaquetats de tornada al git-fetch-pack" +#: command-list.h msgid "Show a Git logical variable" msgstr "Mostra una variable lògica del Git" +#: command-list.h msgid "Check the GPG signature of commits" msgstr "Verifica la signatura GPG de les comissions" +#: command-list.h msgid "Validate packed Git archive files" msgstr "Valida els fitxers d'arxius Git empaquetats" +#: command-list.h msgid "Check the GPG signature of tags" msgstr "Verifica la signatura GPG de les etiquetes" +#: command-list.h msgid "Display version information about Git" msgstr "Mostra informació de la versió del Git" +#: command-list.h msgid "Show logs with differences each commit introduces" msgstr "Mostra els registres amb les diferències que introdueix cada comissió" +#: command-list.h msgid "Manage multiple working trees" msgstr "Gestiona múltiples arbres de treball" +#: command-list.h msgid "Create a tree object from the current index" msgstr "Crea un objecte arbre des de l'índex actual" +#: command-list.h msgid "Defining attributes per path" msgstr "La definició d'atributs per camí" +#: command-list.h msgid "Git command-line interface and conventions" msgstr "Interfície i convencions de la línia d'ordres del Git" +#: command-list.h msgid "A Git core tutorial for developers" msgstr "Un tutorial bàsic del Git per a desenvolupadors" +#: command-list.h msgid "Providing usernames and passwords to Git" msgstr "Proporcionar noms d'usuari i contrasenyes a Git" +#: command-list.h msgid "Git for CVS users" msgstr "Git per a usuaris del CVS" +#: command-list.h msgid "Tweaking diff output" msgstr "Ajustament de la sortida de diferències" +#: command-list.h msgid "A useful minimum set of commands for Everyday Git" msgstr "Un conjunt mínim útil d'ordres diàries del Git" +#: command-list.h msgid "Frequently asked questions about using Git" msgstr "Preguntes freqüents sobre l'ús del Git" +#: command-list.h msgid "The bundle file format" msgstr "El format del fitxer de farcell" +#: command-list.h msgid "Chunk-based file formats" msgstr "Formats de fitxer basats en blocs" +#: command-list.h msgid "Git commit-graph format" msgstr "Format de graf de comissions del Git" +#: command-list.h msgid "Git index format" msgstr "Format de l'índex del Git" +#: command-list.h msgid "Git pack format" msgstr "format de paquet del Git" +#: command-list.h msgid "Git cryptographic signature formats" msgstr "Formats de signatura criptogràfica del Git" +#: command-list.h msgid "A Git Glossary" msgstr "Un glossari de Git" +#: command-list.h msgid "Hooks used by Git" msgstr "Lligams utilitzats pel Git" +#: command-list.h msgid "Specifies intentionally untracked files to ignore" msgstr "Especifica els fitxers intencionalment no seguits a ignorar" +#: command-list.h msgid "The Git repository browser" msgstr "El navegador de repositoris Git" +#: command-list.h msgid "Map author/committer names and/or E-Mail addresses" msgstr "Assigna noms d'autor i comitent i/o adreces de correu electrònic" +#: command-list.h msgid "Defining submodule properties" msgstr "La definició de les propietats de submòduls" +#: command-list.h msgid "Git namespaces" msgstr "Espais de noms del Git" +#: command-list.h msgid "Protocol v0 and v1 capabilities" msgstr "Capacitats de protocol v0 i v1" +#: command-list.h msgid "Things common to various protocols" msgstr "Coses comunes en diversos protocols" +#: command-list.h msgid "Git HTTP-based protocols" msgstr "Protocols basats en HTTP del Git" +#: command-list.h msgid "How packs are transferred over-the-wire" msgstr "Com es transfereixen els paquets en la xarxa" +#: command-list.h msgid "Git Wire Protocol, Version 2" msgstr "Protocol Git Wire, versió 2" +#: command-list.h msgid "Helper programs to interact with remote repositories" msgstr "Programes d'ajuda per a interactuar amb repositoris remots" +#: command-list.h msgid "Git Repository Layout" msgstr "Disposició del repositori del Git" +#: command-list.h msgid "Specifying revisions and ranges for Git" msgstr "L'especificació de revisions i rangs per al Git" +#: command-list.h msgid "Mounting one repository inside another" msgstr "Muntant un repositori dins un altre" +#: command-list.h msgid "A tutorial introduction to Git" msgstr "Un tutorial d'introducció al Git" +#: command-list.h msgid "A tutorial introduction to Git: part two" msgstr "Un tutorial d'introducció al Git: segona part" +#: command-list.h msgid "Git web interface (web frontend to Git repositories)" msgstr "Interfície web del Git (interfície web pels repositoris Git)" +#: command-list.h msgid "An overview of recommended workflows with Git" msgstr "Una visió de conjunt de fluxos de treball recomanats amb Git" +#: command-list.h msgid "A tool for managing large Git repositories" msgstr "Una eina per a gestionar dipòsits Git grans" +#: commit-graph.c msgid "commit-graph file is too small" msgstr "el fitxer del graf de comissions és massa petit" +#: commit-graph.c 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" +#: commit-graph.c msgid "commit-graph fanout values out of order" msgstr "valors de graf de comissions de «fanout» estan fora d'ordre" +#: commit-graph.c msgid "commit-graph OID lookup chunk is the wrong size" msgstr "el fragment de cerca OID és de mida incorrecta" +#: commit-graph.c msgid "commit-graph commit data chunk is wrong size" msgstr "el fragment de dades del graf de comissions és de mida incorrecta" +#: commit-graph.c msgid "commit-graph generations chunk is wrong size" msgstr "" "el fragment de les generacions del graf de comissions és de mida incorrecta" +#: commit-graph.c 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" +#: commit-graph.c #, c-format msgid "" "ignoring too-small changed-path chunk (%<PRIuMAX> < %<PRIuMAX>) in commit-" @@ -14675,107 +18711,144 @@ msgstr "" "s'ignorarà un fragment massa petit de camí canviat (%<PRIuMAX> < %<PRIuMAX>) " "al fitxer del graf de comissions" +#: commit-graph.c #, c-format msgid "commit-graph signature %X does not match signature %X" msgstr "" "la signatura del graf de comissions %X no coincideix amb la signatura %X" +#: commit-graph.c #, c-format msgid "commit-graph version %X does not match version %X" msgstr "la versió del graf de comissions %X no coincideix amb la versió %X" +#: commit-graph.c #, c-format msgid "commit-graph hash version %X does not match version %X" msgstr "" "la versió del resum del graf de comissions %X no coincideix amb la versió %X" +#: commit-graph.c #, c-format 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" +#: commit-graph.c 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" +#: commit-graph.c 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" +#: commit-graph.c 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" +#: commit-graph.c +#, c-format +msgid "" +"disabling Bloom filters for commit-graph layer '%s' due to incompatible " +"settings" +msgstr "" +"s'han inhabilitat els filtres de Bloom per a la capa del graf de comissions " +"«%s»\n" +"perquè els paràmetres són incompatibles" + +#: commit-graph.c msgid "commit-graph has no base graphs chunk" msgstr "el fragment del graf de comissions no té grafs de base" +#: commit-graph.c msgid "commit-graph base graphs chunk is too small" msgstr "el fragment de grafs base de la gràfica de comissió és massa petit" +#: commit-graph.c msgid "commit-graph chain does not match" msgstr "la cadena del graf de comissions no coincideix" +#: commit-graph.c #, c-format msgid "commit count in base graph too high: %<PRIuMAX>" msgstr "el nombre de comissions en el graf base és massa alt: %<PRIuMAX>" +#: commit-graph.c msgid "commit-graph chain file too small" msgstr "el fitxer de cadena del graf de comissions és massa petit" +#: commit-graph.c #, c-format msgid "invalid commit-graph chain: line '%s' not a hash" msgstr "" "la cadena del graf de comissions no és vàlida: la línia «%s» no és un hash" +#: commit-graph.c msgid "unable to find all commit-graph files" msgstr "no es poden trobar tots els fitxers del graf de comissions" +#: commit-graph.c msgid "invalid commit position. commit-graph is likely corrupt" msgstr "" "posició de la comissió no vàlida. Probablement el graf de comissions està " "malmès" +#: commit-graph.c #, c-format msgid "could not find commit %s" msgstr "no s'ha pogut trobar la comissió %s" +#: commit-graph.c msgid "commit-graph requires overflow generation data but has none" msgstr "" "el graf de comissions requereix dades de generació de desbordaments però no " "en té cap" +#: commit-graph.c msgid "commit-graph overflow generation data is too small" msgstr "" "les dades de generació de desbordament del graf de comissions són massa " "petites" +#: commit-graph.c msgid "commit-graph extra-edges pointer out of bounds" msgstr "punter de vores extra del graf de comissió està fora dels límits" +#: commit-graph.c msgid "Loading known commits in commit graph" msgstr "S'estan carregant comissions conegudes al graf de comissions" +#: commit-graph.c msgid "Expanding reachable commits in commit graph" msgstr "S'estan expandint les comissions abastables al graf de comissions" +#: commit-graph.c msgid "Clearing commit marks in commit graph" msgstr "S'estan esborrant les marques de comissions al graf de comissions" +#: commit-graph.c msgid "Computing commit graph topological levels" msgstr "S'estan calculant els nivells topològics del graf de comissions" +#: commit-graph.c msgid "Computing commit graph generation numbers" msgstr "S'estan calculant els nombres de generació del graf de comissions" +#: commit-graph.c msgid "Computing commit changed paths Bloom filters" msgstr "" -"S'estan calculant els canvis les rutes de la comissió en els filtres Bloom" +"S'estan calculant els canvis les rutes de la comissió en els filtres de Bloom" +#: commit-graph.c msgid "Collecting referenced commits" msgstr "S'estan recollint els objectes referenciats" +#: commit-graph.c #, c-format msgid "Finding commits for commit graph in %<PRIuMAX> pack" msgid_plural "Finding commits for commit graph in %<PRIuMAX> packs" @@ -14784,128 +18857,166 @@ msgstr[0] "" msgstr[1] "" "S'estan cercant les comissions pel graf de comissions en %<PRIuMAX> paquets" +#: commit-graph.c #, c-format msgid "error adding pack %s" msgstr "error en afegir paquet %s" +#: commit-graph.c #, c-format msgid "error opening index for %s" msgstr "s'ha produït un error en obrir l'índex per «%s»" +#: commit-graph.c msgid "Finding commits for commit graph among packed objects" msgstr "" "S'estan cercant les comissions pel graf de comissions entre els objectes " "empaquetats" +#: commit-graph.c msgid "Finding extra edges in commit graph" msgstr "S'estan cercant les vores addicionals al graf de comissions" +#: commit-graph.c msgid "failed to write correct number of base graph ids" msgstr "" "s'ha produït un error en escriure el nombre correcte d'ids base del graf" +#: commit-graph.c msgid "unable to create temporary graph layer" msgstr "no s'ha pogut crear una capa de graf temporal" +#: commit-graph.c midx-write.c #, c-format msgid "unable to adjust shared permissions for '%s'" msgstr "no s'han pogut ajustar els permisos compartits per a «%s»" +#: commit-graph.c #, c-format msgid "Writing out commit graph in %d pass" msgid_plural "Writing out commit graph in %d passes" msgstr[0] "S'està escrivint el graf de comissions en %d pas" msgstr[1] "S'està escrivint el graf de comissions en %d passos" +#: commit-graph.c msgid "unable to open commit-graph chain file" msgstr "no s'ha pogut obrir el fitxer d'encadenament del graf de comissions" +#: commit-graph.c msgid "failed to rename base commit-graph file" msgstr "no s'ha pogut canviar el nom del fitxer base del graf de comissions" +#: commit-graph.c msgid "failed to rename temporary commit-graph file" msgstr "" "no s'ha pogut canviar el nom del fitxer temporal del graf de comissions" +#: commit-graph.c #, c-format msgid "cannot merge graphs with %<PRIuMAX>, %<PRIuMAX> commits" msgstr "no es poden fusionar els gràfics amb %<PRIuMAX>, %<PRIuMAX>entregues" +#: commit-graph.c #, c-format msgid "cannot merge graph %s, too many commits: %<PRIuMAX>" msgstr "no es pot fusionar el graf %s, hi ha massa comissions: %<PRIuMAX>" +#: commit-graph.c msgid "Scanning merged commits" msgstr "S'estan escanejant les comissions fusionades" +#: commit-graph.c msgid "Merging commit-graph" msgstr "S'està fusionant el graf de comissions" +#: commit-graph.c msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled" msgstr "" "s'està intentant escriure un graf de comissions, però «core.commitGraph» " "està desactivat" +#: commit-graph.c +#, c-format +msgid "" +"attempting to write a commit-graph, but 'commitGraph." +"changedPathsVersion' (%d) is not supported" +msgstr "" +"s'ha intentat escriure un graf de comissió, però no s'admet 'commitGraph." +"changedPathsVersion' (%d)" + +#: commit-graph.c msgid "too many commits to write graph" msgstr "massa comissions per a escriure un graf" +#: commit-graph.c msgid "the commit-graph file has incorrect checksum and is likely corrupt" msgstr "" "el fitxer commit-graph (graf de comissions) té una suma de verificació " "incorrecta i probablement és corrupte" +#: commit-graph.c #, c-format msgid "commit-graph has incorrect OID order: %s then %s" msgstr "el graf de comissions té una ordre OID incorrecta; %s llavors %s" +#: commit-graph.c #, c-format msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u" msgstr "" "el graf de comissions té un valor de «fanout» incorrecte: fanout[%d] = %u != " "%u" +#: commit-graph.c #, c-format msgid "failed to parse commit %s from commit-graph" msgstr "" "s'ha produït un error en analitzar la comissió %s del graf de comissions" +#: commit-graph.c #, c-format msgid "failed to parse commit %s from object database for commit-graph" msgstr "" "no s'han pogut analitzar la comissió %s de la base de dades d'objectes per " "al graf de comissions" +#: commit-graph.c #, c-format msgid "root tree OID for commit %s in commit-graph is %s != %s" msgstr "" "OID de l'arbre arrel per a comissions %s en el graf de comissions és %s != %s" +#: commit-graph.c #, c-format msgid "commit-graph parent list for commit %s is too long" msgstr "" "la llista de pares del graf de comissions per a la comissió %s és massa " "llarga" +#: commit-graph.c #, c-format msgid "commit-graph parent for %s is %s != %s" msgstr "el pare pel graf de comissions %s és %s != %s" +#: commit-graph.c #, c-format msgid "commit-graph parent list for commit %s terminates early" msgstr "la llista pare del graf de comissions per %s acaba aviat" +#: commit-graph.c #, 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> < " "%<PRIuMAX>" +#: commit-graph.c #, c-format msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" msgstr "" "la data d'enviament per a la comissió %s en el graf de comissions és " "%<PRIuMAX> != %<PRIuMAX>" +#: commit-graph.c #, c-format msgid "" "commit-graph has both zero and non-zero generations (e.g., commits '%s' and " @@ -14914,13 +19025,21 @@ msgstr "" "El graf de comissió té tant generacions zero com no nul·les (p. ex., " "comissions «%s» i «%s»)" +#: commit-graph.c msgid "Verifying commits in commit graph" msgstr "S'estan verificant les comissions al graf de comissions" +#: commit-reach.c sequencer.c +#, c-format +msgid "could not parse commit %s" +msgstr "no s'ha pogut analitzar la comissió %s" + +#: commit.c #, c-format msgid "%s %s is not a commit!" msgstr "%s %s no és una comissió!" +#: commit.c msgid "" "Support for <GIT_DIR>/info/grafts is deprecated\n" "and will be removed in a future Git version.\n" @@ -14940,28 +19059,34 @@ msgstr "" "Desactiveu aquest missatge executant\n" "«git config advice.graftFileDeprecated false»" +#: commit.c #, 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" +#: commit.c #, 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." +#: commit.c #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." msgstr "La comissió %s té una signatura GPG incorrecta suposadament de %s." +#: commit.c #, c-format msgid "Commit %s does not have a GPG signature." msgstr "La comissió %s no té signatura GPG." +#: commit.c #, c-format msgid "Commit %s has a good GPG signature by %s\n" msgstr "La comissió %s té una signatura GPG bona de %s\n" +#: commit.c msgid "" "Warning: commit message did not conform to UTF-8.\n" "You may want to amend it after fixing the message, or set the config\n" @@ -14972,203 +19097,260 @@ msgstr "" "la variable de configuració i18n.commitencoding a la codificació que\n" "usi el vostre projecte.\n" +#: compat/compiler.h msgid "no compiler information available\n" msgstr "no hi ha informació disponible del compilador\n" +#: compat/compiler.h msgid "no libc information available\n" msgstr "no hi ha informació disponible de libc\n" +#: compat/disk.h #, c-format msgid "could not determine free disk size for '%s'" msgstr "no s'ha pogut determinar l'espai de disc lliure per a «%s»" +#: compat/disk.h #, c-format msgid "could not get info for '%s'" msgstr "no s'ha pogut obtenir la informació per a «%s»" +#: compat/fsmonitor/fsm-health-win32.c #, c-format msgid "[GLE %ld] health thread could not open '%ls'" msgstr "[GLE %ld] el fil de salut no ha pogut obrir «%ls»" +#: compat/fsmonitor/fsm-health-win32.c #, c-format msgid "[GLE %ld] health thread getting BHFI for '%ls'" msgstr "[GLE %ld] s'està obtenint BHFI del fil de salut per a «%ls»" +#: compat/fsmonitor/fsm-health-win32.c compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "could not convert to wide characters: '%s'" msgstr "no s'ha pogut convertir a caràcters amples: «%s»" +#: compat/fsmonitor/fsm-health-win32.c #, c-format msgid "BHFI changed '%ls'" msgstr "S'ha canviat BHFI «%ls»" +#: compat/fsmonitor/fsm-health-win32.c #, c-format msgid "unhandled case in 'has_worktree_moved': %d" msgstr "cas no gestionat a «has_worktree_moved»: %d" +#: compat/fsmonitor/fsm-health-win32.c #, c-format msgid "health thread wait failed [GLE %ld]" msgstr "ha fallat l'espera del fil de salut [GLE %ld]" +#: compat/fsmonitor/fsm-ipc-darwin.c #, c-format msgid "Invalid path: %s" msgstr "Camí no vàlid: «%s»" +#: compat/fsmonitor/fsm-listen-darwin.c msgid "Unable to create FSEventStream." msgstr "No s'ha pogut crear el FSEventStream." +#: compat/fsmonitor/fsm-listen-darwin.c msgid "Failed to start the FSEventStream" msgstr "No s'ha pogut iniciar el FSEventStream" +#: compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "[GLE %ld] could not convert path to UTF-8: '%.*ls'" msgstr "[GLE %ld] no s'ha pogut convertir el camí a UTF-8: «%.*ls»" +#: compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "[GLE %ld] could not watch '%s'" msgstr "[GLE %ld] no s'ha pogut vigilar «%s»" +#: compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "[GLE %ld] could not get longname of '%s'" msgstr "[GLE %ld] no s'ha pogut obtenir el nom llarg de «%s»" +#: compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "ReadDirectoryChangedW failed on '%s' [GLE %ld]" msgstr "Ha fallat ReadDirectoryChangedW a «%s» [GLE %ld]" +#: compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "GetOverlappedResult failed on '%s' [GLE %ld]" msgstr "Ha fallat GetOverlappedResult a «%s» [GLE %ld]" +#: compat/fsmonitor/fsm-listen-win32.c #, c-format msgid "could not read directory changes [GLE %ld]" msgstr "no s'han pogut llegir els canvis de directori [GLE %ld]" +#: compat/fsmonitor/fsm-path-utils-darwin.c #, c-format msgid "opendir('%s') failed" msgstr "ha fallat opendir(«%s»)" +#: compat/fsmonitor/fsm-path-utils-darwin.c #, c-format msgid "lstat('%s') failed" msgstr "ha fallat lstat(«%s»)" +#: compat/fsmonitor/fsm-path-utils-darwin.c #, c-format msgid "strbuf_readlink('%s') failed" msgstr "ha fallat strbuf_readlink(«%s»)" +#: compat/fsmonitor/fsm-path-utils-darwin.c #, c-format msgid "closedir('%s') failed" msgstr "ha fallat closedir(«%s»)" +#: compat/fsmonitor/fsm-path-utils-win32.c #, c-format msgid "[GLE %ld] unable to open for read '%ls'" msgstr "[GLE %ld] no s'ha pogut obrir per a llegir «%ls»" +#: compat/fsmonitor/fsm-path-utils-win32.c #, c-format msgid "[GLE %ld] unable to get protocol information for '%ls'" msgstr "[GLE %ld] no s'ha pogut obtenir la informació del protocol per a «%ls»" +#: compat/mingw.c #, c-format msgid "failed to copy SID (%ld)" msgstr "no s'ha pogut copiar el SID (%ld)" +#: compat/mingw.c #, c-format msgid "failed to get owner for '%s' (%ld)" msgstr "no s'ha pogut obtenir el propietari de «%s» (%ld)" +#: compat/obstack.c msgid "memory exhausted" msgstr "memòria esgotada" +#: compat/regex/regcomp.c msgid "Success" msgstr "Èxit" +#: compat/regex/regcomp.c msgid "No match" msgstr "Cap coincidència" +#: compat/regex/regcomp.c msgid "Invalid regular expression" msgstr "Expressió regular no vàlida" +#: compat/regex/regcomp.c msgid "Invalid collation character" msgstr "El caràcter de col·lació no és vàlid" +#: compat/regex/regcomp.c msgid "Invalid character class name" msgstr "Nom de la classe del caràcter no vàlid" +#: compat/regex/regcomp.c msgid "Trailing backslash" msgstr "Barra inversa del final" +#: compat/regex/regcomp.c msgid "Invalid back reference" msgstr "Referència anterior no vàlida" +#: compat/regex/regcomp.c msgid "Unmatched [ or [^" msgstr "[ o [^ no emparellat" +#: compat/regex/regcomp.c msgid "Unmatched ( or \\(" msgstr "( o \\( no emparellat" +#: compat/regex/regcomp.c msgid "Unmatched \\{" msgstr "\\{ no emparellat" +#: compat/regex/regcomp.c msgid "Invalid content of \\{\\}" msgstr "Contingut no vàlid de \\{\\}" +#: compat/regex/regcomp.c msgid "Invalid range end" msgstr "Fi d'interval no vàlid" +#: compat/regex/regcomp.c msgid "Memory exhausted" msgstr "Memòria esgotada" +#: compat/regex/regcomp.c msgid "Invalid preceding regular expression" msgstr "Expressió regular anterior no vàlida" +#: compat/regex/regcomp.c msgid "Premature end of regular expression" msgstr "Fi prematur d'expressió regular" +#: compat/regex/regcomp.c msgid "Regular expression too big" msgstr "Expressió regular és massa gran" +#: compat/regex/regcomp.c msgid "Unmatched ) or \\)" msgstr ") o \\) no emparellat" +#: compat/regex/regcomp.c msgid "No previous regular expression" msgstr "No hi ha expressió regular anterior" +#: compat/simple-ipc/ipc-unix-socket.c compat/simple-ipc/ipc-win32.c msgid "could not send IPC command" msgstr "no s'ha pogut enviar l'ordre IPC" +#: compat/simple-ipc/ipc-unix-socket.c compat/simple-ipc/ipc-win32.c msgid "could not read IPC response" msgstr "no s'ha pogut llegir la resposta IPC" +#: compat/simple-ipc/ipc-unix-socket.c #, c-format msgid "could not start accept_thread '%s'" msgstr "no s'ha pogut començar un fil «accept_thread» «%s»" +#: compat/simple-ipc/ipc-unix-socket.c #, c-format msgid "could not start worker[0] for '%s'" msgstr "no s'ha pogut iniciar el fil[0] per a «%s»" +#: compat/simple-ipc/ipc-win32.c #, c-format msgid "ConnectNamedPipe failed for '%s' (%lu)" msgstr "Ha fallat ConnectNamedPipe per a «%s» (%lu)" +#: compat/simple-ipc/ipc-win32.c #, c-format msgid "could not create fd from pipe for '%s'" msgstr "no s'ha pogut crear un fd a partir de la canonada per a «%s»" +#: compat/simple-ipc/ipc-win32.c #, c-format msgid "could not start thread[0] for '%s'" msgstr "no s'ha pogut iniciar el fil[0] per a «%s»" +#: compat/simple-ipc/ipc-win32.c #, c-format msgid "wait for hEvent failed for '%s'" msgstr "ha fallat l'espera de hEvent per a «%s»" +#: compat/terminal.c msgid "cannot resume in the background, please use 'fg' to resume" msgstr "no es pot reprendre en segon pla, si us plau useu «fg» per a reprendre" +#: compat/terminal.c msgid "cannot restore terminal settings" msgstr "no es poden restaurar els paràmetres del terminal" +#: config.c #, c-format msgid "" "exceeded maximum include depth (%d) while including\n" @@ -15183,17 +19365,21 @@ msgstr "" "\t%s\n" "Això pot ser degut a inclusions circulars." +#: config.c #, c-format msgid "could not expand include path '%s'" msgstr "no s'ha pogut expandir el camí d'inclusió «%s»" +#: config.c msgid "relative config includes must come from files" msgstr "les inclusions de configuració relatives han de venir de fitxers" +#: config.c msgid "relative config include conditionals must come from files" msgstr "" "els condicionals d'inclusió de configuració relatius han de venir de fitxers" +#: config.c msgid "" "remote URLs cannot be configured in file directly or indirectly included by " "includeIf.hasconfig:remote.*.url" @@ -15201,273 +19387,353 @@ msgstr "" "URL remots no es poden configurar en un fitxer directament o indirectament " "inclòs per «includeIf.hasconfig:remote.*.url»" +#: config.c #, c-format msgid "invalid config format: %s" msgstr "format de configuració no vàlid: %s" +#: config.c #, c-format msgid "missing environment variable name for configuration '%.*s'" msgstr "falta el nom de la variable d'entorn per a la configuració «%.*s»" +#: config.c #, c-format msgid "missing environment variable '%s' for configuration '%.*s'" msgstr "falta la variable d'entorn «%s» per a la configuració «%.*s»" +#: config.c #, c-format msgid "key does not contain a section: %s" msgstr "la clau no conté una secció: «%s»" +#: config.c #, c-format msgid "key does not contain variable name: %s" msgstr "la clau no conté un nom de variable: «%s»" +#: config.c sequencer.c #, c-format msgid "invalid key: %s" msgstr "clau no vàlida: %s" +#: config.c #, c-format msgid "invalid key (newline): %s" msgstr "clau no vàlida (línia nova): %s" +#: config.c msgid "empty config key" msgstr "clau de configuració buida" +#: config.c #, c-format msgid "bogus config parameter: %s" msgstr "paràmetre de configuració erroni: %s" +#: config.c #, c-format msgid "bogus format in %s" msgstr "format erroni a %s" +#: config.c #, c-format msgid "bogus count in %s" msgstr "comptatge erroni a %s" +#: config.c #, c-format msgid "too many entries in %s" msgstr "hi ha massa arguments a %s" +#: config.c #, c-format msgid "missing config key %s" msgstr "falta la clau de configuració %s" +#: config.c #, c-format msgid "missing config value %s" msgstr "falta el valor de configuració %s" +#: config.c #, c-format msgid "bad config line %d in blob %s" msgstr "línia de configuració %d errònia en el blob %s" +#: config.c #, c-format msgid "bad config line %d in file %s" msgstr "línia de configuració %d errònia en el fitxer %s" +#: config.c #, c-format msgid "bad config line %d in standard input" msgstr "línia de configuració %d errònia en l'entrada estàndard" +#: config.c #, c-format msgid "bad config line %d in submodule-blob %s" msgstr "línia de configuració %d errònia en el blob de submòdul %s" +#: config.c #, c-format msgid "bad config line %d in command line %s" msgstr "línia de configuració %d errònia en la línia d'ordres %s" +#: config.c #, c-format msgid "bad config line %d in %s" msgstr "línia de configuració %d errònia en %s" +#: config.c msgid "out of range" msgstr "fora de rang" +#: config.c msgid "invalid unit" msgstr "unitat no vàlida" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s': %s" msgstr "valor de configuració numèric erroni «%s» per «%s»: %s" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s' in blob %s: %s" msgstr "valor de configuració numèric erroni «%s» per «%s» en el blob %s: %s" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s' in file %s: %s" msgstr "valor de configuració numèric «%s» erroni per «%s» en el fitxer %s: %s" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s' in standard input: %s" msgstr "" "valor de configuració numèric «%s» erroni per «%s» en l'entrada estàndard: %s" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s" msgstr "" "valor de configuració numèric «%s» erroni per «%s» en el blob de submòdul " "%s: %s" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s' in command line %s: %s" msgstr "" "valor de configuració numèric «%s» erroni per «%s» en la línia d'ordres %s: " "%s" +#: config.c #, c-format msgid "bad numeric config value '%s' for '%s' in %s: %s" msgstr "valor de configuració numèric incorrecte «%s» per «%s» en %s: %s" +#: config.c #, c-format msgid "invalid value for variable %s" msgstr "valor no vàlid per a la variable %s" +#: config.c #, c-format msgid "ignoring unknown core.fsync component '%s'" msgstr "s'ignora el component core.fsync «%s» desconegut" +#: config.c #, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "valor de configuració booleà erroni «%s» per a «%s»" +#: config.c #, c-format msgid "failed to expand user dir in: '%s'" msgstr "s'ha produït un error en expandir el directori d'usuari en: «%s»" +#: config.c #, c-format msgid "'%s' for '%s' is not a valid timestamp" msgstr "«%s» per a «%s» no és una marca de temps vàlida" +#: config.c #, c-format msgid "abbrev length out of range: %d" msgstr "la longitud d'«abbrev» està fora de rang: %d" +#: config.c #, c-format msgid "bad zlib compression level %d" msgstr "nivell de compressió de zlib incorrecte %d" -msgid "core.commentChar should only be one ASCII character" -msgstr "core.commentChar només hauria de ser un caràcter ASCII" +# newline → línia nova o salt de línia? +#: config.c +#, c-format +msgid "%s cannot contain newline" +msgstr "%s no pot contenir una nova línia" + +#: config.c +#, c-format +msgid "%s must have at least one character" +msgstr "%s ha de tenir almenys un caràcter" +#: config.c #, c-format msgid "ignoring unknown core.fsyncMethod value '%s'" msgstr "s'ignora el valor desconegut «%s» de core.fsyncMethod" +#: config.c msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" msgstr "core.fsyncObjectFiles és obsolet; useu core.fsync" +#: config.c #, c-format msgid "invalid mode for object creation: %s" msgstr "mode de creació d'objecte no vàlid: %s" +#: config.c #, c-format msgid "malformed value for %s" msgstr "valor no vàlid per a %s" +#: config.c #, c-format msgid "malformed value for %s: %s" msgstr "valor no vàlid per a %s: %s" +#: config.c msgid "must be one of nothing, matching, simple, upstream or current" msgstr "" "ha de ser un dels elements següents: nothing, matching, simple, upstream o " "current" +#: config.c #, c-format msgid "unable to load config blob object '%s'" msgstr "no s'ha pogut carregar l'objecte blob de configuració «%s»" +#: config.c #, c-format msgid "reference '%s' does not point to a blob" msgstr "la referència «%s» no assenyala a un blob" +#: config.c #, c-format msgid "unable to resolve config blob '%s'" msgstr "no s'ha pogut resoldre el blob de configuració: «%s»" +#: config.c msgid "unable to parse command-line config" msgstr "no s'ha pogut analitzar la configuració de la línia d'ordres" +#: config.c msgid "unknown error occurred while reading the configuration files" msgstr "un error desconegut ha ocorregut en llegir els fitxers de configuració" +#: config.c #, c-format msgid "Invalid %s: '%s'" msgstr "%s no vàlid: «%s»" +#: config.c #, c-format msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100" msgstr "valor «%d» a splitIndex.maxPercentChange ha d'estar entre 0 i 100" +#: config.c #, c-format msgid "unable to parse '%s' from command-line config" msgstr "no s'ha pogut analitzar «%s» de la configuració de la línia d'ordres" +#: config.c #, c-format msgid "bad config variable '%s' in file '%s' at line %d" msgstr "variable de configuració «%s» errònia en el fitxer «%s» a la línia %d" +#: config.c #, c-format msgid "invalid section name '%s'" msgstr "nom de secció no vàlid «%s»" +#: config.c #, c-format msgid "%s has multiple values" msgstr "%s té múltiples valors" +#: config.c #, c-format msgid "failed to write new configuration file %s" msgstr "no es pot escriure un nou fitxer de configuració %s" +#: config.c +#, c-format +msgid "no multi-line comment allowed: '%s'" +msgstr "no es permet el comentari multi-línia: «%s»" + +#: config.c #, c-format msgid "could not lock config file %s" msgstr "no s'ha pogut blocar el fitxer de configuració %s" +#: config.c #, c-format msgid "opening %s" msgstr "s'està obrint %s" +#: config.c #, c-format msgid "invalid config file %s" msgstr "fitxer de configuració no vàlid %s" +#: config.c #, c-format msgid "fstat on %s failed" msgstr "ha fallat «fstat» a %s" +#: config.c #, c-format msgid "unable to mmap '%s'%s" msgstr "no s'ha pogut fer «mmap» «%s»%s" +#: config.c #, c-format msgid "chmod on %s failed" msgstr "ha fallat chmod a %s" +#: config.c #, c-format msgid "could not write config file %s" msgstr "no s'ha pogut escriure el fitxer de configuració «%s»" +#: config.c #, c-format msgid "could not set '%s' to '%s'" msgstr "no s'ha pogut establir «%s» a «%s»" +#: config.c #, c-format msgid "invalid section name: %s" msgstr "nom de secció no vàlida: %s" +#: config.c #, c-format msgid "refusing to work with overly long line in '%s' on line %<PRIuMAX>" msgstr "" "es rebutja treballar amb una línia massa llarga a «%s» a la línia %<PRIuMAX>" +#: config.c #, c-format msgid "missing value for '%s'" msgstr "falta el valor per «%s»" +#: connect.c msgid "the remote end hung up upon initial contact" msgstr "el costat remot ha penjat en el moment de contacte inicial" +#: connect.c msgid "" "Could not read from remote repository.\n" "\n" @@ -15479,77 +19745,97 @@ msgstr "" "Assegureu-vos que tingueu els permisos\n" "d'accés correctes i que el repositori existeixi." +#: connect.c #, c-format msgid "server doesn't support '%s'" msgstr "el servidor no és compatible amb «%s»" +#: connect.c #, c-format msgid "server doesn't support feature '%s'" msgstr "el servidor no és compatible amb la característica «%s»" +#: connect.c msgid "expected flush after capabilities" msgstr "s'esperava un buidatge després de les capacitats" +#: connect.c #, c-format msgid "ignoring capabilities after first line '%s'" msgstr "ignora les capacitats després de la primera línia «%s»" +#: connect.c msgid "protocol error: unexpected capabilities^{}" msgstr "error de protocol: unexpected capabilities^{}" +#: connect.c #, c-format msgid "protocol error: expected shallow sha-1, got '%s'" msgstr "" "s'ha produït un error de protocol: s'esperava shallow sha-1, s'ha rebut «%s»" +#: connect.c msgid "repository on the other end cannot be shallow" msgstr "el repositori de l'altre extrem no pot ser shallow" +#: connect.c msgid "invalid packet" msgstr "paquet no vàlid" +#: connect.c #, c-format msgid "protocol error: unexpected '%s'" msgstr "s'ha produït un error de protocol: no s'esperava «%s»" +#: connect.c #, c-format msgid "unknown object format '%s' specified by server" msgstr "format d'objecte «%s» especificat pel servidor desconegut" +#: connect.c #, c-format msgid "error on bundle-uri response line %d: %s" msgstr "error a la línia de resposta de bundle-uri %d: %s" +#: connect.c msgid "expected flush after bundle-uri listing" msgstr "s'esperava un buidatge després del llistat de bundle-uri" +#: connect.c msgid "expected response end packet after ref listing" msgstr "" "s'esperava un paquet de final de resposta després del llistat de referències" +#: connect.c #, c-format msgid "invalid ls-refs response: %s" msgstr "resposta de ls-refs no vàlida: %s" +#: connect.c msgid "expected flush after ref listing" msgstr "s'esperava una neteja després del llistat de referències" +#: connect.c #, c-format msgid "protocol '%s' is not supported" msgstr "el protocol «%s» no és compatible" +#: connect.c msgid "unable to set SO_KEEPALIVE on socket" msgstr "no s'ha pogut establir SO_KEEPALIVE al sòcol" +#: connect.c #, c-format msgid "Looking up %s ... " msgstr "S'està cercant %s..." +#: connect.c #, c-format msgid "unable to look up %s (port %s) (%s)" msgstr "no s'ha pogut trobar %s (port %s) (%s)" #. TRANSLATORS: this is the end of "Looking up %s ... " +#: connect.c #, c-format msgid "" "done.\n" @@ -15558,6 +19844,7 @@ msgstr "" "fet.\n" "S'està connectant a %s (port %s) ... " +#: connect.c #, c-format msgid "" "unable to connect to %s:\n" @@ -15567,72 +19854,91 @@ msgstr "" "%s" #. TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " +#: connect.c msgid "done." msgstr "fet." +#: connect.c #, c-format msgid "unable to look up %s (%s)" msgstr "no s'ha pogut trobar %s (%s)" +#: connect.c #, c-format msgid "unknown port %s" msgstr "port desconegut %s" +#: connect.c #, c-format msgid "strange hostname '%s' blocked" msgstr "s'ha bloquejat el nom estrany d'amfitrió «%s»" +#: connect.c #, c-format msgid "strange port '%s' blocked" msgstr "s'ha bloquejat el port estrany «%s»" +#: connect.c #, c-format msgid "cannot start proxy %s" msgstr "no s'ha pogut iniciar servidor intermediari «%s»" +#: connect.c msgid "no path specified; see 'git help pull' for valid url syntax" msgstr "" "no s'ha especificat un camí; vegeu «git help pull» per la sintaxi vàlida per " "URL" +#: connect.c msgid "newline is forbidden in git:// hosts and repo paths" msgstr "" "la línia nova està prohibida en els servidors git:// i els camins de " "repositori" +#: connect.c msgid "ssh variant 'simple' does not support -4" msgstr "la variant «simple» de ssh no és compatible amb -4" +#: connect.c msgid "ssh variant 'simple' does not support -6" msgstr "la variant «simple» de ssh no és compatible amb -6" +#: connect.c msgid "ssh variant 'simple' does not support setting port" msgstr "la variant «simple» de ssh no permet definir el port" +#: connect.c #, c-format msgid "strange pathname '%s' blocked" msgstr "s'ha bloquejat el nom de fitxer estrany «%s»" +#: connect.c msgid "unable to fork" msgstr "no s'ha pogut bifurcar" +#: connected.c msgid "Could not run 'git rev-list'" msgstr "No s'ha pogut executar «git rev-list»" +#: connected.c msgid "failed write to rev-list" msgstr "escriptura fallada al rev-list" +#: connected.c msgid "failed to close rev-list's stdin" msgstr "s'ha produït un error en tancar l'stdin del rev-list" +#: convert.c #, c-format msgid "illegal crlf_action %d" msgstr "crlf_action %d il·legal" +#: convert.c #, c-format msgid "CRLF would be replaced by LF in %s" msgstr "CRLF es reemplaçà per LF en %s" +#: convert.c #, c-format msgid "" "in the working copy of '%s', CRLF will be replaced by LF the next time Git " @@ -15641,10 +19947,12 @@ msgstr "" "a la còpia de treball de «%s», CRLF serà substituït per LF, la propera " "vegada que el Git ho modifiqui" +#: convert.c #, c-format msgid "LF would be replaced by CRLF in %s" msgstr "LF es reemplaçà per CRLF en %s" +#: convert.c #, c-format msgid "" "in the working copy of '%s', LF will be replaced by CRLF the next time Git " @@ -15653,64 +19961,79 @@ msgstr "" "a la còpia de treball de «%s», LF serà substituït per CRLF la propera vegada " "que Git ho modifiqui" +#: convert.c #, c-format msgid "BOM is prohibited in '%s' if encoded as %s" msgstr "BOM està prohibida a «%s» si està codificada com a %s" +#: convert.c #, c-format msgid "" "The file '%s' contains a byte order mark (BOM). Please use UTF-%.*s as " "working-tree-encoding." msgstr "" -"El fitxer «%s» conté una marca d'ordre de byte (BOM). Utilitzeu UTF-%.*s com " -"a codificacions d'arbre de treball." +"El fitxer «%s» conté una marca d'ordre de octets (BOM). Utilitzeu UTF-%.*s " +"com a codificacions d'arbre de treball." +#: convert.c #, c-format msgid "BOM is required in '%s' if encoded as %s" msgstr "La BOM és necessària en «%s» si està codificada com a %s" +#: convert.c #, 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 "" -"Falta una marca d'ordre de byte (BOM) al fitxer «%s». Useu UTF-%sBE o UTF-" -"%sLE (depenent de l'ordre de byte) com a codificacions d'arbre de treball." +"Falta una marca d'ordre d'octets (BOM) al fitxer «%s». Useu UTF-%sBE o UTF-" +"%sLE (depenent de l'ordre dels octets) com a codificacions d'arbre de " +"treball." +#: convert.c #, c-format msgid "failed to encode '%s' from %s to %s" msgstr "s'ha produït un error en codificar «%s» des de %s a %s" +#: convert.c #, c-format msgid "encoding '%s' from %s to %s and back is not the same" msgstr "codificar «%s» des de %s a %s i cap enrere no és el mateix" +#: convert.c #, c-format msgid "cannot fork to run external filter '%s'" msgstr "no es pot bifurcar per a executar el filtre extern «%s»" +#: convert.c #, c-format msgid "cannot feed the input to external filter '%s'" msgstr "no es pot alimentar l'entrada al filtre extern «%s»" +#: convert.c #, c-format msgid "external filter '%s' failed %d" msgstr "el filtre extern «%s» ha fallat %d" +#: convert.c #, c-format msgid "read from external filter '%s' failed" msgstr "la lectura del filtre extern «%s» ha fallat" +#: convert.c #, c-format msgid "external filter '%s' failed" msgstr "el filtre extern «%s» ha fallat" +#: convert.c msgid "unexpected filter type" msgstr "tipus de filtre inesperat" +#: convert.c msgid "path name too long for external filter" msgstr "el nom del camí és massa gran per al filtre extern" +#: convert.c #, c-format msgid "" "external filter '%s' is not available anymore although not all paths have " @@ -15719,80 +20042,97 @@ msgstr "" "el filtre extern «%s» ja no està disponible encara que no s'han filtrat tots " "els camins" +#: convert.c msgid "true/false are no valid working-tree-encodings" msgstr "cert/fals no són codificacions d'arbre de treball vàlides" +#: convert.c #, c-format msgid "%s: clean filter '%s' failed" msgstr "%s: el filtre de netejat «%s» ha fallat" +#: convert.c #, c-format msgid "%s: smudge filter %s failed" msgstr "%s: ha fallat el filtre smudge %s" +#: credential.c #, c-format msgid "skipping credential lookup for key: credential.%s" msgstr "s'està ometent la cerca de credencials per una clau: credential.%s" +#: credential.c msgid "refusing to work with credential missing host field" msgstr "" "s'ha rebutjat treballar amb credencials que no tenen el camp d'amfitrió" +#: credential.c msgid "refusing to work with credential missing protocol field" msgstr "" "s'ha rebutjat treballar amb credencials que no tenen el camp de protocol" +#: credential.c #, c-format msgid "url contains a newline in its %s component: %s" msgstr "url conté una línia nova en %s component: %s" +#: credential.c #, c-format msgid "url has no scheme: %s" msgstr "l'url no té esquema: %s" +#: credential.c #, c-format msgid "credential url cannot be parsed: %s" msgstr "no s'ha pogut analitzar l'URL de credencials: %s" +#: date.c msgid "in the future" msgstr "en el futur" +#: date.c #, c-format msgid "%<PRIuMAX> second ago" msgid_plural "%<PRIuMAX> seconds ago" msgstr[0] "fa %<PRIuMAX> segon" msgstr[1] "fa %<PRIuMAX> segons" +#: date.c #, c-format msgid "%<PRIuMAX> minute ago" msgid_plural "%<PRIuMAX> minutes ago" msgstr[0] "fa %<PRIuMAX> minut" msgstr[1] "fa %<PRIuMAX> minuts" +#: date.c #, c-format msgid "%<PRIuMAX> hour ago" msgid_plural "%<PRIuMAX> hours ago" msgstr[0] "fa %<PRIuMAX> hora" msgstr[1] "fa %<PRIuMAX> hores" +#: date.c #, c-format msgid "%<PRIuMAX> day ago" msgid_plural "%<PRIuMAX> days ago" msgstr[0] "fa %<PRIuMAX> dia" msgstr[1] "fa %<PRIuMAX> dies" +#: date.c #, c-format msgid "%<PRIuMAX> week ago" msgid_plural "%<PRIuMAX> weeks ago" msgstr[0] "fa %<PRIuMAX> setmana" msgstr[1] "fa %<PRIuMAX> setmanes" +#: date.c #, c-format msgid "%<PRIuMAX> month ago" msgid_plural "%<PRIuMAX> months ago" msgstr[0] "fa %<PRIuMAX> mes" msgstr[1] "fa %<PRIuMAX> mesos" +#: date.c #, c-format msgid "%<PRIuMAX> year" msgid_plural "%<PRIuMAX> years" @@ -15800,87 +20140,109 @@ msgstr[0] "%<PRIuMAX> any" msgstr[1] "%<PRIuMAX> anys" #. TRANSLATORS: "%s" is "<n> years" +#: date.c #, c-format msgid "%s, %<PRIuMAX> month ago" msgid_plural "%s, %<PRIuMAX> months ago" msgstr[0] "fa %s i %<PRIuMAX> mes" msgstr[1] "fa %s i %<PRIuMAX> mesos" +#: date.c #, c-format msgid "%<PRIuMAX> year ago" msgid_plural "%<PRIuMAX> years ago" msgstr[0] "fa %<PRIuMAX> any" msgstr[1] "fa %<PRIuMAX> anys" +#: delta-islands.c msgid "Propagating island marks" msgstr "S'estan propagant les marques d'illa" +#: delta-islands.c #, c-format msgid "bad tree object %s" msgstr "objecte d'arbre malmès %s" +#: delta-islands.c #, c-format msgid "failed to load island regex for '%s': %s" msgstr "" "s'ha produït un error en carregar l'expressió regular de l'illa per «%s»: %s" +#: delta-islands.c #, c-format msgid "island regex from config has too many capture groups (max=%d)" msgstr "" "l'expressió regular de l'illa des de la configuració té massa grups de " "captura (màx=%d)" +#: delta-islands.c #, c-format msgid "Marked %d islands, done.\n" msgstr "Marcades %d illes, fet.\n" +#: diagnose.c #, c-format msgid "invalid --%s value '%s'" msgstr "no és vàlid --%s amb valor «%s»" +#: diagnose.c #, c-format msgid "could not archive missing directory '%s'" msgstr "no s'ha pogut arxivar el directori que falta «%s»" +#: diagnose.c dir.c #, c-format msgid "could not open directory '%s'" msgstr "no s'ha pogut obrir el directori «%s»" +#: diagnose.c #, c-format msgid "skipping '%s', which is neither file nor directory" msgstr "s'omet «%s», que no és ni fitxer ni directori" +#: diagnose.c msgid "could not duplicate stdout" msgstr "no s'ha pogut duplicar stdout" +#: diagnose.c #, c-format msgid "could not add directory '%s' to archiver" msgstr "no s'ha pogut afegir el directori «%s» a l'arxivador" +#: diagnose.c msgid "failed to write archive" msgstr "s'ha produït un error en escriure arxiu" +#: diff-lib.c msgid "--merge-base does not work with ranges" msgstr "--merge-base no funciona amb intervals" +#: diff-lib.c msgid "unable to get HEAD" msgstr "no s'ha pogut obtenir HEAD" +#: diff-lib.c msgid "no merge base found" msgstr "no s'ha trobat una base de fusió" +#: diff-lib.c msgid "multiple merge bases found" msgstr "s'han trobat múltiples bases de fusió" +#: diff-no-index.c msgid "cannot compare stdin to a directory" msgstr "no es pot comparar stdin amb un directori" +#: diff-no-index.c msgid "cannot compare a named pipe to a directory" msgstr "no es pot comparar una canonada amb nom amb un directori" +#: diff-no-index.c msgid "git diff --no-index [<options>] <path> <path>" msgstr "git diff --no-index [<opcions>] <camí> <camí>" +#: diff-no-index.c msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " "tree" @@ -15888,16 +20250,19 @@ msgstr "" "No és un repositori Git. Useu --no-index per a comparar dos camins fora del " "directori de treball" +#: diff.c #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr "" " S'ha produït un error en analitzar el percentatge limitant de dirstat " "«%s»\n" +#: diff.c #, c-format msgid " Unknown dirstat parameter '%s'\n" msgstr " Paràmetre de dirstat desconegut «%s»\n" +#: diff.c msgid "" "color moved setting must be one of 'no', 'default', 'blocks', 'zebra', " "'dimmed-zebra', 'plain'" @@ -15905,6 +20270,7 @@ msgstr "" "el paràmetre de color en moviment ha de ser «no», «default», «blocks», " "«zebra», «dimmed-zebra» o «plain»" +#: diff.c #, c-format msgid "" "unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', " @@ -15914,6 +20280,7 @@ msgstr "" "«ignore-space-change», «ignore-space-at-eol», «ignore-all-space», «allow-" "indentation-change»" +#: diff.c msgid "" "color-moved-ws: allow-indentation-change cannot be combined with other " "whitespace modes" @@ -15921,15 +20288,18 @@ msgstr "" "color-moved-ws: allow-indentation-change no es pot combinar amb altres modes " "d'espai en blanc" +#: diff.c #, c-format msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "" "Valor desconegut de la variable de configuració de «diff.submodule»: «%s»" +#: diff.c merge-recursive.c transport.c #, c-format msgid "unknown value for config '%s': %s" msgstr "valor desconegut per al config «%s»': %s" +#: diff.c #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" @@ -15938,39 +20308,48 @@ msgstr "" "S'han trobat errors en la variable de configuració «diff.dirstat»:\n" "%s" +#: diff.c #, c-format msgid "external diff died, stopping at %s" msgstr "el diff external s'ha mort, s'està aturant a %s" +#: diff.c msgid "--follow requires exactly one pathspec" msgstr "--follow requereix exactament una especificació de camí" +#: diff.c #, c-format msgid "pathspec magic not supported by --follow: %s" msgstr "el «pathspec» màgic no està suportat per --follow: %s" +#: diff.c parse-options.c #, c-format msgid "options '%s', '%s', '%s', and '%s' cannot be used together" msgstr "les opcions «%s», «%s», «%s», i «%s» no es poden usar juntes" +#: diff.c #, c-format msgid "options '%s' and '%s' cannot be used together, use '%s' with '%s'" msgstr "les opcions «%s» i «%s» no es poden usar juntes, useu «%s» amb «%s»" +#: diff.c #, c-format msgid "" "options '%s' and '%s' cannot be used together, use '%s' with '%s' and '%s'" msgstr "" "les opcions «%s» i «%s» no es poden usar juntes, useu «%s» amb «%s» i «%s»" +#: diff.c #, c-format msgid "invalid --stat value: %s" msgstr "valor --stat no vàlid: %s" +#: diff.c parse-options.c #, c-format msgid "%s expects a numerical value" msgstr "%s espera un valor numèric" +#: diff.c #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -15979,147 +20358,189 @@ msgstr "" "S'ha produït un error en analitzar el paràmetre d'opció de --dirstat/-X:\n" "%s" +#: diff.c #, c-format msgid "unknown change class '%c' in --diff-filter=%s" msgstr "classe de canvi «%c» desconeguda a --diff-filter=%s" +#: diff.c #, c-format msgid "unknown value after ws-error-highlight=%.*s" msgstr "valor desconegut després de ws-error-highlight=%.*s" +#: diff.c #, c-format msgid "unable to resolve '%s'" msgstr "no s'ha pogut resoldre «%s»" +#: diff.c #, c-format msgid "%s expects <n>/<m> form" msgstr "%s espera una forma <n>/<m>" +#: diff.c #, c-format msgid "%s expects a character, got '%s'" msgstr "%s esperava un caràcter, s'ha rebut «%s»" +#: diff.c #, c-format msgid "bad --color-moved argument: %s" msgstr "argument --color-moved incorrecte: %s" +#: diff.c #, c-format msgid "invalid mode '%s' in --color-moved-ws" msgstr "mode «%s» no vàlid en --color-moved-ws" +#: diff.c #, c-format msgid "invalid argument to %s" msgstr "argument no vàlid a %s" +#: diff.c #, c-format msgid "invalid regex given to -I: '%s'" msgstr "expressió regular donada a -I: no vàlida: «%s»" +#: diff.c #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "" "s'ha produït un error en analitzar el paràmetre d'opció de --submodule: «%s»" +#: diff.c #, c-format msgid "bad --word-diff argument: %s" msgstr "argument --word-diff incorrecte: %s" +#: diff.c msgid "Diff output format options" msgstr "Opcions del format de sortida del diff" +#: diff.c msgid "generate patch" msgstr "genera el pedaç" +#: diff.c msgid "<n>" msgstr "<n>" +#: diff.c msgid "generate diffs with <n> lines context" msgstr "genera diffs amb <n> línies de context" +#: diff.c msgid "generate the diff in raw format" msgstr "genera el diff en format cru" +#: diff.c msgid "synonym for '-p --raw'" msgstr "sinònim de «-p --raw»" +#: diff.c msgid "synonym for '-p --stat'" msgstr "sinònim de «-p --stat»" +#: diff.c msgid "machine friendly --stat" msgstr "llegible per una màquina --stat" +#: diff.c msgid "output only the last line of --stat" msgstr "mostra només l'última línia de --stat" +#: diff.c msgid "<param1>,<param2>..." msgstr "<param1>,<param2>..." +#: diff.c msgid "" "output the distribution of relative amount of changes for each sub-directory" msgstr "" "genera la distribució de la quantitat relativa de canvis per a cada " "subdirectori" +#: diff.c msgid "synonym for --dirstat=cumulative" msgstr "sinònim de --dirstat=cumulative" +#: diff.c msgid "synonym for --dirstat=files,<param1>,<param2>..." msgstr "sinònim de --dirstat=files,<param1>,<param2>..." +#: diff.c msgid "warn if changes introduce conflict markers or whitespace errors" msgstr "" "avisa si els canvis introdueixen marcadors en conflicte o errors d'espai en " "blanc" +#: diff.c msgid "condensed summary such as creations, renames and mode changes" msgstr "resum condensat com ara creacions, canvis de nom i mode" +#: diff.c msgid "show only names of changed files" msgstr "mostra només els noms de fitxers canviats" +#: diff.c msgid "show only names and status of changed files" msgstr "mostra només els noms i l'estat dels fitxers canviats" +#: diff.c msgid "<width>[,<name-width>[,<count>]]" msgstr "<amplada>[<amplada-nom>[,<recompte>]]" +#: diff.c msgid "generate diffstat" msgstr "genera diffstat" +#: diff.c msgid "<width>" msgstr "<amplada>" +#: diff.c msgid "generate diffstat with a given width" msgstr "genera diffstat amb una amplada donada" +#: diff.c msgid "generate diffstat with a given name width" msgstr "genera diffstat amb un nom d'amplada donat" +#: diff.c msgid "generate diffstat with a given graph width" msgstr "genera diffstat amb una amplada de graf donada" +#: diff.c msgid "<count>" msgstr "<comptador>" +#: diff.c msgid "generate diffstat with limited lines" msgstr "genera diffstat amb línies limitades" +#: diff.c msgid "generate compact summary in diffstat" msgstr "genera un resum compacte a diffstat" +#: diff.c msgid "output a binary diff that can be applied" msgstr "diff amb sortida binària que pot ser aplicada" +#: diff.c msgid "show full pre- and post-image object names on the \"index\" lines" msgstr "" "mostra els noms complets dels objectes pre i post-imatge a les línies «index»" +#: diff.c msgid "show colored diff" msgstr "mostra un diff amb colors" +#: diff.c msgid "<kind>" msgstr "<kind>" +#: diff.c msgid "" "highlight whitespace errors in the 'context', 'old' or 'new' lines in the " "diff" @@ -16127,6 +20548,7 @@ msgstr "" "ressalta els errors d'espai en blanc a les línies «context», «old» o «new» " "al diff" +#: diff.c msgid "" "do not munge pathnames and use NULs as output field terminators in --raw or " "--numstat" @@ -16134,74 +20556,96 @@ msgstr "" "no consolidis els noms de camí i utilitza NULs com a terminadors de camp de " "sortida en --raw o --numstat" +#: diff.c msgid "<prefix>" msgstr "<prefix>" +#: diff.c msgid "show the given source prefix instead of \"a/\"" msgstr "mostra el prefix d'origen donat en lloc de «a/»" +#: diff.c msgid "show the given destination prefix instead of \"b/\"" msgstr "mostra el prefix de destinació indicat en lloc de «b/»" +#: diff.c msgid "prepend an additional prefix to every line of output" msgstr "afegir un prefix addicional per a cada línia de sortida" +#: diff.c msgid "do not show any source or destination prefix" msgstr "no mostris cap prefix d'origen o destí" +#: diff.c msgid "use default prefixes a/ and b/" msgstr "utilitza els prefixos per defecte a/ i b/" +#: diff.c msgid "show context between diff hunks up to the specified number of lines" msgstr "" "mostra el context entre trossos de diferència fins al nombre especificat de " "línies" +#: diff.c msgid "<char>" -msgstr "<char>" +msgstr "<caràcter>" +#: diff.c msgid "specify the character to indicate a new line instead of '+'" msgstr "" "especifiqueu el caràcter per a indicar una línia nova en comptes de «+»" +#: diff.c msgid "specify the character to indicate an old line instead of '-'" msgstr "" "especifiqueu el caràcter per a indicar una línia antiga en comptes de «-»" +#: diff.c msgid "specify the character to indicate a context instead of ' '" msgstr "especifiqueu el caràcter per a indicar context en comptes de « »" +#: diff.c msgid "Diff rename options" msgstr "Opcions de canvi de nom del diff" +#: diff.c msgid "<n>[/<m>]" msgstr "<n>[/<m>]" +#: diff.c msgid "break complete rewrite changes into pairs of delete and create" msgstr "" "divideix els canvis de reescriptura completa en parells de suprimir i crear" +#: diff.c msgid "detect renames" msgstr "detecta els canvis de noms" +#: diff.c msgid "omit the preimage for deletes" msgstr "omet les preimatges per les supressions" +#: diff.c msgid "detect copies" msgstr "detecta còpies" +#: diff.c msgid "use unmodified files as source to find copies" msgstr "usa els fitxers no modificats com a font per a trobar còpies" +#: diff.c msgid "disable rename detection" msgstr "inhabilita la detecció de canvis de nom" +#: diff.c msgid "use empty blobs as rename source" msgstr "usa els blobs buits com a font de canvi de nom" +#: diff.c msgid "continue listing the history of a file beyond renames" msgstr "continua llistant l'històric d'un fitxer més enllà dels canvis de nom" +#: diff.c msgid "" "prevent rename/copy detection if the number of rename/copy targets exceeds " "given limit" @@ -16209,118 +20653,154 @@ msgstr "" "evita la detecció de canvi de nom/còpia si el nombre d'objectius de canvi de " "nom/còpia supera el límit indicat" +#: diff.c msgid "Diff algorithm options" msgstr "Opcions de l'algorisme Diff" +#: diff.c msgid "produce the smallest possible diff" msgstr "produeix el diff més petit possible" +#: diff.c msgid "ignore whitespace when comparing lines" msgstr "ignora els espais en blanc en comparar línies" +#: diff.c msgid "ignore changes in amount of whitespace" msgstr "ignora els canvis en la quantitat d'espai en blanc" +#: diff.c msgid "ignore changes in whitespace at EOL" msgstr "ignora els canvis d'espai en blanc al final de la línia" +#: diff.c msgid "ignore carrier-return at the end of line" msgstr "ignora els retorns de línia al final de la línia" +#: diff.c msgid "ignore changes whose lines are all blank" msgstr "ignora els canvis en línies que estan en blanc" +#: diff.c msgid "<regex>" -msgstr "<regex>" +msgstr "<expr-reg>" +#: diff.c msgid "ignore changes whose all lines match <regex>" -msgstr "ignora els canvis en les línies que coincideixen amb <regex>" +msgstr "ignora els canvis en les línies que coincideixen amb <expr-reg>" +#: diff.c msgid "heuristic to shift diff hunk boundaries for easy reading" msgstr "" "heurística per a desplaçar els límits del tros de diferència per a una " "lectura fàcil" +#: diff.c msgid "generate diff using the \"patience diff\" algorithm" msgstr "genera diff usant l'algorisme «patience diff»" +#: diff.c msgid "generate diff using the \"histogram diff\" algorithm" msgstr "genera diff usant l'algorisme «histogram diff»" +#: diff.c msgid "<text>" msgstr "<text>" +#: diff.c msgid "generate diff using the \"anchored diff\" algorithm" msgstr "genera diff usant l'algorisme «anchored diff»" +#: diff.c msgid "<mode>" msgstr "<mode>" +#: diff.c msgid "show word diff, using <mode> to delimit changed words" msgstr "" "mostra el diff de paraules usant <mode> per a delimitar les paraules " "modificades" +#: diff.c msgid "use <regex> to decide what a word is" -msgstr "utilitza <regex> per a decidir què és una paraula" +msgstr "utilitza <expr-reg> per a decidir què és una paraula" +#: diff.c msgid "equivalent to --word-diff=color --word-diff-regex=<regex>" -msgstr "equivalent a --word-diff=color --word-diff-regex=<regex>" +msgstr "equivalent a --word-diff=color --word-diff-regex=<expr-reg>" +#: diff.c msgid "moved lines of code are colored differently" msgstr "les línies de codi que s'han mogut s'acoloreixen diferent" +#: diff.c msgid "how white spaces are ignored in --color-moved" msgstr "com s'ignoren els espais en blanc a --color-moved" +#: diff.c msgid "Other diff options" msgstr "Altres opcions diff" +#: diff.c msgid "when run from subdir, exclude changes outside and show relative paths" msgstr "" "quan s'executa des d'un subdirectori, exclou els canvis de fora i mostra els " "camins relatius" +#: diff.c msgid "treat all files as text" msgstr "tracta tots els fitxers com a text" +#: diff.c msgid "swap two inputs, reverse the diff" msgstr "intercanvia les dues entrades, inverteix el diff" +#: diff.c msgid "exit with 1 if there were differences, 0 otherwise" msgstr "surt amb 1 si hi ha diferències, 0 en cas contrari" +#: diff.c msgid "disable all output of the program" msgstr "inhabilita totes les sortides del programa" +#: diff.c msgid "allow an external diff helper to be executed" msgstr "permet executar un ajudant de diff extern" +#: diff.c msgid "run external text conversion filters when comparing binary files" msgstr "" "executa els filtres externs de conversió de text en comparar fitxers binaris" +#: diff.c msgid "<when>" msgstr "<quan>" +#: diff.c msgid "ignore changes to submodules in the diff generation" msgstr "ignora els canvis als submòduls en la generació del diff" +#: diff.c msgid "<format>" msgstr "<format>" +#: diff.c msgid "specify how differences in submodules are shown" msgstr "especifiqueu com es mostren els canvis als submòduls" +#: diff.c msgid "hide 'git add -N' entries from the index" msgstr "amaga les entrades «git add -N» de l'índex" +#: diff.c msgid "treat 'git add -N' entries as real in the index" msgstr "tracta les entrades «git add -N» com a reals a l'índex" +#: diff.c msgid "<string>" msgstr "<cadena>" +#: diff.c msgid "" "look for differences that change the number of occurrences of the specified " "string" @@ -16328,6 +20808,7 @@ msgstr "" "cerca les diferències que canvien el nombre d'ocurrències de la cadena " "especificada" +#: diff.c msgid "" "look for differences that change the number of occurrences of the specified " "regex" @@ -16335,27 +20816,35 @@ msgstr "" "cerca les diferències que canvien el nombre d'ocurrències de l'expressió " "regular especificada" +#: diff.c msgid "show all changes in the changeset with -S or -G" msgstr "mostra tots els canvis amb el conjunt de canvis amb -S o -G" +#: diff.c msgid "treat <string> in -S as extended POSIX regular expression" msgstr "tracta <cadena> a -S com a expressió regular POSIX ampliada" +#: diff.c msgid "control the order in which files appear in the output" msgstr "controla l'ordre amb el qual els fitxers apareixen en la sortida" +#: diff.c msgid "<path>" msgstr "<camí>" +#: diff.c msgid "show the change in the specified path first" msgstr "mostra el canvi primer al camí especificat" +#: diff.c msgid "skip the output to the specified path" msgstr "omet la sortida al camí especificat" +#: diff.c msgid "<object-id>" msgstr "<id de l'objecte>" +#: diff.c msgid "" "look for differences that change the number of occurrences of the specified " "object" @@ -16363,26 +20852,33 @@ msgstr "" "cerca les diferències que canvien el nombre d'ocurrències de l'objecte " "especificat" +#: diff.c msgid "[(A|C|D|M|R|T|U|X|B)...[*]]" msgstr "[(A|C|D|M|R|T|U|X|B)...[*]]" +#: diff.c msgid "select files by diff type" msgstr "seleccioneu els fitxers per tipus de diff" +#: diff.c msgid "<file>" msgstr "<fitxer>" +#: diff.c msgid "output to a specific file" msgstr "sortida a un fitxer específic" +#: diff.c msgid "exhaustive rename detection was skipped due to too many files." msgstr "" "s'ha omès la detecció de canvi de nom exhaustiva perquè hi ha massa fitxers." +#: diff.c msgid "only found copies from modified paths due to too many files." msgstr "" "només s'han trobat còpies des de camins modificats perquè de massa fitxers." +#: diff.c #, c-format msgid "" "you may want to set your %s variable to at least %d and retry the command." @@ -16390,50 +20886,62 @@ msgstr "" "potser voleu establir la vostra variable %s a almenys %d i tornar a intentar " "l'ordre." +#: diffcore-order.c #, c-format msgid "failed to read orderfile '%s'" msgstr "s'ha produït un error en llegir el fitxer d'ordres «%s»" +#: diffcore-rename.c msgid "Performing inexact rename detection" msgstr "S'està realitzant una detecció inexacta de canvis de nom" +#: diffcore-rotate.c #, c-format msgid "No such path '%s' in the diff" msgstr "No existeix el camí «%s» al diff" +#: dir.c #, c-format msgid "pathspec '%s' did not match any file(s) known to git" msgstr "" "l'especificació de camí «%s» no ha coincidit amb cap fitxer que git conegui" +#: dir.c #, c-format msgid "unrecognized pattern: '%s'" msgstr "patró no reconegut: «%s»" +#: dir.c #, c-format msgid "unrecognized negative pattern: '%s'" msgstr "patró negatiu no reconegut: «%s»" +#: dir.c #, c-format msgid "your sparse-checkout file may have issues: pattern '%s' is repeated" msgstr "" "el vostre fitxer «sparse-checkout» pot tenir problemes el patró «%s» es " "repeteix" +#: dir.c msgid "disabling cone pattern matching" msgstr "inhabilita la coincidència de patrons «cone»" +#: dir.c #, c-format msgid "cannot use %s as an exclude file" msgstr "no es pot usar %s com a fitxer d'exclusió" +#: dir.c msgid "failed to get kernel name and information" msgstr "s'ha produït un error en obtenir el nombre i la informació del nucli" +#: dir.c msgid "untracked cache is disabled on this system or location" msgstr "" "la memòria cau no seguida està inhabilitada en aquest sistema o ubicació" +#: dir.c msgid "" "No directory name could be guessed.\n" "Please specify a directory on the command line" @@ -16441,191 +20949,243 @@ msgstr "" "No s'ha pogut deduir cap nom de directori.\n" "Especifiqueu un directori en la línia d'ordres" +#: dir.c #, c-format msgid "index file corrupt in repo %s" msgstr "el fitxer d'índex al repositori %s és malmès" +#: dir.c #, c-format msgid "could not create directories for %s" msgstr "no s'han pogut crear directoris per %s" +#: dir.c #, c-format msgid "could not migrate git directory from '%s' to '%s'" msgstr "no s'ha pogut migrar el directori de «%s» a «%s»" +#: editor.c #, c-format msgid "hint: Waiting for your editor to close the file...%c" msgstr "consell: s'està esperant que el vostre editor tanqui el fitxer...%c" +#: editor.c sequencer.c wrapper.c #, c-format msgid "could not write to '%s'" msgstr "no s'ha pogut escriure a «%s»" +#: editor.c #, c-format msgid "could not edit '%s'" msgstr "no s'ha pogut editar «%s»" +#: entry.c msgid "Filtering content" msgstr "S'està filtrant el contingut" +#: entry.c #, c-format msgid "could not stat file '%s'" msgstr "no s'ha pogut fer «stat» sobre el fitxer «%s»" +#: environment.c #, c-format msgid "bad git namespace path \"%s\"" msgstr "camí d'espai de noms git incorrecte «%s»" +#: exec-cmd.c #, c-format msgid "too many args to run %s" msgstr "hi ha massa arguments per a executar %s" +#: fetch-pack.c msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: llista shallow esperada" +#: fetch-pack.c msgid "git fetch-pack: expected a flush packet after shallow list" msgstr "" "git fetch-pack: s'esperava un paquet de buidatge després d'una llista shallow" +#: fetch-pack.c msgid "git fetch-pack: expected ACK/NAK, got a flush packet" msgstr "git fetch-pack: s'esperava ACK/NAK, s'ha rebut un paquet de buidatge" +#: fetch-pack.c #, c-format msgid "git fetch-pack: expected ACK/NAK, got '%s'" msgstr "git fetch-pack: s'esperava ACK/NAK, s'ha rebut «%s»" +#: fetch-pack.c msgid "unable to write to remote" msgstr "no s'ha pogut escriure al remot" +#: fetch-pack.c msgid "Server supports filter" msgstr "El servidor accepta filtratge" +#: fetch-pack.c #, c-format msgid "invalid shallow line: %s" msgstr "línia de shallow no vàlida: %s" +#: fetch-pack.c #, c-format msgid "invalid unshallow line: %s" msgstr "línia d'unshallow no vàlida: %s" +#: fetch-pack.c #, c-format msgid "object not found: %s" msgstr "objecte no trobat: %s" +#: fetch-pack.c #, c-format msgid "error in object: %s" msgstr "error en objecte: %s" +#: fetch-pack.c #, c-format msgid "no shallow found: %s" msgstr "no s'ha trobat cap shallow: %s" +#: fetch-pack.c #, c-format msgid "expected shallow/unshallow, got %s" msgstr "s'esperava shallow/unshallow, s'ha rebut %s" +#: fetch-pack.c #, c-format msgid "got %s %d %s" msgstr "s'ha rebut %s %d %s" +#: fetch-pack.c #, c-format msgid "invalid commit %s" msgstr "comissió no vàlida %s" +#: fetch-pack.c msgid "giving up" msgstr "s'abandona" +#: fetch-pack.c progress.h msgid "done" msgstr "fet" +#: fetch-pack.c #, c-format msgid "got %s (%d) %s" msgstr "s'ha rebut %s (%d) %s" +#: fetch-pack.c #, c-format msgid "Marking %s as complete" msgstr "S'està marcant %s com a complet" +#: fetch-pack.c #, c-format msgid "already have %s (%s)" msgstr "ja es té %s (%s)" +#: fetch-pack.c msgid "fetch-pack: unable to fork off sideband demultiplexer" msgstr "fetch-pack: no s'ha pogut bifurcar del desmultiplexor de banda lateral" +#: fetch-pack.c msgid "protocol error: bad pack header" msgstr "error de protocol: capçalera de paquet errònia" +#: fetch-pack.c #, c-format msgid "fetch-pack: unable to fork off %s" msgstr "fetch-pack: no es pot bifurcar de %s" +#: fetch-pack.c msgid "fetch-pack: invalid index-pack output" msgstr "fetch-pack: sortida d'index-pack no vàlida" +#: fetch-pack.c #, c-format msgid "%s failed" msgstr "%s ha fallat" +#: fetch-pack.c msgid "error in sideband demultiplexer" msgstr "error en desmultiplexor de banda lateral" +#: fetch-pack.c #, c-format msgid "Server version is %.*s" msgstr "La versió del servidor és %.*s" +#: fetch-pack.c #, c-format msgid "Server supports %s" msgstr "El servidor accepta %s" +#: fetch-pack.c msgid "Server does not support shallow clients" msgstr "El servidor no permet clients superficials" +#: fetch-pack.c msgid "Server does not support --shallow-since" msgstr "El servidor no admet --shallow-since" +#: fetch-pack.c msgid "Server does not support --shallow-exclude" msgstr "El servidor no admet --shallow-exclude" +#: fetch-pack.c msgid "Server does not support --deepen" msgstr "El servidor no admet --deepen" +#: fetch-pack.c msgid "Server does not support this repository's object format" msgstr "" "El servidor no és compatible amb el format d'objecte d'aquest repositori" +#: fetch-pack.c msgid "no common commits" msgstr "cap comissió en comú" +#: fetch-pack.c msgid "git fetch-pack: fetch failed." msgstr "git fetch-pack: l'obtenció ha fallat." +#: fetch-pack.c #, c-format msgid "mismatched algorithms: client %s; server %s" msgstr "algoritmes no coincidents: client %s; servidor %s" +#: fetch-pack.c #, c-format msgid "the server does not support algorithm '%s'" msgstr "el servidor no és compatible amb l'algorisme «%s»" +#: fetch-pack.c msgid "Server does not support shallow requests" msgstr "El servidor no permet sol·licituds superficials" +#: fetch-pack.c msgid "unable to write request to remote" msgstr "no s'ha pogut escriure la sol·licitud al remot" +#: fetch-pack.c #, c-format msgid "expected '%s', received '%s'" msgstr "s'esperava «%s», s'ha rebut «%s»" +#: fetch-pack.c #, c-format msgid "expected '%s'" msgstr "s'esperava «%s»" +#: fetch-pack.c #, c-format msgid "unexpected acknowledgment line: '%s'" msgstr "línia de confirmació inesperada: «%s»" +#: fetch-pack.c #, c-format msgid "error processing acks: %d" msgstr "s'ha produït un error en processar els acks: %d" @@ -16633,6 +21193,7 @@ msgstr "s'ha produït un error en processar els acks: %d" #. TRANSLATORS: The parameter will be 'ready', a protocol #. keyword. #. +#: fetch-pack.c #, c-format msgid "expected packfile to be sent after '%s'" msgstr "s'esperava que el fitxer de paquet s'enviés després de «%s»" @@ -16640,74 +21201,93 @@ msgstr "s'esperava que el fitxer de paquet s'enviés després de «%s»" #. TRANSLATORS: The parameter will be 'ready', a protocol #. keyword. #. +#: fetch-pack.c #, c-format msgid "expected no other sections to be sent after no '%s'" msgstr "no s'esperava que cap altra secció s'enviés després de «%s»" +#: fetch-pack.c #, c-format msgid "error processing shallow info: %d" msgstr "s'ha produït un error en processar la informació superficial: %d" +#: fetch-pack.c #, c-format msgid "expected wanted-ref, got '%s'" msgstr "s'esperava wanted-ref, s'ha rebut «%s»" +#: fetch-pack.c #, c-format msgid "unexpected wanted-ref: '%s'" msgstr "wanted-ref inesperat: «%s»" +#: fetch-pack.c #, c-format msgid "error processing wanted refs: %d" msgstr "s'ha produït un error en processar les referències desitjades: %d" +#: fetch-pack.c msgid "git fetch-pack: expected response end packet" msgstr "git fetch-pack: s'esperava un paquet de final de resposta" +#: fetch-pack.c msgid "no matching remote head" msgstr "no hi ha cap HEAD remot coincident" +#: fetch-pack.c msgid "unexpected 'ready' from remote" msgstr "«ready» no esperat des del remot" +#: fetch-pack.c #, c-format msgid "no such remote ref %s" msgstr "no existeix la referència remota %s" +#: fetch-pack.c #, c-format msgid "Server does not allow request for unadvertised object %s" msgstr "El servidor no permet sol·licitar objectes no anunciats %s" +#: fsmonitor-ipc.c #, c-format msgid "fsmonitor_ipc__send_query: invalid path '%s'" msgstr "fsmonitor_ipc__send_query: camí no vàlid «%s»" +#: fsmonitor-ipc.c #, c-format msgid "fsmonitor_ipc__send_query: unspecified error on '%s'" msgstr "fsmonitor_ipc__send_query: error no especificat en «%s»" +#: fsmonitor-ipc.c msgid "fsmonitor--daemon is not running" msgstr "fsmonitor--daemon no s'està executant" +#: fsmonitor-ipc.c #, c-format msgid "could not send '%s' command to fsmonitor--daemon" msgstr "no s'ha pogut enviar l'ordre «%s» a fsmonitor--daemon" +#: fsmonitor-settings.c #, c-format msgid "bare repository '%s' is incompatible with fsmonitor" msgstr "el repositori nu «%s» és incompatible amb fsmonitor" +#: fsmonitor-settings.c #, c-format msgid "repository '%s' is incompatible with fsmonitor due to errors" msgstr "el repositori «%s» és incompatible amb fsmonitor a causa d'errors" +#: fsmonitor-settings.c #, c-format msgid "remote repository '%s' is incompatible with fsmonitor" msgstr "el repositori remot «%s» no és compatible amb fsmonitor" +#: fsmonitor-settings.c #, c-format msgid "virtual repository '%s' is incompatible with fsmonitor" msgstr "el repositori virtual «%s» és incompatible amb fsmonitor" +#: fsmonitor-settings.c #, c-format msgid "" "socket directory '%s' is incompatible with fsmonitor due to lack of Unix " @@ -16716,21 +21296,27 @@ msgstr "" "el directori del sòcol «%s» és incompatible amb fsmonitor a causa de la " "manca de compatibilitat amb els sòcols Unix" +#: git.c msgid "" "git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n" " [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n" -" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--" -"bare]\n" -" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n" -" [--config-env=<name>=<envvar>] <command> [<args>]" -msgstr "" -"git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n" -" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n" -" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--" -"bare]\n" -" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n" -" [--config-env=<name>=<envvar>] <command> [<args>]" - +" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-" +"lazy-fetch]\n" +" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<path>]\n" +" [--work-tree=<path>] [--namespace=<name>] [--config-" +"env=<name>=<envvar>]\n" +" <command> [<args>]" +msgstr "" +"git [-v | --version] [-h | --help] [-C <camí>] [-c <nom>=<valor>]\n" +" [--exec-path[=<camí>]] [--html-path] [--man-path] [--info-path]\n" +" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--no-" +"lazy-fetch]\n" +" [--no-optional-locks] [--no-advice] [--bare] [--git-dir=<camí>]\n" +" [--work-tree=<camí>] [--namespace=<nom>] [--config-" +"env=<nom>=<variable-d-entorn>]\n" +" <ordre> [<arguments>]" + +#: git.c msgid "" "'git help -a' and 'git help -g' list available subcommands and some\n" "concept guides. See 'git help <command>' or 'git help <concept>'\n" @@ -16742,38 +21328,47 @@ msgstr "" "«git help <concepte>» per a llegir sobre una subordre o concepte\n" "específic. Vegeu «git help git» per a una visió general del sistema." +#: git.c help.c #, c-format msgid "unsupported command listing type '%s'" msgstr "tipus de llistat de l'ordre no compatible «%s»" +#: git.c #, c-format msgid "no directory given for '%s' option\n" msgstr "no s'ha especificat un directori per a l'opció «%s»\n" +#: git.c #, c-format msgid "no namespace given for --namespace\n" msgstr "no s'ha especificat un nom d'espai per --namespace\n" +#: git.c #, c-format msgid "-c expects a configuration string\n" msgstr "-c espera una cadena de configuració\n" +#: git.c #, c-format msgid "no config key given for --config-env\n" msgstr "no s'ha indicat cap clau de configuració per a --config-env\n" +#: git.c #, c-format msgid "no attribute source given for --attr-source\n" msgstr "no s'ha donat d'atribut font per a --attr-source\n" +#: git.c #, c-format msgid "unknown option: %s\n" msgstr "opció desconeguda: %s\n" +#: git.c #, c-format msgid "while expanding alias '%s': '%s'" msgstr "en expandir l'àlies «%s»: «%s»" +#: git.c #, c-format msgid "" "alias '%s' changes environment variables.\n" @@ -16782,31 +21377,39 @@ msgstr "" "l'àlies «%s» canvia variables d'entorn.\n" "Podeu utilitzar «!git» a l'àlies per a fer-ho" +#: git.c #, c-format msgid "empty alias for %s" msgstr "àlies buit per a %s" +#: git.c #, c-format msgid "recursive alias: %s" msgstr "àlies recursiu: %s" +#: git.c msgid "write failure on standard output" msgstr "fallada d'escriptura en la sortida estàndard" +#: git.c msgid "unknown write failure on standard output" msgstr "fallada d'escriptura desconeguda en la sortida estàndard" +#: git.c msgid "close failed on standard output" msgstr "ha fallat el tancament en la sortida estàndard" +#: git.c #, c-format msgid "alias loop detected: expansion of '%s' does not terminate:%s" msgstr "bucle d'àlies detectat expansió de «%s» no acaba:%s" +#: git.c #, c-format msgid "cannot handle %s as a builtin" msgstr "no es pot gestionar %s com a integrat" +#: git.c #, c-format msgid "" "usage: %s\n" @@ -16815,21 +21418,26 @@ msgstr "" "ús: %s\n" "\n" +#: git.c #, c-format msgid "expansion of alias '%s' failed; '%s' is not a git command\n" msgstr "ha fallat l'expansió de l'àlies «%s»; «%s» no és una ordre git\n" +#: git.c #, c-format msgid "failed to run command '%s': %s\n" msgstr "s'ha produït un error en executar l'ordre «%s»: %s\n" +#: gpg-interface.c msgid "could not create temporary file" msgstr "no s'ha pogut crear el fitxer temporal" +#: gpg-interface.c #, c-format msgid "failed writing detached signature to '%s'" msgstr "s'ha produït un error en escriure la clau de signatura separada a «%s»" +#: gpg-interface.c msgid "" "gpg.ssh.allowedSignersFile needs to be configured and exist for ssh " "signature verification" @@ -16837,6 +21445,7 @@ msgstr "" "gpg.ssh.allowedSignersFile s'ha de configurar i existeix per a la " "verificació de la signatura ssh" +#: gpg-interface.c msgid "" "ssh-keygen -Y find-principals/verify is needed for ssh signature " "verification (available in openssh version 8.2p1+)" @@ -16844,32 +21453,39 @@ msgstr "" "ssh-keygen -Y find-principals/verify és necessari per a la verificació de la " "signatura ssh (disponible a opensh versió 8.2p1+)" +#: gpg-interface.c #, c-format msgid "ssh signing revocation file configured but not found: %s" msgstr "fitxer de revocació de la signatura ssh configurat però no trobat: %s" +#: gpg-interface.c #, c-format msgid "bad/incompatible signature '%s'" msgstr "la signatura «%s» és incompatible o està malmesa" +#: gpg-interface.c #, c-format msgid "failed to get the ssh fingerprint for key '%s'" msgstr "no s'ha pogut obtenir l'empremta ssh de la clau «%s»" +#: gpg-interface.c msgid "" "either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured" msgstr "" "o bé user.signingkey o gpg.ssh.defaultKeyCommand han de ser configurats" +#: gpg-interface.c #, c-format msgid "gpg.ssh.defaultKeyCommand succeeded but returned no keys: %s %s" msgstr "" "gpg.ssh.defaultKeyCommand ha tingut èxit però no ha retornat cap clau: %s %s" +#: gpg-interface.c #, c-format msgid "gpg.ssh.defaultKeyCommand failed: %s %s" msgstr "gpg.ssh.defaultKeyCommand ha fallat: %s %s" +#: gpg-interface.c #, c-format msgid "" "gpg failed to sign the data:\n" @@ -16878,17 +21494,21 @@ msgstr "" "gpg ha fallat en signar les dades:\n" "%s" +#: gpg-interface.c msgid "user.signingKey needs to be set for ssh signing" msgstr "user.signingKey s'ha d'establir per a signar amb ssh" +#: gpg-interface.c #, c-format msgid "failed writing ssh signing key to '%s'" msgstr "s'ha produït un error en escriure la clau de signatura ssh a «%s»" +#: gpg-interface.c #, c-format msgid "failed writing ssh signing key buffer to '%s'" msgstr "s'ha produït un error en escriure la clau de signatura ssh a «%s»" +#: gpg-interface.c msgid "" "ssh-keygen -Y sign is needed for ssh signing (available in openssh version " "8.2p1+)" @@ -16896,102 +21516,132 @@ msgstr "" "ssh-keygen -Y sign és necessari per a signar amb ssh (disponible a openssh " "versió 8.2p1+)" +#: gpg-interface.c #, c-format msgid "failed reading ssh signing data buffer from '%s'" msgstr "s'ha produït un error en llegir la signatura ssh des de «%s»" +#: graph.c #, c-format msgid "ignored invalid color '%.*s' in log.graphColors" msgstr "ignora el color no vàlid «%.*s» a log.graphColors" +#: grep.c msgid "" "given pattern contains NULL byte (via -f <file>). This is only supported " "with -P under PCRE v2" msgstr "" -"el patró indicat conté byte NULL (via -f <fitxer>). Això només és compatible " -"amb -P sota PCRE v2" +"el patró indicat conté l'octet NULL (via -f <fitxer>). Això només és " +"compatible amb -P sota PCRE v2" +#: grep.c #, c-format msgid "'%s': unable to read %s" msgstr "«%s»: no s'ha pogut llegir %s" +#: grep.c #, c-format msgid "'%s': short read" msgstr "«%s»: lectura curta" +#: help.c msgid "start a working area (see also: git help tutorial)" msgstr "començar una àrea de treball (vegeu també: git help tutorial)" +#: help.c msgid "work on the current change (see also: git help everyday)" msgstr "treballar en el canvi actual (vegeu també: git help everyday)" +#: help.c msgid "examine the history and state (see also: git help revisions)" msgstr "examinar la història i l'estat (vegeu també: git help revisions)" +#: help.c msgid "grow, mark and tweak your common history" msgstr "fer créixer, marcar i ajustar la vostra història comuna" +#: help.c msgid "collaborate (see also: git help workflows)" msgstr "col·laborar (vegeu també: git help workflow)" +#: help.c msgid "Main Porcelain Commands" msgstr "Ordres principals de porcellana" +#: help.c msgid "Ancillary Commands / Manipulators" msgstr "Ordres auxiliars / manipuladors" +#: help.c msgid "Ancillary Commands / Interrogators" msgstr "Ordres auxiliars / interrogadors" +#: help.c msgid "Interacting with Others" msgstr "Interaccionar amb altres" +#: help.c msgid "Low-level Commands / Manipulators" msgstr "Ordres de baix nivell / Manipuladors" +#: help.c msgid "Low-level Commands / Interrogators" msgstr "Ordres de baix nivell / Interrogadors" +#: help.c msgid "Low-level Commands / Syncing Repositories" msgstr "Ordres de baix nivell / Sincronització de repositoris" +#: help.c msgid "Low-level Commands / Internal Helpers" msgstr "Ordres de baix nivell / Ajudants interns" +#: help.c msgid "User-facing repository, command and file interfaces" msgstr "Repositori, ordre i interfície de fitxers que veu l'usuari" +#: help.c msgid "Developer-facing file formats, protocols and other interfaces" -msgstr "Formats de fitxers, protocols i interfícies que veu el desenvolupador" +msgstr "Formats de fitxer, protocols i interfícies que veu el desenvolupador" +#: help.c #, c-format msgid "available git commands in '%s'" msgstr "ordres de git disponibles en «%s»" +#: help.c msgid "git commands available from elsewhere on your $PATH" msgstr "ordres de git disponibles d'altres llocs en el vostre $PATH" +#: help.c msgid "These are common Git commands used in various situations:" msgstr "Aquestes són ordres habituals del Git usades en diverses situacions:" +#: help.c msgid "The Git concept guides are:" msgstr "Les guies de Git de conceptes són:" +#: help.c msgid "User-facing repository, command and file interfaces:" msgstr "Repositori, ordre i interfície de fitxers que veu l'usuari:" +#: help.c msgid "File formats, protocols and other developer interfaces:" msgstr "Formats de fitxer, protocols i altres interfícies de desenvolupador:" +#: help.c msgid "External commands" msgstr "Ordres externes" +#: help.c msgid "Command aliases" msgstr "Àlies d'ordres" +#: help.c msgid "See 'git help <command>' to read about a specific subcommand" msgstr "Vegeu «git help <ordre>» per a llegir sobre una subordre específica" +#: help.c #, c-format msgid "" "'%s' appears to be a git command, but we were not\n" @@ -17000,31 +21650,38 @@ msgstr "" "«%s» sembla una ordre de git, però no hem pogut\n" "executar-la. Pot ser que git-%s estigui malmès?" +#: help.c #, c-format msgid "git: '%s' is not a git command. See 'git --help'." msgstr "git: «%s» no és una ordre de git. Vegeu «git --help»." +#: help.c msgid "Uh oh. Your system reports no Git commands at all." msgstr "Ai. El vostre sistema no informa de cap ordre de Git." +#: help.c #, c-format msgid "WARNING: You called a Git command named '%s', which does not exist." msgstr "" "ADVERTÈNCIA: Heu invocat una ordre de Git amb nom «%s», la qual no existeix." +#: help.c #, c-format msgid "Continuing under the assumption that you meant '%s'." msgstr "El procés continuarà, pressuposant que volíeu dir «%s»." +#: help.c #, c-format msgid "Run '%s' instead [y/N]? " msgstr "Voleu executar «%s» en el seu lloc? [y/N]? " +#: help.c #, c-format msgid "Continuing in %0.1f seconds, assuming that you meant '%s'." msgstr "" "El procés continuarà en %0.1f segons, pressuposant que volíeu dir «%s»." +#: help.c msgid "" "\n" "The most similar command is" @@ -17038,13 +21695,16 @@ msgstr[1] "" "\n" "Les ordres més similars són" +#: help.c msgid "git version [--build-options]" msgstr "git version [--build-options]" +#: help.c #, c-format msgid "%s: %s - %s" msgstr "%s: %s - %s" +#: help.c msgid "" "\n" "Did you mean this?" @@ -17058,6 +21718,7 @@ msgstr[1] "" "\n" "Volíeu dir un d'aquests?" +#: hook.c #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" @@ -17066,40 +21727,62 @@ msgstr "" "El lligam «%s» s'ha ignorat perquè no s'ha establert com a executable.\n" "Podeu desactivar aquest avís amb «git config advice.ignoredHook false»." +#: http-fetch.c +msgid "not a git repository" +msgstr "no és un repositori de git" + +#: http-fetch.c #, c-format msgid "argument to --packfile must be a valid hash (got '%s')" msgstr "l'argument a --packfile ha de ser un resum vàlid (s'ha obtingut «%s»)" -msgid "not a git repository" -msgstr "no és un repositori de git" - +#: http.c #, c-format msgid "negative value for http.postBuffer; defaulting to %d" msgstr "valor negatiu per http.postBuffer; utilitzant el valor %d" +#: http.c msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "No s'admet el control de delegació amb el cURL < 7.22.0" +#: http.c msgid "Public key pinning not supported with cURL < 7.39.0" msgstr "No s'admet la fixació de clau pública amb cURL < 7.39.0" +#: http.c +msgid "Unknown value for http.proactiveauth" +msgstr "Valor desconegut de http.proactiveauth" + +#: http.c msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" msgstr "CURLSSLOPT_NO_REVOKE no està admès amb cURL < 7.44.0" +#: http.c #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "El rerefons SSL «%s» no està admès. Els rerefons SSL admesos:" +#: http.c #, c-format msgid "Could not set SSL backend to '%s': cURL was built without SSL backends" msgstr "" "No s'ha pogut establir el rerefons SSL a «%s»: cURL es va construir sense " "rerefons SSL" +#: http.c #, c-format msgid "Could not set SSL backend to '%s': already set" msgstr "No s'ha pogut establir el rerefons SSL a «%s»: ja establert" +#: http.c +msgid "refusing to read cookies from http.cookiefile '-'" +msgstr "res'ha rebutjat llegir galetes del http.cookiefile «-»" + +#: http.c +msgid "ignoring http.savecookies for empty http.cookiefile" +msgstr "s'està ignorant http.savecookies per al http.cookiefile buit" + +#: http.c #, c-format msgid "" "unable to update url base from redirection:\n" @@ -17110,12 +21793,15 @@ msgstr "" " petició: %s\n" " redirecció: %s" +#: ident.c msgid "Author identity unknown\n" msgstr "Identitat de l'autor desconeguda\n" +#: ident.c msgid "Committer identity unknown\n" msgstr "Es desconeix la identitat del comitent\n" +#: ident.c msgid "" "\n" "*** Please tell me who you are.\n" @@ -17140,88 +21826,110 @@ msgstr "" "per a establir la identitat predeterminada del vostre compte.\n" "Ometeu --global per a establir la identitat només en aquest repositori.\n" +#: ident.c msgid "no email was given and auto-detection is disabled" msgstr "" "no s'ha proporcionat cap adreça electrònica i la detecció automàtica està " "inhabilitada" +#: ident.c #, c-format msgid "unable to auto-detect email address (got '%s')" msgstr "" "no s'ha pogut detectar automàticament una adreça electrònica vàlida (s'ha " "rebut «%s»)" +#: ident.c msgid "no name was given and auto-detection is disabled" msgstr "" "no s'ha proporcionat cap nom i la detecció automàtica està inhabilitada" +#: ident.c #, c-format msgid "unable to auto-detect name (got '%s')" msgstr "no s'ha pogut detectar automàticament el nom (s'ha rebut «%s»)" +#: ident.c #, c-format msgid "empty ident name (for <%s>) not allowed" msgstr "nom d'identitat buit (per <%s>) no és permès" +#: ident.c #, c-format msgid "name consists only of disallowed characters: %s" msgstr "el nom conté només caràcters no permesos: %s" +#: list-objects-filter-options.c msgid "expected 'tree:<depth>'" msgstr "s'esperava «tree:<profunditat>»" +#: list-objects-filter-options.c msgid "sparse:path filters support has been dropped" msgstr "sparse: s'ha eliminat la implementació de filtres de camí sparse" +#: list-objects-filter-options.c #, c-format msgid "'%s' for 'object:type=<type>' is not a valid object type" msgstr "«%s» per a «object:type=<tipus>» no és un tipus d'objecte vàlid" +#: list-objects-filter-options.c #, c-format msgid "invalid filter-spec '%s'" msgstr "filtre d'especificació no vàlid: «%s»" +#: list-objects-filter-options.c #, c-format msgid "must escape char in sub-filter-spec: '%c'" msgstr "cal escapar el caràcter en el sub-filter-spec «%c»" +#: list-objects-filter-options.c msgid "expected something after combine:" msgstr "s'esperava alguna cosa després de combinar:" +#: list-objects-filter-options.c msgid "multiple filter-specs cannot be combined" msgstr "no es poden combinar múltiples especificacions de filtratge" +#: list-objects-filter-options.c msgid "unable to upgrade repository format to support partial clone" msgstr "" "no s'ha pogut actualitzar el format del repositori perquè sigui compatible " "amb un clonatge parcial" +#: list-objects-filter-options.h msgid "args" msgstr "arguments" +#: list-objects-filter-options.h msgid "object filtering" msgstr "filtratge d'objecte" +#: list-objects-filter.c #, c-format msgid "unable to access sparse blob in '%s'" msgstr "no s'ha pogut accedir a un blob dispers en «%s»" +#: list-objects-filter.c #, c-format msgid "unable to parse sparse filter data in %s" msgstr "no s'han pogut analitzar les dades disperses filtrades %s" +#: list-objects.c #, c-format msgid "entry '%s' in tree %s has tree mode, but is not a tree" msgstr "l'entrada «%s» a l'arbre %s té mode d'arbre, però no és un arbre" +#: list-objects.c #, c-format msgid "entry '%s' in tree %s has blob mode, but is not a blob" msgstr "l'entrada «%s» a l'arbre %s té mode blob, però no és un blob" +#: list-objects.c #, c-format msgid "unable to load root tree for commit %s" msgstr "no s'ha pogut carregar l'arrel de l'arbre per la comissió %s" +#: lockfile.c #, c-format msgid "" "Unable to create '%s.lock': %s.\n" @@ -17241,46 +21949,82 @@ msgstr "" "ha fallat en aquest repositori abans:\n" "elimineu el fitxer manualment per a continuar." +#: lockfile.c #, c-format msgid "Unable to create '%s.lock': %s" msgstr "No s'ha pogut crear «%s.lock»: %s" +#: log-tree.c +msgid "unable to create temporary object directory" +msgstr "no s'ha pogut crear el directori temporal de l'objecte" + +#: loose.c +#, c-format +msgid "could not write loose object index %s" +msgstr "no s'ha pogut escriure l'índex d'objecte solt %s" + +#: loose.c +#, c-format +msgid "failed to write loose object index %s" +msgstr "no s'ha pogut escriure l'índex d'objectes solts %s" + +#: ls-refs.c #, c-format msgid "unexpected line: '%s'" msgstr "línia inesperada: «%s»" +#: ls-refs.c msgid "expected flush after ls-refs arguments" msgstr "s'esperava una neteja després dels arguments ls-refs" +#: mailinfo.c msgid "quoted CRLF detected" msgstr "CRLF entre cometes detectat" +#: mem-pool.c strbuf.c wrapper.c +#, c-format +msgid "unable to format message: %s" +msgstr "no es pot formatar el missatge: %s" + +#: merge-ort.c merge-recursive.c #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "S'ha produït un error en fusionar el submòdul %s (no està agafat)" +#: merge-ort.c #, c-format msgid "Failed to merge submodule %s (no merge base)" msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha fusió base)" +#: merge-ort.c merge-recursive.c #, c-format msgid "Failed to merge submodule %s (commits not present)" msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha comissions)" +# corrupt → malmès OK per a repositori? +#: merge-ort.c +#, c-format +msgid "error: failed to merge submodule %s (repository corrupt)" +msgstr "error: no s'ha pogut fusionar el submòdul %s (repositori malmès)" + +#: merge-ort.c merge-recursive.c #, c-format msgid "Failed to merge submodule %s (commits don't follow merge-base)" msgstr "" "S'ha produït un error en fusionar el submòdul %s (les comissions no " "segueixen merge-base)" +#: merge-ort.c #, c-format msgid "Note: Fast-forwarding submodule %s to %s" msgstr "Nota: avançament ràpid del submòdul %s a %s" +#: merge-ort.c #, c-format msgid "Failed to merge submodule %s" msgstr "S'ha produït un error en fusionar el submòdul «%s»" +#: merge-ort.c #, c-format msgid "" "Failed to merge submodule %s, but a possible merge resolution exists: %s" @@ -17288,6 +22032,7 @@ msgstr "" "S'ha produït un error en fusionar el submòdul %s, però existeix una solució " "possible: %s" +#: merge-ort.c #, c-format msgid "" "Failed to merge submodule %s, but multiple possible merges exist:\n" @@ -17297,17 +22042,22 @@ msgstr "" "solucions possibles:\n" "%s" -msgid "failed to execute internal merge" -msgstr "no s'ha pogut executar la fusió interna" +#: merge-ort.c +#, c-format +msgid "error: failed to execute internal merge for %s" +msgstr "no s'ha pogut executar la fusió interna per a %s" +#: merge-ort.c #, c-format -msgid "unable to add %s to database" -msgstr "no s'ha pogut afegir %s a la base de dades" +msgid "error: unable to add %s to database" +msgstr "error: no es pot afegir %s a la base de dades" +#: merge-ort.c merge-recursive.c #, c-format msgid "Auto-merging %s" msgstr "S'està autofusionant %s" +#: merge-ort.c merge-recursive.c #, c-format msgid "" "CONFLICT (implicit dir rename): Existing file/dir at %s in the way of " @@ -17317,6 +22067,7 @@ msgstr "" "existent a %s en forma de canvi del nom del directori implícit, posant-hi " "els camins següents a: %s." +#: merge-ort.c merge-recursive.c #, c-format msgid "" "CONFLICT (implicit dir rename): Cannot map more than one path to %s; " @@ -17326,6 +22077,7 @@ msgstr "" "camí a %s; els canvis del nom del directori implícits han intentat posar " "aquests camins a: %s segons" +#: merge-ort.c #, c-format msgid "" "CONFLICT (directory rename split): Unclear where to rename %s to; it was " @@ -17336,6 +22088,7 @@ msgstr "" "%s; s'han canviat de nom a múltiples altres directoris, sense una destinació " "per a la majoria dels fitxers." +#: merge-ort.c merge-recursive.c #, c-format msgid "" "WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was " @@ -17344,6 +22097,7 @@ msgstr "" "AVÍS: S'està evitant aplicar el canvi de nom %s -> %s a %s, perquè %s ell " "mateix ja havia canviat de nom." +#: merge-ort.c merge-recursive.c #, c-format msgid "" "Path updated: %s added in %s inside a directory that was renamed in %s; " @@ -17352,6 +22106,7 @@ msgstr "" "Pedaç actualitzat: %s afegit a %s dins d'un directori que va canviar de nom " "a %s; movent-lo a %s." +#: merge-ort.c merge-recursive.c #, c-format msgid "" "Path updated: %s renamed to %s in %s, inside a directory that was renamed in " @@ -17360,6 +22115,7 @@ msgstr "" "Pedaç actualitzat: %s canviat al nom %s a %s, dins d'un directori que va " "canviar de nom a %s; movent-lo a %s." +#: merge-ort.c merge-recursive.c #, c-format msgid "" "CONFLICT (file location): %s added in %s inside a directory that was renamed " @@ -17368,6 +22124,7 @@ msgstr "" "CONFLICTE (ubicació del fitxer): %s afegit a %s dins d'un directori que va " "canviar de nom a %s suggerint que potser hauria de moure's a %s." +#: merge-ort.c merge-recursive.c #, c-format msgid "" "CONFLICT (file location): %s renamed to %s in %s, inside a directory that " @@ -17377,11 +22134,13 @@ msgstr "" "directori que va canviar de nom a %s, suggerint que potser hauria de moure's " "a %s." +#: merge-ort.c #, c-format msgid "CONFLICT (rename/rename): %s renamed to %s in %s and to %s in %s." msgstr "" "CONFLICTE (canvi de nom/canvi de nom): %s ara té el nom %s a %s i %s a %s." +#: merge-ort.c #, c-format msgid "" "CONFLICT (rename involved in collision): rename of %s -> %s has content " @@ -17392,20 +22151,24 @@ msgstr "" "%s té conflictes de contingut i col·lisiona amb un altre camí; això pot " "donar lloc a marcadors de conflicte imbricats." +#: merge-ort.c #, c-format msgid "CONFLICT (rename/delete): %s renamed to %s in %s, but deleted in %s." msgstr "" "CONFLICTE (canvi de nom/supressió): %s ara té el nom %s a %s, però s'ha " "suprimit a %s." +#: merge-ort.c #, c-format -msgid "cannot read object %s" -msgstr "no es pot llegir l'objecte %s" +msgid "error: cannot read object %s" +msgstr "error: no es pot llegir l'objecte %s" +#: merge-ort.c #, c-format -msgid "object %s is not a blob" -msgstr "l'objecte %s no és un blob" +msgid "error: object %s is not a blob" +msgstr "error: l'objecte %s no és un blob" +#: merge-ort.c #, c-format msgid "" "CONFLICT (file/directory): directory in the way of %s from %s; moving it to " @@ -17414,6 +22177,7 @@ msgstr "" "CONFLICTE (fitxer/directori): directori en el camí de %s des de %s; en " "comptes es mou a %s." +#: merge-ort.c #, c-format msgid "" "CONFLICT (distinct types): %s had different types on each side; renamed both " @@ -17422,6 +22186,7 @@ msgstr "" "CONFLICTE (tipus diferents): %s tenia diferents tipus a cada costat; se'ls " "ha canviat el nom per tal que cadascun pugui ser registrat en algun lloc." +#: merge-ort.c #, c-format msgid "" "CONFLICT (distinct types): %s had different types on each side; renamed one " @@ -17431,19 +22196,24 @@ msgstr "" "canviat el nom d'un d'ells per tal que cadascun pugui ser registrat en algun " "lloc." +#: merge-ort.c merge-recursive.c msgid "content" msgstr "contingut" +#: merge-ort.c merge-recursive.c msgid "add/add" msgstr "afegiment/afegiment" +#: merge-ort.c merge-recursive.c msgid "submodule" msgstr "submòdul" +#: merge-ort.c merge-recursive.c #, c-format msgid "CONFLICT (%s): Merge conflict in %s" msgstr "CONFLICTE (%s): Conflicte de fusió en %s" +#: merge-ort.c #, c-format msgid "" "CONFLICT (modify/delete): %s deleted in %s and modified in %s. Version %s " @@ -17458,6 +22228,7 @@ msgstr "" #. commit that needs to be merged. For example: #. - go to submodule (mysubmodule), and either merge commit abc1234" #. +#: merge-ort.c #, c-format msgid "" " - go to submodule (%s), and either merge commit %s\n" @@ -17466,6 +22237,7 @@ msgstr "" " - aneu al submòdul (%s), i fusioneu la comissió %s\n" " o actualitzeu-la a una comissió existent que ha fusionat aquests canvis\n" +#: merge-ort.c #, c-format msgid "" "Recursive merging with submodules currently only supports trivial cases.\n" @@ -17493,75 +22265,98 @@ msgstr "" #. TRANSLATORS: The %s arguments are: 1) tree hash of a merge #. base, and 2-3) the trees for the two trees we're merging. #. +#: merge-ort.c #, c-format msgid "collecting merge info failed for trees %s, %s, %s" msgstr "" "ha fallat la recollida de la informació de fusió per als arbres %s, %s, %s" +#: merge-recursive.c msgid "(bad commit)\n" msgstr "(comissió errònia)\n" +#: merge-recursive.c #, c-format msgid "add_cacheinfo failed for path '%s'; merge aborting." msgstr "add_cacheinfo ha fallat per al camí «%s»; interrompent la fusió." +#: merge-recursive.c #, c-format msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." msgstr "" "add_cacheinfo ha fallat al refrescar el camí «%s»; interrompent la fusió." +#: merge-recursive.c #, c-format msgid "failed to create path '%s'%s" msgstr "s'ha produït un error en crear el camí «%s»%s" +#: merge-recursive.c #, c-format msgid "Removing %s to make room for subdirectory\n" msgstr "S'està eliminant %s per a fer espai per al subdirectori\n" +#: merge-recursive.c msgid ": perhaps a D/F conflict?" msgstr ": potser un conflicte D/F?" +#: merge-recursive.c #, c-format msgid "refusing to lose untracked file at '%s'" msgstr "s'està refusant perdre el fitxer no seguit a «%s»" +#: merge-recursive.c #, c-format msgid "blob expected for %s '%s'" msgstr "blob esperat per a %s «%s»" +#: merge-recursive.c #, c-format msgid "failed to open '%s': %s" msgstr "s'ha produït un error en obrir «%s»: %s" +#: merge-recursive.c #, c-format msgid "failed to symlink '%s': %s" msgstr "s'ha produït un error en fer l'enllaç simbòlic «%s»: %s" +#: merge-recursive.c #, c-format msgid "do not know what to do with %06o %s '%s'" msgstr "no se sap què fer amb %06o %s «%s»" +#: merge-recursive.c +#, c-format +msgid "Failed to merge submodule %s (repository corrupt)" +msgstr "No s'ha pogut fusionar el submòdul %s (repositori malmès)" + +#: merge-recursive.c #, c-format msgid "Fast-forwarding submodule %s to the following commit:" msgstr "Avançament ràpid del submòdul %s a la següent comissió:" +#: merge-recursive.c #, c-format msgid "Fast-forwarding submodule %s" msgstr "Avançament ràpid al submòdul %s" +#: merge-recursive.c #, c-format msgid "Failed to merge submodule %s (merge following commits not found)" msgstr "" "Ha fallat en fusionar el submòdul %s (no s'ha trobat les comissions següents)" +#: merge-recursive.c #, c-format msgid "Failed to merge submodule %s (not fast-forward)" msgstr "" "S'ha produït un error en fusionar el submòdul %s (sense avançament ràpid)" +#: merge-recursive.c msgid "Found a possible merge resolution for the submodule:\n" msgstr "S'ha trobat una possible resolució de fusió pel submòdul:\n" +#: merge-recursive.c #, c-format msgid "" "If this is correct simply add it to the index for example\n" @@ -17578,18 +22373,30 @@ msgstr "" "\n" "que acceptarà aquest suggeriment.\n" +#: merge-recursive.c #, c-format msgid "Failed to merge submodule %s (multiple merges found)" msgstr "" "S'ha produït un error en fusionar el submòdul %s (s'han trobat múltiples " "fusions)" +#: merge-recursive.c +msgid "failed to execute internal merge" +msgstr "no s'ha pogut executar la fusió interna" + +#: merge-recursive.c +#, c-format +msgid "unable to add %s to database" +msgstr "no s'ha pogut afegir %s a la base de dades" + +#: merge-recursive.c #, c-format msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." msgstr "" "Error: s'està refusant perdre el fitxer no seguit a %s; en comptes s'ha " "escrit a %s." +#: merge-recursive.c #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -17598,6 +22405,7 @@ msgstr "" "CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s " "s'ha deixat en l'arbre." +#: merge-recursive.c #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " @@ -17606,6 +22414,7 @@ msgstr "" "CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s " "de %s s'ha deixat en l'arbre." +#: merge-recursive.c #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -17614,6 +22423,7 @@ msgstr "" "CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s " "s'ha deixat en l'arbre a %s." +#: merge-recursive.c #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " @@ -17622,38 +22432,46 @@ msgstr "" "CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s " "de %s s'ha deixat en l'arbre a %s." +#: merge-recursive.c msgid "rename" msgstr "canvi de nom" +#: merge-recursive.c msgid "renamed" msgstr "canviat de nom" +#: merge-recursive.c #, c-format msgid "Refusing to lose dirty file at %s" msgstr "S'està refusant a perdre el fitxer brut a %s" +#: merge-recursive.c #, c-format msgid "Refusing to lose untracked file at %s, even though it's in the way." msgstr "" "S'està refusant perdre el fitxer no seguit a «%s», malgrat que està en mig " "de l'operació." +#: merge-recursive.c #, c-format msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" msgstr "" "CONFLICTE (canvi de nom/afegiment): Canvi de nom %s->%s a %s. S'ha afegit " "%s a %s" +#: merge-recursive.c #, c-format msgid "%s is a directory in %s adding as %s instead" msgstr "%s és un directori en %s; s'està afegint com a %s en lloc d'això" +#: merge-recursive.c #, c-format msgid "Refusing to lose untracked file at %s; adding as %s instead" msgstr "" "S'està refusant perdre el fitxer no seguit a %s; en comptes, s'està afegint " "com a %s" +#: merge-recursive.c #, c-format msgid "" "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " @@ -17662,15 +22480,18 @@ msgstr "" "CONFLICTE (canvi de nom/canvi de nom): Canvi de nom «%s»->«%s» en la branca " "«%s» canvi de nom «%s»->«%s» en «%s»%s" +#: merge-recursive.c msgid " (left unresolved)" msgstr " (deixat sense resolució)" +#: merge-recursive.c #, c-format msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" msgstr "" "CONFLICTE (canvi de nom/canvi de nom): Canvi de nom %s->%s en %s. Canvi de " "nom %s->%s en %s" +#: merge-recursive.c #, c-format msgid "" "CONFLICT (directory rename split): Unclear where to place %s because " @@ -17681,6 +22502,7 @@ msgstr "" "%s perquè el directori %s s'han canviat de nom a múltiples altres " "directoris, sense una destinació per a la majoria dels fitxers." +#: merge-recursive.c #, c-format msgid "" "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" @@ -17689,285 +22511,426 @@ msgstr "" "CONFLICTE (canvi de nom/canvi de nom): canvi de nom %s->%s en %s. Canvi de " "nom de directori %s->%s en %s" +#: merge-recursive.c +#, c-format +msgid "cannot read object %s" +msgstr "no es pot llegir l'objecte %s" + +#: merge-recursive.c +#, c-format +msgid "object %s is not a blob" +msgstr "l'objecte %s no és un blob" + +#: merge-recursive.c msgid "modify" msgstr "modificació" +#: merge-recursive.c msgid "modified" msgstr "modificat" +#: merge-recursive.c #, c-format msgid "Skipped %s (merged same as existing)" msgstr "S'ha omès %s (el fusionat és igual a l'existent)" +#: merge-recursive.c #, c-format msgid "Adding as %s instead" msgstr "S'està afegint com a %s en lloc d'això" +#: merge-recursive.c #, c-format msgid "Removing %s" msgstr "S'està eliminant %s" +#: merge-recursive.c msgid "file/directory" msgstr "fitxer/directori" +#: merge-recursive.c msgid "directory/file" msgstr "directori/fitxer" +#: merge-recursive.c #, c-format msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" msgstr "" "CONFLICTE (%s): Hi ha un directori amb nom %s en %s. S'està afegint %s com a " "%s" +#: merge-recursive.c #, c-format msgid "Adding %s" msgstr "S'està afegint %s" +#: merge-recursive.c #, c-format msgid "CONFLICT (add/add): Merge conflict in %s" msgstr "CONFLICTE (afegiment/afegiment): Conflicte de fusió en %s" +#: merge-recursive.c #, c-format msgid "merging of trees %s and %s failed" msgstr "la fusió dels arbres %s i %s ha fallat" +#: merge-recursive.c msgid "Merging:" msgstr "S'està fusionant:" +#: merge-recursive.c #, c-format msgid "found %u common ancestor:" msgid_plural "found %u common ancestors:" msgstr[0] "s'ha trobat %u avantpassat en comú:" msgstr[1] "s'han trobat %u avantpassats en comú:" +#: merge-recursive.c msgid "merge returned no commit" msgstr "la fusió no ha retornat cap comissió" +#: merge-recursive.c #, c-format msgid "Could not parse object '%s'" msgstr "No s'ha pogut analitzar l'objecte «%s»" +#: merge.c 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 «fanout» de l'índex multipaquet és d'una mida incorrecta" +#: midx-write.c +#, c-format +msgid "failed to add packfile '%s'" +msgstr "no s'ha pogut afegir el fitxer de paquet «%s»" +#: midx-write.c #, 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 "failed to open pack-index '%s'" +msgstr "no s'ha pogut obrir l'índex del paquet «%s»" -msgid "multi-pack-index OID lookup chunk is the wrong size" -msgstr "El fragment de cerca OID índex multipaquet és de mida incorrecta" +#: midx-write.c +#, c-format +msgid "failed to locate object %d in packfile" +msgstr "no s'ha pogut localitzar l'objecte %d en el fitxer de paquet" -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" +#: midx-write.c +msgid "cannot store reverse index file" +msgstr "no es pot emmagatzemar el fitxer d'índex invers" +#: midx-write.c #, c-format -msgid "multi-pack-index file %s is too small" -msgstr "el fitxer de l'índex multipaquet %s és massa petit" +msgid "could not parse line: %s" +msgstr "no s'ha pogut analitzar la línia: %s" +#: midx-write.c #, c-format -msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x" -msgstr "" -"la signatura de l'índex multipaquet 0x%08x no coincideix amb la signatura " -"0x%08x" +msgid "malformed line: %s" +msgstr "línia mal formada: %s" + +#: midx-write.c +msgid "could not load pack" +msgstr "no s'ha pogut carregar el paquet" +#: midx-write.c #, c-format -msgid "multi-pack-index version %d not recognized" -msgstr "no es reconeix la versió %d de l'índex multipaquet" +msgid "could not open index for %s" +msgstr "s'ha produït un error en obrir l'índex per «%s»" +#: midx-write.c #, c-format -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 "unable to link '%s' to '%s'" +msgstr "no s'ha pogut enllaçar «%s» a «%s»" +#: midx-write.c midx.c +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "no s'ha pogut netejar l'índex multipaquet a %s" + +#: midx-write.c +msgid "cannot write incremental MIDX with bitmap" +msgstr "no es pot escriure un MIDX incremental amb mapa de bits" + +#: midx-write.c +msgid "ignoring existing multi-pack-index; checksum mismatch" +msgstr "" +"s'està ignorant l'índex multipaquet existent; la suma de verificació no " +"coincideix" + +#: midx-write.c +msgid "Adding packfiles to multi-pack-index" +msgstr "S'estan afegint fitxers empaquetats a l'índex multipaquet" + +#: midx-write.c +#, c-format +msgid "unknown preferred pack: '%s'" +msgstr "paquet preferit desconegut: «%s»" + +#: midx-write.c +#, c-format +msgid "cannot select preferred pack %s with no objects" +msgstr "no es pot seleccionar un paquet preferit %s sense objectes" + +#: midx-write.c +#, c-format +msgid "did not see pack-file %s to drop" +msgstr "no s'ha vist caure el fitxer empaquetat %s" + +#: midx-write.c +#, c-format +msgid "preferred pack '%s' is expired" +msgstr "el paquet preferit «%s» ha caducat" + +#: midx-write.c +msgid "no pack files to index." +msgstr "no hi ha fitxers empaquetats a indexar." + +#: midx-write.c +msgid "refusing to write multi-pack .bitmap without any objects" +msgstr "s'està refusant a escriure el .bitmap multipaquet sense cap objecte" + +#: midx-write.c +msgid "unable to create temporary MIDX layer" +msgstr "no s'ha pogut crear una capa MIDX temporal" + +#: midx-write.c +msgid "could not write multi-pack bitmap" +msgstr "no s'han pogut escriure els mapes de bits dels multipaquets" + +#: midx-write.c +msgid "unable to open multi-pack-index chain file" +msgstr "no s'ha pogut obrir el fitxer de cadenes multi-path-index" + +#: midx-write.c +msgid "unable to rename new multi-pack-index layer" +msgstr "no s'ha pogut canviar el nom de la capa multi-pack-index" + +#: midx-write.c +msgid "could not write multi-pack-index" +msgstr "no s'ha pogut escriure l'índex multipaquet" + +#: midx-write.c +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "no es pot fer caducar paquets d'un multi-pack-index incremental" + +#: midx-write.c +msgid "Counting referenced objects" +msgstr "S'estan comptant els objectes referenciats" + +#: midx-write.c +msgid "Finding and deleting unreferenced packfiles" +msgstr "S'estan cercant i suprimint els fitxers de paquets no referenciats" + +#: midx-write.c +msgid "cannot repack an incremental multi-pack-index" +msgstr "no es pot reempaquetar un multi-pack-index incremental" + +#: midx-write.c +msgid "could not start pack-objects" +msgstr "no s'ha pogut iniciar el pack-objects" + +#: midx-write.c +msgid "could not finish pack-objects" +msgstr "no s'ha pogut finalitzar el pack-objects" + +#: midx.c +msgid "multi-pack-index OID fanout is of the wrong size" +msgstr "l'OID «fanout» de l'índex multipaquet és d'una mida incorrecta" + +#: midx.c +#, c-format +msgid "" +"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" +msgstr "" +"oid «fanout» desordenat: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" + +#: midx.c +msgid "multi-pack-index OID lookup chunk is the wrong size" +msgstr "El fragment de cerca OID índex multipaquet és de mida incorrecta" + +#: midx.c +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" + +#: midx.c +#, c-format +msgid "multi-pack-index file %s is too small" +msgstr "el fitxer de l'índex multipaquet %s és massa petit" + +#: midx.c +#, c-format +msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x" +msgstr "" +"la signatura de l'índex multipaquet 0x%08x no coincideix amb la signatura " +"0x%08x" + +#: midx.c +#, c-format +msgid "multi-pack-index version %d not recognized" +msgstr "no es reconeix la versió %d de l'índex multipaquet" + +#: midx.c +#, c-format +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" + +#: midx.c 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" +#: midx.c 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" +#: midx.c 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" +#: midx.c 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" +#: midx.c msgid "multi-pack-index pack-name chunk is too short" msgstr "el fragment de nom de l'índex multipaquet és massa curt" +#: midx.c #, c-format msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "" "els noms de paquet de l'índex multipaquet estan desordenats «%s» abans de " "«%s»" +#: midx.c +msgid "multi-pack-index chain file too small" +msgstr "el fitxer de cadena multi-pack-index és massa petit" + +#: midx.c +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "el recompte de paquets en el MIDX de base és massa alt: %<PRIuMAX>" + +#: midx.c +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "el recompte de objectes en el MIDX de base és massa alt: %<PRIuMAX>" + +#: midx.c +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "cadena multi-pack-index invàlida: la línia «%s» no és un hash" + +# tots els fitxers multi-pack-index ? +#: midx.c +msgid "unable to find all multi-pack index files" +msgstr "no s'han pogut trobar tots els fitxers d'índex multi-pack" + +#: midx.c +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "" +"posició invàlida de l'objecte MIDX; probablement el MIDX s'ha corromput" + +#: midx.c #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "pack-int-id: %u incorrecte (%u paquets en total)" +#: midx.c msgid "MIDX does not contain the BTMP chunk" msgstr "MIDX no conté el fragment BTMP" +#: midx.c #, c-format msgid "could not load bitmapped pack %<PRIu32>" msgstr "no s'ha pogut carregar el paquet amb bits %<PRIu32>" +#: midx.c 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" +#: midx.c 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»" - -#, c-format -msgid "failed to open pack-index '%s'" -msgstr "no s'ha pogut obrir l'índex del paquet «%s»" - -#, c-format -msgid "failed to locate object %d in packfile" -msgstr "no s'ha pogut localitzar l'objecte %d en el fitxer de paquet" - -msgid "cannot store reverse index file" -msgstr "no es pot emmagatzemar el fitxer d'índex invers" - -#, c-format -msgid "could not parse line: %s" -msgstr "no s'ha pogut analitzar la línia: %s" - -#, c-format -msgid "malformed line: %s" -msgstr "línia mal formada: %s" - -msgid "ignoring existing multi-pack-index; checksum mismatch" -msgstr "" -"s'està ignorant l'índex multipaquet existent; la suma de verificació no " -"coincideix" - -msgid "could not load pack" -msgstr "no s'ha pogut carregar el paquet" - -#, c-format -msgid "could not open index for %s" -msgstr "s'ha produït un error en obrir l'índex per «%s»" - -msgid "Adding packfiles to multi-pack-index" -msgstr "S'estan afegint fitxers empaquetats a l'índex multipaquet" - -#, c-format -msgid "unknown preferred pack: '%s'" -msgstr "paquet preferit desconegut: «%s»" - -#, c-format -msgid "cannot select preferred pack %s with no objects" -msgstr "no es pot seleccionar un paquet preferit %s sense objectes" - -#, c-format -msgid "did not see pack-file %s to drop" -msgstr "no s'ha vist caure el fitxer empaquetat %s" - -#, c-format -msgid "preferred pack '%s' is expired" -msgstr "el paquet preferit «%s» ha caducat" - -msgid "no pack files to index." -msgstr "no hi ha fitxers empaquetats a indexar." - -msgid "refusing to write multi-pack .bitmap without any objects" -msgstr "s'està refusant a escriure el .bitmap multipaquet sense cap objecte" - -msgid "could not write multi-pack bitmap" -msgstr "no s'han pogut escriure els mapes de bits dels multipaquets" - -msgid "could not write multi-pack-index" -msgstr "no s'ha pogut escriure l'índex multipaquet" - -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "no s'ha pogut netejar l'índex multipaquet a %s" - +#: midx.c msgid "multi-pack-index file exists, but failed to parse" msgstr "" "el fitxer de l'índex multipaquet existeix, però no s'ha pogut analitzar" +#: midx.c msgid "incorrect checksum" msgstr "suma de verificació incorrecta" +#: midx.c msgid "Looking for referenced packfiles" msgstr "S'estan cercant fitxers empaquetats referenciats" +#: midx.c msgid "the midx contains no oid" msgstr "el midx no conté cap oid" +#: midx.c msgid "Verifying OID order in multi-pack-index" msgstr "S'està verificant l'ordre OID a l'índex multipaquet" +#: midx.c #, c-format msgid "oid lookup out of order: oid[%d] = %s >= %s = oid[%d]" msgstr "oid lookup desordenat: oid[%d] = %s >= %s = oid[%d]" +#: midx.c msgid "Sorting objects by packfile" msgstr "S'estan ordenant els objectes per fitxer empaquetats" +#: midx.c msgid "Verifying object offsets" msgstr "S'estan verificant els desplaçaments dels objectes" +#: midx.c #, c-format msgid "failed to load pack entry for oid[%d] = %s" msgstr "no s'ha pogut carregar l'entrada del paquet per a oid[%d] = %s" +#: midx.c #, c-format msgid "failed to load pack-index for packfile %s" msgstr "no s'ha pogut carregar l'índex del paquet per al fitxer empaquetat %s" +#: midx.c #, c-format msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>" msgstr "" "desplaçament incorrecte de l'objecte per a oid[%d] = %s: %<PRIx64> != " "%<PRIx64>" -msgid "Counting referenced objects" -msgstr "S'estan comptant els objectes referenciats" - -msgid "Finding and deleting unreferenced packfiles" -msgstr "S'estan cercant i suprimint els fitxers de paquets no referenciats" - -msgid "could not start pack-objects" -msgstr "no s'ha pogut iniciar el pack-objects" - -msgid "could not finish pack-objects" -msgstr "no s'ha pogut finalitzar el pack-objects" - +#: name-hash.c #, c-format msgid "unable to create lazy_dir thread: %s" msgstr "no s'ha pogut crear el fil «lazy_dir» :%s" +#: name-hash.c #, c-format msgid "unable to create lazy_name thread: %s" msgstr "no s'ha pogut crear un fil «lazy_name»: %s" +#: name-hash.c #, c-format msgid "unable to join lazy_name thread: %s" msgstr "no s'ha pogut unir el fil «lazy_name»: %s" +#: notes-merge.c #, c-format msgid "" "You have not concluded your previous notes merge (%s exists).\n" @@ -17978,17 +22941,21 @@ msgstr "" "Useu «git notes merge --commit» o «git notes merge --abort» per a cometre/" "avortar la fusió prèvia abans de començar una fusió de notes nova." +#: notes-merge.c #, c-format msgid "You have not concluded your notes merge (%s exists)." msgstr "No heu conclòs la vostra fusió de notes (%s existeix)." +#: notes-utils.c msgid "Cannot commit uninitialized/unreferenced notes tree" msgstr "No es pot cometre un arbre de notes no inicialitzat / no referenciat" +#: notes-utils.c #, c-format msgid "Bad notes.rewriteMode value: '%s'" msgstr "Valor de notes.rewriteMode erroni: «%s»" +#: notes-utils.c #, c-format msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" msgstr "S'està refusant reescriure les notes en %s (fora de refs/notes/)" @@ -17997,217 +22964,310 @@ msgstr "S'està refusant reescriure les notes en %s (fora de refs/notes/)" #. the environment variable, the second %s is #. its value. #. +#: notes-utils.c #, c-format msgid "Bad %s value: '%s'" msgstr "Valor erroni de %s: «%s»" +#: object-file-convert.c +msgid "failed to decode tree entry" +msgstr "no s'ha pogut descodificar una entrada d'arbre" + +#: object-file-convert.c +#, c-format +msgid "failed to map tree entry for %s" +msgstr "no s'ha pogut mapar l'entrada d'arbre per a %s" + +#: object-file-convert.c +#, c-format +msgid "bad %s in commit" +msgstr "%s és incorrecte en la comissió" + +#: object-file-convert.c +#, c-format +msgid "unable to map %s %s in commit object" +msgstr "no es pot mapar %s %s en l'objecte de comissió" + +#: object-file-convert.c +#, c-format +msgid "Failed to convert object from %s to %s" +msgstr "No s'ha pogut convertir l'objecte de %s a %s" + +#: object-file.c #, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "" "no existeix el directori d'objecte %s; comproveu .git/objects/info/alternates" +#: object-file.c #, c-format msgid "unable to normalize alternate object path: %s" msgstr "no s'ha pogut normalitzar el camí a l'objecte alternatiu: %s" +#: object-file.c #, c-format msgid "%s: ignoring alternate object stores, nesting too deep" msgstr "" "%s: s'estan ignorant els emmagatzematges alternatius d'objectes, imbricació " "massa profunda" +#: object-file.c msgid "unable to fdopen alternates lockfile" msgstr "no s'ha pogut fer «fdopen» al fitxer de bloqueig alternatiu" +#: object-file.c msgid "unable to read alternates file" msgstr "no es pot llegir el fitxer «alternates»" +#: object-file.c msgid "unable to move new alternates file into place" msgstr "no s'ha pogut moure el nou fitxer «alternates» al lloc" +#: object-file.c #, c-format msgid "path '%s' does not exist" msgstr "el camí «%s» no existeix" +#: object-file.c #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "" "encara no s'admet el repositori de referència «%s» com a agafament enllaçat." +#: object-file.c #, c-format msgid "reference repository '%s' is not a local repository." msgstr "el repositori de referència «%s» no és un repositori local." +#: object-file.c #, c-format msgid "reference repository '%s' is shallow" msgstr "el repositori de referència «%s» és superficial" +#: object-file.c #, c-format msgid "reference repository '%s' is grafted" msgstr "el repositori de referència «%s» és empeltat" +#: object-file.c #, c-format msgid "could not find object directory matching %s" msgstr "no s'ha pogut trobar el directori de l'objecte que coincideixi amb %s" +#: object-file.c #, c-format msgid "invalid line while parsing alternate refs: %s" msgstr "" "línia no vàlida quan s'analitzaven les referències de l'«alternate»: %s" +#: object-file.c #, c-format msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" msgstr "s'està intentant fer mmap %<PRIuMAX> per sobre del límit %<PRIuMAX>" +#: object-file.c #, c-format msgid "mmap failed%s" msgstr "mmap ha fallat%s" +#: object-file.c #, c-format msgid "object file %s is empty" msgstr "el tipus d'objecte %s és buit" +#: object-file.c #, c-format msgid "corrupt loose object '%s'" msgstr "objecte solt corrupte «%s»" +#: object-file.c #, c-format msgid "garbage at end of loose object '%s'" msgstr "brossa al final de l'objecte solt «%s»" +#: object-file.c #, c-format msgid "unable to open loose object %s" msgstr "no s'ha pogut obrir l'objecte solt %s" +#: object-file.c #, c-format msgid "unable to parse %s header" msgstr "no s'ha pogut analitzar la capçalera %s" +#: object-file.c msgid "invalid object type" msgstr "tipus d'objecte és incorrecte" +#: object-file.c #, c-format msgid "unable to unpack %s header" msgstr "no s'ha pogut desempaquetar la capçalera %s" +#: object-file.c #, c-format msgid "header for %s too long, exceeds %d bytes" -msgstr "la capçalera per a %s és massa llarga, supera els %d bytes" +msgstr "la capçalera per a %s és massa llarga, supera els %d octets" +#: object-file.c #, c-format msgid "loose object %s (stored in %s) is corrupt" msgstr "l'objecte solt %s (emmagatzemat a %s) és corrupte" +#: object-file.c #, c-format msgid "replacement %s not found for %s" msgstr "no s'ha trobat el reemplaçament %s per a %s" +#: object-file.c #, c-format msgid "packed object %s (stored in %s) is corrupt" msgstr "l'objecte empaquetat %s (emmagatzemat a %s) és corrupte" +#: object-file.c +#, c-format +msgid "missing mapping of %s to %s" +msgstr "manca el mapatge de %s a %s" + +#: object-file.c +#, c-format +msgid "unable to open %s" +msgstr "no s'ha pogut obrir %s" + +#: object-file.c +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "els fitxers «%s» i «%s» difereixen en el contingut" + +#: object-file.c #, c-format msgid "unable to write file %s" msgstr "no s'ha pogut escriure al fitxer %s" +#: object-file.c #, c-format msgid "unable to set permission to '%s'" msgstr "no s'ha pogut establir el permís a «%s»" +#: object-file.c msgid "error when closing loose object file" msgstr "error en tancar el fitxer d'objecte solt" +#: object-file.c #, c-format msgid "insufficient permission for adding an object to repository database %s" msgstr "" "permisos insuficients per a afegir un objecte a la base de dades del " "repositori %s" +#: object-file.c msgid "unable to create temporary file" msgstr "no s'ha pogut crear un fitxer temporal" +#: object-file.c msgid "unable to write loose object file" msgstr "no s'ha pogut escriure el fitxer d'objecte solt" +#: object-file.c #, c-format msgid "unable to deflate new object %s (%d)" msgstr "no s'ha pogut desinflar l'object nou %s (%d)" +#: object-file.c #, c-format msgid "deflateEnd on object %s failed (%d)" msgstr "ha fallat deflateEnd a l'objecte %s(%d)" +#: object-file.c #, c-format msgid "confused by unstable object source data for %s" msgstr "confós per la font de dades inestable de l'objecte per a %s" +#: object-file.c #, c-format msgid "write stream object %ld != %<PRIuMAX>" msgstr "escriu l'objecte de flux %ld != %<PRIuMAX>" +#: object-file.c #, c-format msgid "unable to stream deflate new object (%d)" msgstr "no s'ha pogut desinflar l'object nou (%d)" +#: object-file.c #, c-format msgid "deflateEnd on stream object failed (%d)" msgstr "ha fallat deflateEnd a l'objecte del flux (%d)" +#: object-file.c #, c-format msgid "unable to create directory %s" msgstr "s'ha produït un error en crear el directori %s" +#: object-file.c #, c-format msgid "cannot read object for %s" msgstr "no es pot llegir l'objecte per a %s" +#: object-file.c +#, c-format +msgid "cannot map object %s to %s" +msgstr "no és possible mapar l'objecte %s a %s" + +#: object-file.c #, c-format msgid "object fails fsck: %s" msgstr "l'objecte ha fallat fsck: %s" +#: object-file.c msgid "refusing to create malformed object" msgstr "es rebutja crear un objecte mal format" +#: object-file.c #, c-format msgid "read error while indexing %s" msgstr "error de lectura mentre s'indexava %s" +#: object-file.c #, c-format msgid "short read while indexing %s" msgstr "lectura curta mentre s'indexa %s" +#: object-file.c #, c-format msgid "%s: failed to insert into database" msgstr "%s: no s'han pogut inserir a la base de dades" +#: object-file.c #, c-format msgid "%s: unsupported file type" msgstr "%s: tipus de fitxer no suportat" +#: object-file.c #, c-format msgid "%s is not a valid '%s' object" msgstr "%s no és un objecte de «%s» vàlid" -#, c-format -msgid "unable to open %s" -msgstr "no s'ha pogut obrir %s" - +#: object-file.c #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "no coincideix el resum per a %s (s'esperava %s)" +#: object-file.c #, c-format msgid "unable to mmap %s" msgstr "no s'ha pogut fer «mmap» %s" +#: object-file.c #, c-format msgid "unable to unpack header of %s" msgstr "no s'ha pogut desempaquetar la capçalera de %s" +#: object-file.c #, c-format msgid "unable to parse header of %s" msgstr "no s'ha pogut analitzar la capçalera de %s" +#: object-file.c #, c-format msgid "unable to unpack contents of %s" msgstr "no s'han pogut desempaquetar els continguts de %s" @@ -18216,6 +23276,7 @@ msgstr "no s'han pogut desempaquetar els continguts de %s" #. output shown when we cannot look up or parse the #. object in question. E.g. "deadbeef [bad object]". #. +#: object-name.c #, c-format msgid "%s [bad object]" msgstr "%s [objecte incorrecte]" @@ -18225,6 +23286,7 @@ msgstr "%s [objecte incorrecte]" #. * #. "deadbeef commit 2021-01-01 - Some Commit Message" #. +#: object-name.c #, c-format msgid "%s commit %s - %s" msgstr "%s comissió %s - %s" @@ -18240,6 +23302,7 @@ msgstr "%s comissió %s - %s" #. The third argument is the "tag" string #. from object.c. #. +#: object-name.c #, c-format msgid "%s tag %s - %s" msgstr "%s etiqueta %s - %s" @@ -18250,6 +23313,7 @@ msgstr "%s etiqueta %s - %s" #. * #. "deadbeef [bad tag, could not parse it]" #. +#: object-name.c #, c-format msgid "%s [bad tag, could not parse it]" msgstr "%s [etiqueta malmesa, no s'ha pogut analitzar]" @@ -18257,6 +23321,7 @@ msgstr "%s [etiqueta malmesa, no s'ha pogut analitzar]" #. TRANSLATORS: This is a line of ambiguous <type> #. object output. E.g. "deadbeef tree". #. +#: object-name.c #, c-format msgid "%s tree" msgstr "arbre %s" @@ -18264,10 +23329,12 @@ msgstr "arbre %s" #. TRANSLATORS: This is a line of ambiguous <type> #. object output. E.g. "deadbeef blob". #. +#: object-name.c #, c-format msgid "%s blob" msgstr "blob %s" +#: object-name.c #, c-format msgid "short object ID %s is ambiguous" msgstr "l'id d'objecte curt %s és ambigu" @@ -18276,6 +23343,7 @@ msgstr "l'id d'objecte curt %s és ambigu" #. objects composed in show_ambiguous_object(). See #. its "TRANSLATORS" comments for details. #. +#: object-name.c #, c-format msgid "" "The candidates are:\n" @@ -18284,6 +23352,7 @@ msgstr "" "Els candidats són:\n" "%s" +#: object-name.c msgid "" "Git normally never creates a ref that ends with 40 hex characters\n" "because it will be ignored when you just specify 40-hex. These refs\n" @@ -18307,18 +23376,22 @@ msgstr "" "suprimiu-les. Desactiveu aquest missatge executant\n" "«git config advice.objectNameWarning false»" +#: object-name.c #, c-format msgid "log for '%.*s' only goes back to %s" msgstr "registre per a «%.*s» només retorna a %s" +#: object-name.c #, c-format msgid "log for '%.*s' only has %d entries" msgstr "registre per a «%.*s» només té %d entrades" +#: object-name.c #, c-format msgid "path '%s' exists on disk, but not in '%.*s'" msgstr "el camí «%s» existeix al disc, però no a «%.*s»" +#: object-name.c #, c-format msgid "" "path '%s' exists, but not '%s'\n" @@ -18327,10 +23400,12 @@ msgstr "" "el camí «%s» existeix, però no «%s»\n" "consell: volíeu dir «%.*s:%s» conegut com a «%.*s:./%s»?" +#: object-name.c #, c-format msgid "path '%s' does not exist in '%.*s'" msgstr "el camí «%s» no existeix en «%.*s»" +#: object-name.c #, c-format msgid "" "path '%s' is in the index, but not at stage %d\n" @@ -18339,6 +23414,7 @@ msgstr "" "el camí «%s» està a l'índex, però no a «stage» %d\n" ".consell: volíeu dir «:%d:%s»?" +#: object-name.c #, c-format msgid "" "path '%s' is in the index, but not '%s'\n" @@ -18347,328 +23423,455 @@ msgstr "" "el camí «%s» està a l'índex, però no a «%s»\n" ".consell: volíeu dir «:%d:%s» conegut com a «:%d:./%s»?" +#: object-name.c #, c-format msgid "path '%s' exists on disk, but not in the index" msgstr "el camí «%s» existeix al disc, però no a l'índex" +#: object-name.c #, c-format msgid "path '%s' does not exist (neither on disk nor in the index)" msgstr "el camí «%s» no existeix (ni al disc ni a l'índex)" +#: object-name.c msgid "relative path syntax can't be used outside working tree" msgstr "" "la sintaxi de camí relatiu no es pot utilitzar fora de l'arbre de treball" +#: object-name.c #, c-format msgid "<object>:<path> required, only <object> '%s' given" msgstr "<objecte>:<camí> requerit, només s'ha donat <objecte> «%s»" +#: object-name.c #, c-format msgid "invalid object name '%.*s'." msgstr "nom d'objecte no vàlid «%.*s»." +#: object.c #, c-format msgid "invalid object type \"%s\"" msgstr "tipus d'objecte «%s» no vàlid" +#: object.c #, c-format msgid "object %s is a %s, not a %s" msgstr "l'objecte %s és %s, no pas %s" +#: object.c #, c-format msgid "object %s has unknown type id %d" msgstr "l'objecte %s té un identificador de tipus %d desconegut" +#: object.c #, c-format msgid "unable to parse object: %s" msgstr "no s'ha pogut analitzar l'objecte: %s" +#: object.c #, c-format msgid "hash mismatch %s" msgstr "el resum no coincideix %s" +#: pack-bitmap-write.c +#, c-format +msgid "duplicate entry when writing bitmap index: %s" +msgstr "entrada duplicada en escriure l'índex de mapa de bits: %s" + +#: pack-bitmap-write.c +#, c-format +msgid "attempted to store non-selected commit: '%s'" +msgstr "s'ha intentat emmagatzemar una comissió no seleccionada: «%s»" + +#: pack-bitmap-write.c +msgid "too many pseudo-merges" +msgstr "massa pseudo-fusions" + +#: pack-bitmap-write.c msgid "trying to write commit not in index" msgstr "s'està intentant no escriure la comissió a l'índex" +#: pack-bitmap.c msgid "failed to load bitmap index (corrupted?)" msgstr "" "s'ha produït un error en carregar l'índex de mapa de bits (està malmès?)" +#: pack-bitmap.c msgid "corrupted bitmap index (too small)" msgstr "índex de mapa de bits malmès (massa petit)" +#: pack-bitmap.c msgid "corrupted bitmap index file (wrong header)" msgstr "fitxer d'índex de mapa de bits malmès (capçalera incorrecta)" +#: pack-bitmap.c #, c-format msgid "unsupported version '%d' for bitmap index file" msgstr "versió «%d» no admesa per al fitxer d'índex de mapa de bits" +#: pack-bitmap.c msgid "corrupted bitmap index file (too short to fit hash cache)" msgstr "" "fitxer d'índex de mapa de bits malmès (massa curt per a ajustar-se a la " "memòria cau de hash)" +#: pack-bitmap.c msgid "corrupted bitmap index file (too short to fit lookup table)" msgstr "" "fitxer d'índex de mapa de bits malmès (massa curt per a ajustar-se a la " "taula de cerca)" +# 2 línies OK? +#: pack-bitmap.c +msgid "" +"corrupted bitmap index file (too short to fit pseudo-merge table header)" +msgstr "" +"fitxer d'índex de mapes de bits malmès (massa curt per a ajustar-se\n" +"a la capçalera de la taula de pseudo-fusions)" + +# 2 línies OK? +#: pack-bitmap.c +msgid "corrupted bitmap index file (too short to fit pseudo-merge table)" +msgstr "" +"fitxer d'índex de mapa de bits malmès (massa curt per a ajustar-se\n" +"a la taula de pseudo-fusions)" + +#: pack-bitmap.c +msgid "corrupted bitmap index file, pseudo-merge table too short" +msgstr "" +"fitxer d'índex de mapa de bits malmès, taula de pseudo-fusions massa curta" + +#: pack-bitmap.c #, c-format msgid "duplicate entry in bitmap index: '%s'" msgstr "entrada duplicada a l'índex del mapa de bits: «%s»" +#: pack-bitmap.c #, c-format msgid "corrupt ewah bitmap: truncated header for entry %d" msgstr "mapa de bits ewah malmès: capçalera truncada per a l'entrada %d" +#: pack-bitmap.c #, c-format msgid "corrupt ewah bitmap: commit index %u out of range" msgstr "mapa de bits ewah malmès: l'índex de comissió %u està fora de rang" +#: pack-bitmap.c msgid "corrupted bitmap pack index" msgstr "índex de paquets de mapa de bits malmès" +#: pack-bitmap.c msgid "invalid XOR offset in bitmap pack index" msgstr "el desplaçament XOR a l'índex de mapa de bits no és vàlid" +#: pack-bitmap.c msgid "cannot fstat bitmap file" msgstr "no es pot fer fstat en el fitxer de mapa de bits" +#: pack-bitmap.c msgid "checksum doesn't match in MIDX and bitmap" msgstr "la suma de verificació no coincideix amb el MIDX i el mapa de bits" +#: pack-bitmap.c msgid "multi-pack bitmap is missing required reverse index" msgstr "falta l'índex invers necessari al mapa de bits multipaquet" +#: pack-bitmap.c #, c-format msgid "could not open pack %s" msgstr "no s'ha pogut obrir el paquet %s" +#: pack-bitmap.c t/helper/test-read-midx.c msgid "could not determine MIDX preferred pack" msgstr "no s'ha pogut determinar el paquet preferit MIDX" +#: pack-bitmap.c #, c-format msgid "preferred pack (%s) is invalid" msgstr "el paquet preferit (%s) no és vàlid" +#: pack-bitmap.c msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "" "taula de cerca de mapa de bits malmesa: posició la tripleta fora de l'índex" +#: pack-bitmap.c msgid "corrupt bitmap lookup table: xor chain exceeds entry count" msgstr "" "taula de cerca de mapa de bits malmesa: la cadena xor excedeix el nombre " "d'entrades" +#: pack-bitmap.c #, c-format msgid "corrupt bitmap lookup table: commit index %u out of range" msgstr "" "taula de cerca de mapa de bits malmesa: l'índex de comissió %u està fora de " "rang" +#: pack-bitmap.c #, c-format msgid "corrupt ewah bitmap: truncated header for bitmap of commit \"%s\"" msgstr "" "mapa de bits ewah malmès: capçalera truncada per al mapa de bits de la " "comissió «%s»" +#: pack-bitmap.c #, 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" +# s'inhabilita / s'està inhabilitant? +#: pack-bitmap.c +msgid "unable to compute preferred pack, disabling pack-reuse" +msgstr "no s'ha pogut calcular el paquet preferit, s'inhabilita pack-reuse" + +#: pack-bitmap.c #, c-format msgid "object '%s' not found in type bitmaps" msgstr "no s'ha trobat l'objecte «%s» als tipus de mapes de bits" +#: pack-bitmap.c #, c-format msgid "object '%s' does not have a unique type" msgstr "l'objecte «%s» no té un tipus únic" +#: pack-bitmap.c #, c-format msgid "object '%s': real type '%s', expected: '%s'" msgstr "objecte «%s»: tipus real «%s», s'esperava: «%s»" +#: pack-bitmap.c #, c-format msgid "object not in bitmap: '%s'" msgstr "objecte no trobat al mapa de bits: «%s»" +#: pack-bitmap.c msgid "failed to load bitmap indexes" msgstr "s'ha produït un error en carregar l'índex de mapa de bits" +#: pack-bitmap.c msgid "you must specify exactly one commit to test" msgstr "heu d'especificar exactament una comissió a provar" +#: pack-bitmap.c #, c-format msgid "commit '%s' doesn't have an indexed bitmap" msgstr "la comissió «%s» no té un mapa de bits indexat" +#: pack-bitmap.c msgid "mismatch in bitmap results" msgstr "no coincideix en els resultats del mapa de bits" +#: pack-bitmap.c +#, c-format +msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)" +msgstr "l'índex de pseudo-fusions és fora de rang (%<PRIu32> >= %<PRIuMAX>)" + +#: pack-bitmap.c #, c-format msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>" msgstr "no s'ha pogut trobar «%s» al paquet «%s» al desplaçament %<PRIuMAX>" +#: pack-bitmap.c #, c-format msgid "unable to get disk usage of '%s'" msgstr "no s'ha pogut obtenir l'ús del disc de «%s»" +#: pack-bitmap.c #, c-format msgid "bitmap file '%s' has invalid checksum" msgstr "el fitxer de mapa de bits «%s» té una suma de verificació no vàlida" +#: pack-mtimes.c #, c-format msgid "mtimes file %s is too small" msgstr "el fitxer mtimes %s és massa petit" +#: pack-mtimes.c #, c-format msgid "mtimes file %s has unknown signature" msgstr "el fitxer mtimes %s té una signatura desconeguda" +#: pack-mtimes.c #, c-format msgid "mtimes file %s has unsupported version %<PRIu32>" msgstr "el fitxer mtimes %s té la versió %<PRIu32> no admesa" +#: pack-mtimes.c #, c-format msgid "mtimes file %s has unsupported hash id %<PRIu32>" msgstr "el fitxer mtimes %s té un ID de resum %<PRIu32> no admès" +#: pack-mtimes.c #, c-format msgid "mtimes file %s is corrupt" msgstr "el fitxer mtimes %s està malmès" +#: pack-revindex.c #, c-format msgid "reverse-index file %s is too small" msgstr "el fitxer d'índex invers %s és massa petit" +#: pack-revindex.c #, c-format msgid "reverse-index file %s is corrupt" msgstr "el fitxer d'índex invers %s està malmès" +#: pack-revindex.c #, c-format msgid "reverse-index file %s has unknown signature" msgstr "el fitxer d'índex invers %s té una signatura desconeguda" +#: pack-revindex.c #, c-format msgid "reverse-index file %s has unsupported version %<PRIu32>" msgstr "el fitxer d'índex invers %s té la versió %<PRIu32> no admesa" +#: pack-revindex.c #, c-format msgid "reverse-index file %s has unsupported hash id %<PRIu32>" msgstr "el fitxer d'índex invers %s té un ID de resum %<PRIu32> no admès" +#: pack-revindex.c msgid "invalid checksum" msgstr "suma de verificació no vàlida" +#: pack-revindex.c #, c-format msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" msgstr "" "posició no vàlida de l'índex de reversió a %<PRIu64>: %<PRIu32> != %<PRIu32>" +#: pack-revindex.c 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" +#: pack-revindex.c msgid "could not determine preferred pack" msgstr "no s'ha pogut determinar el paquet preferit" +#: pack-write.c msgid "cannot both write and verify reverse index" msgstr "no es pot escriure i verificar l'índex invers" +#: pack-write.c #, c-format msgid "could not stat: %s" msgstr "no s'ha pogut fer stat a: %s" +#: pack-write.c #, c-format msgid "failed to make %s readable" msgstr "s'ha produït un error en fer %s llegible" +#: pack-write.c #, c-format msgid "could not write '%s' promisor file" msgstr "no s'ha pogut escriure «%s» al fitxer «promisor»" +#: packfile.c msgid "offset before end of packfile (broken .idx?)" msgstr "desplaçament abans de la fi del fitxer de paquet (.idx trencat?)" +#: packfile.c #, c-format msgid "packfile %s cannot be mapped%s" msgstr "el fitxer de paquet %s no es pot mapar%s" +#: packfile.c #, c-format msgid "offset before start of pack index for %s (corrupt index?)" msgstr "" "desplaçament abans d'inici d'índex de paquet per a %s (índex corromput?)" +#: packfile.c #, c-format msgid "offset beyond end of pack index for %s (truncated index?)" msgstr "" "desplaçament més enllà de la fi d'índex de paquet per a %s (índex truncat?)" +#: parse-options-cb.c #, c-format msgid "malformed expiration date '%s'" msgstr "data de venciment «%s» mal formada" +#: parse-options-cb.c #, c-format msgid "option `%s' expects \"always\", \"auto\", or \"never\"" msgstr "l'opció «%s» espera «always», «auto» o «never»" +#: parse-options-cb.c #, c-format msgid "malformed object name '%s'" msgstr "nom d'objecte «%s» mal format" +#: parse-options-cb.c #, c-format msgid "option `%s' expects \"%s\" or \"%s\"" msgstr "l'opció «%s» espera «%s» o «%s»" +#: parse-options.c #, c-format msgid "%s requires a value" msgstr "%s requereix un valor" +#: parse-options.c #, c-format msgid "%s takes no value" msgstr "%s no accepta cap valor" +#: parse-options.c #, c-format msgid "%s isn't available" msgstr "%s no és disponible" +#: parse-options.c #, c-format msgid "%s expects a non-negative integer value with an optional k/m/g suffix" msgstr "%s espera un valor enter no negatiu amb un sufix opcional k/m/g" +#: parse-options.c #, c-format msgid "ambiguous option: %s (could be --%s%s or --%s%s)" msgstr "opció ambigua: %s (pot ser --%s%s o --%s%s)" +#: parse-options.c #, c-format msgid "did you mean `--%s` (with two dashes)?" msgstr "voleu dir «--%s» (amb dos guionets)?" +#: parse-options.c #, c-format msgid "alias of --%s" msgstr "àlies de --%s" +#: parse-options.c msgid "need a subcommand" msgstr "cal una subordre" +#: parse-options.c #, c-format msgid "unknown option `%s'" msgstr "opció desconeguda «%s»" +#: parse-options.c #, c-format msgid "unknown switch `%c'" msgstr "opció «%c» desconeguda" +#: parse-options.c #, c-format msgid "unknown non-ascii option in string: `%s'" msgstr "opció no ascii desconeguda en la cadena: «%s»" +#: parse-options.c msgid "..." msgstr "..." +#: parse-options.c #, c-format msgid "usage: %s" msgstr "ús: %s" @@ -18676,6 +23879,7 @@ msgstr "ús: %s" #. TRANSLATORS: the colon here should align with the #. one in "usage: %s" translation. #. +#: parse-options.c #, c-format msgid " or: %s" msgstr " o: %s" @@ -18699,83 +23903,105 @@ msgstr " o: %s" #. translated) N_() usage string, which contained embedded #. newlines before we split it up. #. +#: parse-options.c #, c-format msgid "%*s%s" msgstr "%*s%s" +#: parse-options.c #, c-format msgid " %s" msgstr " %s" +#: parse-options.c msgid "-NUM" msgstr "-NUM" +#: parse-options.c #, c-format msgid "opposite of --no-%s" msgstr "oposat a --no-%s" +#: parse-options.h msgid "expiry-date" msgstr "data-de-caducitat" +#: parse-options.h msgid "no-op (backward compatibility)" msgstr "operació nul·la (per a compatibilitat amb versions anteriors)" +#: parse-options.h msgid "be more verbose" msgstr "sigues més detallat" +#: parse-options.h msgid "be more quiet" msgstr "sigues més discret" +#: parse-options.h msgid "use <n> digits to display object names" msgstr "usa <n> xifres per a mostrar els noms d'objecte" +#: parse-options.h msgid "prefixed path to initial superproject" msgstr "camí prefixat al superprojecte inicial" +#: parse-options.h msgid "how to strip spaces and #comments from message" msgstr "com suprimir els espais i #comentaris del missatge" +#: parse-options.h msgid "read pathspec from file" msgstr "llegeix l'especificació del camí del fitxer" +#: parse-options.h msgid "" "with --pathspec-from-file, pathspec elements are separated with NUL character" msgstr "" "amb --pathspec-from-file els elements d'especificació del camí estan " "separats amb el caràcter NUL" +#: parse.c #, c-format msgid "bad boolean environment value '%s' for '%s'" msgstr "el valor «%s» booleà de l'entorn és incorrecte per a «%s»" +#: parse.c #, c-format msgid "failed to parse %s" msgstr "s'ha produït un error en analitzar %s" +#: path.c #, c-format msgid "Could not make %s writable by group" msgstr "No s'ha pogut fer %s escrivible pel grup" +#: pathspec.c msgid "Escape character '\\' not allowed as last character in attr value" msgstr "" "El caràcter d'escapament «\\» no està permès com a últim caràcter en un " "valor d'un atribut" +#: pathspec.c msgid "Only one 'attr:' specification is allowed." msgstr "Només es permet una especificació «attr:»." +#: pathspec.c msgid "attr spec must not be empty" msgstr "una especificació d'atribut no pot estar buida" +#: pathspec.c #, c-format msgid "invalid attribute name %s" msgstr "nom d'atribut no vàlid %s" +#: pathspec.c msgid "global 'glob' and 'noglob' pathspec settings are incompatible" msgstr "" "els paràmetres d'especificació de camí «glob» i «noglob» globals són " "incompatibles" +#: pathspec.c msgid "" "global 'literal' pathspec setting is incompatible with all other global " "pathspec settings" @@ -18783,138 +24009,273 @@ msgstr "" "el paràmetre d'especificació de camí «literal» global és incompatible amb " "tots els altres paràmetres d'especificació de camí globals" +#: pathspec.c msgid "invalid parameter for pathspec magic 'prefix'" msgstr "paràmetre no vàlid per a la màgia d'especificació de camí «prefix»" +#: pathspec.c #, c-format msgid "Invalid pathspec magic '%.*s' in '%s'" msgstr "Màgia d'especificació de camí no vàlida «%.*s» en «%s»" +#: pathspec.c #, c-format msgid "Missing ')' at the end of pathspec magic in '%s'" msgstr "«)» mancant al final de la màgia d'especificació de camí en «%s»" +#: pathspec.c #, c-format msgid "Unimplemented pathspec magic '%c' in '%s'" msgstr "Màgia d'especificació de camí no implementada «%c» en «%s»" +#: pathspec.c #, c-format msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: «literal» i «glob» són incompatibles" +#: pathspec.c #, c-format msgid "'%s' is outside the directory tree" msgstr "«%s» és fora de l'arbre de directoris" +#: pathspec.c #, c-format msgid "%s: '%s' is outside repository at '%s'" msgstr "%s: «%s» està fora del repositori en «%s»" +#: pathspec.c #, c-format msgid "'%s' (mnemonic: '%c')" msgstr "«%s» (mnemònic: «%c»)" +#: pathspec.c #, c-format msgid "%s: pathspec magic not supported by this command: %s" msgstr "" "%s: aquesta ordre no està admesa amb la màgia d'especificació de camí: %s" +#: pathspec.c #, c-format msgid "pathspec '%s' is beyond a symbolic link" msgstr "l'especificació de camí «%s» és més enllà d'un enllaç simbòlic" +#: pathspec.c #, c-format msgid "line is badly quoted: %s" msgstr "la línia no està ben envoltada per cometes: %s" +#: pkt-line.c msgid "unable to write flush packet" msgstr "no s'ha pogut escriure el paquet de buidatge" +#: pkt-line.c msgid "unable to write delim packet" msgstr "no s'ha pogut escriure el paquet delim" +#: pkt-line.c msgid "unable to write response end packet" msgstr "no s'ha pogut escriure el paquet de final de resposta" +#: pkt-line.c msgid "flush packet write failed" msgstr "s'ha produït un error en escriure el paquet de buidatge" +#: pkt-line.c msgid "protocol error: impossibly long line" msgstr "error de protocol: longitud de línia impossible" +#: pkt-line.c msgid "packet write with format failed" msgstr "ha fallat l'escriptura del paquet amb format" +#: pkt-line.c msgid "packet write failed - data exceeds max packet size" msgstr "" "no s'ha pogut escriure el paquet - les dades excedeixen la mida màxima del " "paquet" +#: pkt-line.c #, c-format msgid "packet write failed: %s" msgstr "no s'ha pogut escriure el paquet: %s" +#: pkt-line.c msgid "read error" msgstr "error de lectura" +#: pkt-line.c msgid "the remote end hung up unexpectedly" msgstr "el remot ha penjat inesperadament" +#: pkt-line.c #, c-format msgid "protocol error: bad line length character: %.4s" msgstr "error de protocol: caràcter de longitud de línia erroni: %.4s" +#: pkt-line.c #, c-format msgid "protocol error: bad line length %d" msgstr "error de protocol: longitud de línia errònia %d" +#: pkt-line.c sideband.c #, c-format msgid "remote error: %s" msgstr "error remot: %s" +#: preload-index.c msgid "Refreshing index" msgstr "S'està actualitzant l'índex" +#: preload-index.c #, c-format msgid "unable to create threaded lstat: %s" msgstr "no s'han pogut crear lstat amb fils %s" +#: pretty.c msgid "unable to parse --pretty format" msgstr "no s'ha pogut analitzar el format --pretty" +# lazy → tardà as in “lazy evaluation” +# 2 línies OK? +#: promisor-remote.c +msgid "lazy fetching disabled; some objects may not be available" +msgstr "" +"s'ha inhabilitat l'obtenció tardana; por ser que alguns objectes\n" +"no estiguin disponibles" + +#: promisor-remote.c msgid "promisor-remote: unable to fork off fetch subprocess" msgstr "promisor-remote: no es pot bifurcar el subprocés d'obtenció" +#: promisor-remote.c msgid "promisor-remote: could not write to fetch subprocess" msgstr "promisor-remote: no s'ha pogut escriure per al subprocés d'obtenció" +#: promisor-remote.c msgid "promisor-remote: could not close stdin to fetch subprocess" msgstr "promisor-remote: no s'ha pogut tancar stdin al subprocés d'obtenció" +#: promisor-remote.c #, c-format msgid "promisor remote name cannot begin with '/': %s" msgstr "el nom remot «promisor» no pot començar amb «/»: %s" +#: promisor-remote.c #, c-format msgid "could not fetch %s from promisor remote" msgstr "no s'ha pogut obtenir «%s» del «promisor» remot" +#: protocol-caps.c msgid "object-info: expected flush after arguments" msgstr "object-info: s'esperava una neteja després dels arguments" +#: prune-packed.c msgid "Removing duplicate objects" msgstr "S'estan eliminant els objectes duplicats" +#: pseudo-merge.c +#, c-format +msgid "failed to load pseudo-merge regex for %s: '%s'" +msgstr "" +"no s'ha pogut carregar l'expressió regular de pseudo-fusió per a %s: «%s»" + +# gerundi → futur? +# default → valor predeterminat? +#: pseudo-merge.c +#, c-format +msgid "%s must be non-negative, using default" +msgstr "%s ha de ser no negatiu, s'usarà el valor predeterminat" + +# gerundi → futur? +# default → valor predeterminat? +#: pseudo-merge.c +#, c-format +msgid "%s must be between 0 and 1, using default" +msgstr "%s ha d'estar entre 0 i 1, s'usarà el valor predeterminat" + +# gerundi → futur? +# default → valor predeterminat? +#: pseudo-merge.c +#, c-format +msgid "%s must be positive, using default" +msgstr "%s ha de ser positiu, s'usarà el valor predeterminat" + +#: pseudo-merge.c +#, c-format +msgid "pseudo-merge group '%s' missing required pattern" +msgstr "manca un patró requerit al grup de pseudo-fusió «%s»" + +#: pseudo-merge.c +#, c-format +msgid "pseudo-merge group '%s' has unstable threshold before stable one" +msgstr "" +"el grup de pseudo-fusió «%s» té un llindar inestable abans de l'estable" + +#: pseudo-merge.c +#, c-format +msgid "" +"pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)" +msgstr "" +"l'expressió regular de pseudo-fusions procedent de la configuració\n" +"té massa grups de captura (màxim=%<PRIuMAX>)" + +# lectura ampliada o pseudo-fusions ampliades? +# read → lectura / llegit? +#: pseudo-merge.c +#, c-format +msgid "extended pseudo-merge read out-of-bounds (%<PRIuMAX> >= %<PRIuMAX>)" +msgstr "" +"la lectura de pseudo-fusions ampliades és fora de rang (%<PRIuMAX> >= " +"%<PRIuMAX>)" + +#: pseudo-merge.c +#, c-format +msgid "extended pseudo-merge entry is too short (%<PRIuMAX> >= %<PRIuMAX>)" +msgstr "" +"l'entrada de pseudo-fusions ampliades és massa curta (%<PRIuMAX> >= " +"%<PRIuMAX>)" + +#: pseudo-merge.c +#, c-format +msgid "could not find pseudo-merge for commit %s at offset %<PRIuMAX>" +msgstr "" +"no s'ha pogut trobar una pseudo-fusió per a la comissió %s\n" +"a la posició %<PRIuMAX>" + +# consulta ampliada o pseudo-fusions ampliades? +#: pseudo-merge.c +#, c-format +msgid "extended pseudo-merge lookup out-of-bounds (%<PRIu32> >= %<PRIu32>)" +msgstr "" +"la consulta de pseudo-fusions ampliades és fora de rang (%<PRIu32> >= " +"%<PRIu32>)" + +# read → lectura? +#: pseudo-merge.c +#, c-format +msgid "out-of-bounds read: (%<PRIuMAX> >= %<PRIuMAX>)" +msgstr "lectura fora de rang: (%<PRIuMAX> >= %<PRIuMAX>)" + +#: pseudo-merge.c +#, c-format +msgid "could not read extended pseudo-merge table for commit %s" +msgstr "" +"no s'ha pogut llegir la taula de pseudo-fusions ampliada per a la comissió %s" + +#: range-diff.c msgid "could not start `log`" msgstr "no s'ha pogut iniciar «log»" +#: range-diff.c msgid "could not read `log` output" msgstr "no s'ha pogut llegir la sortida de «log»" +#: range-diff.c sequencer.c #, c-format msgid "could not parse commit '%s'" msgstr "no s'ha pogut analitzar la comissió «%s»" +#: range-diff.c #, c-format msgid "" "could not parse first line of `log` output: did not start with 'commit ': " @@ -18923,51 +24284,64 @@ msgstr "" "no s'ha pogut analitzar la primera línia de la sortida «log»: no començava " "amb «commit»: «%s»" +#: range-diff.c #, c-format msgid "could not parse git header '%.*s'" msgstr "no s'ha pogut llegir la capçalera de la gif «%.*s»" +#: range-diff.c msgid "failed to generate diff" msgstr "s'ha produït un error en generar el diff" +#: range-diff.c #, c-format msgid "could not parse log for '%s'" msgstr "no s'ha pogut llegir el fitxer de registre per a «%s»" +#: reachable.c #, c-format msgid "invalid extra cruft tip: '%s'" msgstr "punta extra extra no vàlida: «%s»" +#: reachable.c msgid "unable to enumerate additional recent objects" msgstr "no s'han pogut enumerar els objectes recents addicionals" +#: read-cache.c #, c-format msgid "will not add file alias '%s' ('%s' already exists in index)" msgstr "no s'afegirà l'àlies «%s»: («%s» ja existeix en l'índex)" +#: read-cache.c msgid "cannot create an empty blob in the object database" msgstr "no es pot crear un blob buit a la base de dades d'objectes" +#: read-cache.c #, c-format msgid "%s: can only add regular files, symbolic links or git-directories" msgstr "" "%s: només pot afegir fitxers normals, enllaços simbòlics o directoris git" +#: read-cache.c #, c-format msgid "unable to index file '%s'" msgstr "no es pot llegir indexar el fitxer «%s»" +#: read-cache.c #, c-format msgid "unable to add '%s' to index" msgstr "no s'ha pogut afegir «%s» a l'índex" +#: read-cache.c #, c-format msgid "'%s' appears as both a file and as a directory" msgstr "«%s» apareix com a fitxer i com a directori" +#: read-cache.c msgid "Refresh index" msgstr "Actualitza l'índex" +#: read-cache.c #, c-format msgid "" "index.version set, but the value is invalid.\n" @@ -18976,6 +24350,7 @@ msgstr "" "index.version està establerta, però el valor no és vàlid.\n" "S'està usant la versió %i" +#: read-cache.c #, c-format msgid "" "GIT_INDEX_VERSION set, but the value is invalid.\n" @@ -18984,114 +24359,143 @@ msgstr "" "GIT_INDEX_VERSION està establerta, però el valor no és vàlid.\n" "S'està usant la versió %i" +#: read-cache.c #, c-format msgid "bad signature 0x%08x" msgstr "signatura malmesa 0x%08x" +#: read-cache.c #, c-format msgid "bad index version %d" msgstr "versió d'índex incorrecta %d" +#: read-cache.c msgid "bad index file sha1 signature" msgstr "signatura sha1 malmesa al fitxer d'índex" +#: read-cache.c #, c-format msgid "index uses %.4s extension, which we do not understand" msgstr "l'índex usa l'extensió %.4s, que no es pot entendre" +#: read-cache.c #, c-format msgid "ignoring %.4s extension" msgstr "s'està ignorant l'extensió %.4s" +#: read-cache.c #, c-format msgid "unknown index entry format 0x%08x" msgstr "format d'entrada d'índex desconeguda «0x%08x»" +#: read-cache.c #, c-format msgid "malformed name field in the index, near path '%s'" msgstr "camp del nom mal formatat l'índex, camí a prop «%s»" +#: read-cache.c msgid "unordered stage entries in index" msgstr "entrades «stage» no ordenades en l'índex" +#: read-cache.c #, c-format msgid "multiple stage entries for merged file '%s'" msgstr "múltiples entrades «stage» per al fitxer fusionat «%s»" +#: read-cache.c #, c-format msgid "unordered stage entries for '%s'" msgstr "entrades «stage» no ordenades per a «%s»" +#: read-cache.c #, c-format msgid "unable to create load_cache_entries thread: %s" msgstr "no s'ha pogut crear fil «load_cache_entries»: %s" +#: read-cache.c #, c-format msgid "unable to join load_cache_entries thread: %s" msgstr "no s'ha pogut unir al fil «load_cache_entries»: %s" +#: read-cache.c #, c-format msgid "%s: index file open failed" msgstr "%s: ha fallat l'obertura del fitxer d'índex" +#: read-cache.c #, c-format msgid "%s: cannot stat the open index" msgstr "%s: no es pot fer «stat» a l'índex obert" +#: read-cache.c #, c-format msgid "%s: index file smaller than expected" msgstr "%s: fitxer d'índex més petit que s'esperava" +#: read-cache.c #, c-format msgid "%s: unable to map index file%s" msgstr "%s: no es pot mapar el fitxer d'índex%s" +#: read-cache.c #, c-format msgid "unable to create load_index_extensions thread: %s" msgstr "no s'ha pogut crear un fil «load_index_extensions»: %s" +#: read-cache.c #, c-format msgid "unable to join load_index_extensions thread: %s" msgstr "no s'ha pogut unir un fil «load_index_extensions»: %s" +#: read-cache.c #, c-format msgid "could not freshen shared index '%s'" msgstr "no s'ha pogut refrescar l'índex compartit «%s»" +#: read-cache.c #, c-format msgid "broken index, expect %s in %s, got %s" msgstr "índex malmès, s'esperava %s a %s, s'ha rebut %s" +#: read-cache.c msgid "cannot write split index for a sparse index" msgstr "no es pot escriure l'índex dividit per a un índex dispers" +#: read-cache.c msgid "failed to convert to a sparse-index" msgstr "s'ha produït un error en convertir a un índex dispers" +#: read-cache.c #, c-format msgid "unable to open git dir: %s" msgstr "no s'ha pogut obrir el directori git: %s" +#: read-cache.c #, c-format msgid "unable to unlink: %s" msgstr "no s'ha pogut desenllaçar: %s" +#: read-cache.c #, c-format msgid "cannot fix permission bits on '%s'" msgstr "no s'han pogut corregir els bits de permisos en «%s»" +#: read-cache.c #, c-format msgid "%s: cannot drop to stage #0" msgstr "%s: no es pot baixar fins al «stage» #0" +#: read-cache.c #, c-format msgid "unexpected diff status %c" msgstr "estat de diff inesperat %c" +#: read-cache.c #, c-format msgid "remove '%s'\n" msgstr "elimina «%s»\n" +#: rebase-interactive.c msgid "" "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --" "continue'.\n" @@ -19101,6 +24505,7 @@ msgstr "" "continue».\n" "O bé, podeu avortar el «rebase» amb «git rebase --abort».\n" +#: rebase-interactive.c #, c-format msgid "" "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring." @@ -19108,6 +24513,7 @@ msgstr "" "no s'ha reconegut el paràmetre %s per rebase.missingCommitsCheck. S'està " "ignorant." +#: rebase-interactive.c msgid "" "\n" "Commands:\n" @@ -19160,20 +24566,22 @@ msgstr "" " (o línia única, si no hi ha cap comissió de fusió original " "especificada).\n" " Useu -c <comissió> per a reescriure el missatge de la comissió.\n" -"u, update-ref <ref> = segueix un marcador de posició per a actualitzar " -"<ref>\n" +"u, update-ref <referència> = segueix un marcador de posició per a " +"actualitzar <ref>\n" " a aquesta posició en les comissions noves. La <ref> " "s'actualitza\n" " al final del «rebase»\n" "\n" "Es pot canviar l'ordre d'aquestes línies; s'executen de dalt a baix.\n" +#: rebase-interactive.c #, c-format msgid "Rebase %s onto %s (%d command)" msgid_plural "Rebase %s onto %s (%d commands)" msgstr[0] "Fes «rebase» de %s a %s (%d ordre)" msgstr[1] "Fes «rebase» de %s a %s (%d ordres)" +#: rebase-interactive.c msgid "" "\n" "Do not remove any line. Use 'drop' explicitly to remove a commit.\n" @@ -19182,6 +24590,7 @@ msgstr "" "No elimineu cap línia. Useu «drop» explícitament per a eliminar una " "comissió.\n" +#: rebase-interactive.c msgid "" "\n" "If you remove a line here THAT COMMIT WILL BE LOST.\n" @@ -19189,6 +24598,7 @@ msgstr "" "\n" "Si elimineu una línia aquí, ES PERDRÀ AQUELLA COMISSIÓ.\n" +#: rebase-interactive.c msgid "" "\n" "You are editing the todo file of an ongoing interactive rebase.\n" @@ -19202,19 +24612,22 @@ msgstr "" " git rebase --continue\n" "\n" +#: rebase-interactive.c msgid "" "\n" "However, if you remove everything, the rebase will be aborted.\n" "\n" msgstr "" "\n" -"No obstant això, si elimineu tot, s'avortarà el «rebase».\n" +"No obstant això, si ho elimineu tot, s'avortarà el «rebase».\n" "\n" +#: rebase-interactive.c #, c-format msgid "could not write '%s'." msgstr "no s'ha pogut escriure a «%s»." +#: rebase-interactive.c #, c-format msgid "" "Warning: some commits may have been dropped accidentally.\n" @@ -19224,6 +24637,7 @@ msgstr "" "accidentalment.\n" "Les comissions descartades (més nova a més vella):\n" +#: rebase-interactive.c #, c-format msgid "" "To avoid this message, use \"drop\" to explicitly remove a commit.\n" @@ -19240,113 +24654,146 @@ msgstr "" "d'advertències.\n" "Els comportaments possibles són: ignore, warn, error.\n" +#: rebase.c #, c-format msgid "%s: 'preserve' superseded by 'merges'" msgstr "%s: «conserva» substituït per «fusiona»" +#: ref-filter.c wt-status.c msgid "gone" msgstr "no hi és" +#: ref-filter.c #, c-format msgid "ahead %d" msgstr "davant per %d" +#: ref-filter.c #, c-format msgid "behind %d" msgstr "darrere per %d" +#: ref-filter.c #, c-format msgid "ahead %d, behind %d" msgstr "davant per %d, darrere per %d" +#: ref-filter.c #, c-format msgid "%%(%.*s) does not take arguments" msgstr "%%(%.*s) no accepta arguments" +#: ref-filter.c #, c-format msgid "unrecognized %%(%.*s) argument: %s" msgstr "argument %%(%.*s) desconegut: %s" +#: ref-filter.c #, c-format msgid "expected format: %%(color:<color>)" msgstr "format esperat: %%(color:<color>)" +#: ref-filter.c #, c-format msgid "unrecognized color: %%(color:%s)" msgstr "color no reconegut: %%(color:%s)" +#: ref-filter.c #, c-format msgid "Integer value expected refname:lstrip=%s" msgstr "Valor enter esperat pel nom de referència:lstrip=%s" +#: ref-filter.c #, c-format msgid "Integer value expected refname:rstrip=%s" msgstr "Valor enter esperat pel nom de referència:rstrip=%s" +#: ref-filter.c #, c-format msgid "expected %%(trailers:key=<value>)" -msgstr "s'esperava %%(trailers:key=<value>)" +msgstr "s'esperava %%(trailers:key=<valor>)" +#: ref-filter.c #, c-format msgid "unknown %%(trailers) argument: %s" msgstr "argument %%(trailers) desconegut: %s" +#: ref-filter.c #, c-format msgid "positive value expected contents:lines=%s" msgstr "valor positiu esperat conté:lines=%s" +#: ref-filter.c #, c-format msgid "argument expected for %s" msgstr "s'esperava un argument per a %s" +#: ref-filter.c #, c-format msgid "positive value expected %s=%s" msgstr "valor positiu esperat %s=%s" +#: ref-filter.c #, c-format msgid "cannot fully parse %s=%s" msgstr "no es pot analitzar completament %s=%s" +#: ref-filter.c #, c-format msgid "value expected %s=" msgstr "s'esperava un valor %s=" +#: ref-filter.c #, c-format msgid "positive value expected '%s' in %%(%s)" msgstr "valor positiu esperat «%s» a %%(%s)" +#: ref-filter.c #, c-format msgid "expected format: %%(align:<width>,<position>)" msgstr "format esperat: %%(align:<amplada>,<posició>)" +#: ref-filter.c #, c-format msgid "unrecognized position:%s" msgstr "posició no reconeguda:%s" +#: ref-filter.c #, c-format msgid "unrecognized width:%s" msgstr "amplada no reconeguda:%s" +#: ref-filter.c #, c-format msgid "unrecognized %%(%s) argument: %s" msgstr "argument %%(%s) desconegut: %s" +#: ref-filter.c #, c-format msgid "positive width expected with the %%(align) atom" msgstr "amplada positiva esperada amb l'àtom %%(align)" +#: ref-filter.c #, c-format msgid "expected format: %%(ahead-behind:<committish>)" msgstr "format esperat: %%(ahead-behind:<committish>)" +#: ref-filter.c +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "format esperat: %%(is-base:<committish>)" + +#: ref-filter.c #, c-format msgid "malformed field name: %.*s" msgstr "nom de camp mal format: %.*s" +#: ref-filter.c #, c-format msgid "unknown field name: %.*s" msgstr "nom de camp desconegut: %.*s" +#: ref-filter.c #, c-format msgid "" "not a git repository, but the field '%.*s' requires access to object data" @@ -19354,117 +24801,147 @@ msgstr "" "no és un repositori git, però el camp «%.*s» requereix accés a les dades de " "l'objecte" +#: ref-filter.c #, c-format msgid "format: %%(%s) atom used without a %%(%s) atom" msgstr "format: l'àtom %%(%s) usat sense un àtom %%(%s)" +#: ref-filter.c #, c-format msgid "format: %%(then) atom used more than once" msgstr "format: s'ha usat l'àtom %%(then) més d'un cop" +#: ref-filter.c #, c-format msgid "format: %%(then) atom used after %%(else)" msgstr "format: s'ha usat l'àtom %%(then) després de %%(else)" +#: ref-filter.c #, c-format msgid "format: %%(else) atom used more than once" msgstr "format: s'ha usat l'àtom %%(else) més d'un cop" +#: ref-filter.c #, c-format msgid "format: %%(end) atom used without corresponding atom" msgstr "format: s'ha usat l'àtom %%(end) sense l'àtom corresponent" +#: ref-filter.c #, c-format msgid "malformed format string %s" msgstr "cadena de format mal format %s" +#: ref-filter.c #, c-format msgid "this command reject atom %%(%.*s)" msgstr "aquesta ordre rebutja l'àtom %%(%.*s)" +#: ref-filter.c #, c-format msgid "--format=%.*s cannot be used with --python, --shell, --tcl" msgstr "no es pot usar --format=%.*s amb --python, --shell, --tcl" +#: ref-filter.c msgid "failed to run 'describe'" msgstr "no s'ha pogut executar «describe»" +#: ref-filter.c #, c-format msgid "(no branch, rebasing %s)" msgstr "(sense branca, s'està fent «rebase» %s)" +#: ref-filter.c #, c-format msgid "(no branch, rebasing detached HEAD %s)" msgstr "(sense branca, s'està fent «rebase» d'un «HEAD» separat %s)" +#: ref-filter.c #, c-format msgid "(no branch, bisect started on %s)" msgstr "(sense branca, bisecció començada en %s)" +#: ref-filter.c #, c-format msgid "(HEAD detached at %s)" msgstr "(HEAD separat a %s)" +#: ref-filter.c #, c-format msgid "(HEAD detached from %s)" msgstr "(HEAD separat des de %s)" +#: ref-filter.c msgid "(no branch)" msgstr "(sense branca)" +#: ref-filter.c #, c-format msgid "missing object %s for %s" msgstr "manca l'objecte %s per a %s" +#: ref-filter.c #, c-format msgid "parse_object_buffer failed on %s for %s" msgstr "parse_object_buffer ha fallat en %s per a %s" +#: ref-filter.c #, c-format msgid "malformed object at '%s'" msgstr "objecte mal format a «%s»" +#: ref-filter.c #, c-format msgid "ignoring ref with broken name %s" msgstr "s'està ignorant la referència amb nom malmès %s" +#: ref-filter.c refs.c #, c-format msgid "ignoring broken ref %s" msgstr "s'està ignorant la referència malmesa %s" +#: ref-filter.c #, c-format msgid "format: %%(end) atom missing" msgstr "format: manca l'àtom %%(end)" +#: ref-filter.c #, c-format msgid "malformed object name %s" msgstr "nom d'objecte %s mal format" +#: ref-filter.c #, c-format msgid "option `%s' must point to a commit" msgstr "l'opció «%s» ha d'apuntar a una comissió" +#: ref-filter.h msgid "key" msgstr "clau" +#: ref-filter.h msgid "field name to sort on" msgstr "nom del camp en el qual ordenar" +#: ref-filter.h msgid "exclude refs which match pattern" msgstr "exclou refs que coincideixin amb el patró" +#: reflog.c #, c-format msgid "not a reflog: %s" -msgstr "no és un registre de referència: %s" +msgstr "no és un registre de referències: %s" +#: reflog.c #, c-format msgid "no reflog for '%s'" -msgstr "cap registre de referència per a «%s»" +msgstr "cap registre de referències per a «%s»" +#: refs.c #, c-format msgid "%s does not point to a valid object!" msgstr "%s no apunta a un objecte vàlid" +#: refs.c #, c-format msgid "" "Using '%s' as the name for the initial branch. This default branch name\n" @@ -19492,231 +24969,438 @@ msgstr "" "\n" "\tgit branch -m <nom>\n" +#: refs.c #, c-format msgid "could not retrieve `%s`" msgstr "no s'ha pogut recuperar «%s»" +#: refs.c #, c-format msgid "invalid branch name: %s = %s" msgstr "nom de branca no vàlida: %s = %s" +#: refs.c #, c-format msgid "ignoring dangling symref %s" -msgstr "s'està ignorant symref penjant %s" +msgstr "s'està ignorant referència simbòlica despenjada %s" +#: refs.c #, c-format msgid "log for ref %s has gap after %s" msgstr "registre per a ref %s té un buit després de %s" +#: refs.c #, c-format msgid "log for ref %s unexpectedly ended on %s" msgstr "registre per als ref %s ha acabat inesperadament a %s" +#: refs.c #, c-format msgid "log for %s is empty" msgstr "el registre per a %s és buit" +#: refs.c +msgid "refusing to force and skip creation of reflog" +msgstr "" +"s'ha rebutjat l'acció forçada i l'omissió de crear un registre de referències" + +#: refs.c #, c-format msgid "refusing to update ref with bad name '%s'" msgstr "s'està refusant la referència amb nom malmès «%s»" +#: refs.c +#, c-format +msgid "refusing to update pseudoref '%s'" +msgstr "s'ha rebutjat l'actualització de la pseudoreferència «%s»" + +#: refs.c #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "ha fallat update_ref per a la ref «%s»: %s" +#: refs.c #, c-format msgid "multiple updates for ref '%s' not allowed" msgstr "no es permeten múltiples actualitzacions per a la referència «%s»" +#: refs.c msgid "ref updates forbidden inside quarantine environment" msgstr "no està permès actualitzar les referències en un entorn de quarantena" +#: refs.c msgid "ref updates aborted by hook" msgstr "les actualitzacions de referències s'han avortat per un lligam" +#: refs.c #, c-format msgid "'%s' exists; cannot create '%s'" msgstr "«%s» existeix; no es pot crear «%s»" +#: refs.c #, c-format msgid "cannot process '%s' and '%s' at the same time" msgstr "no es poden processar «%s» i «%s» a la vegada" +#: refs.c #, c-format msgid "could not delete reference %s: %s" msgstr "no s'ha pogut suprimir la referència %s: %s" +#: refs.c #, c-format msgid "could not delete references: %s" msgstr "no s'han pogut suprimir les referències: %s" +# 2 línies OK? +#: refs.c +#, c-format +msgid "Finished dry-run migration of refs, the result can be found at '%s'\n" +msgstr "" +"S'ha acabat la prova no destructiva de migració de referències;\n" +"el resultat es pot trobar a «%s»\n" + +# migració OK? +#: refs.c +#, c-format +msgid "could not remove temporary migration directory '%s'" +msgstr "no s'ha pogut eliminar el directori temporal de migració «%s»" + +# migrar OK? +#: refs.c +#, c-format +msgid "migrated refs can be found at '%s'" +msgstr "les referències migrades es poden trobar en «%s»" + +#: refs/files-backend.c refs/reftable-backend.c +#, c-format +msgid "" +"cannot lock ref '%s': expected symref with target '%s': but is a regular ref" +msgstr "" +"no puc bloquejar la referència«%s»: s'esperava una referència\n" +"simbòlica amb destinació «%s» però és una referència regular" + +#: refs/files-backend.c +#, c-format +msgid "cannot open directory %s" +msgstr "no es pot obrir el directori «%s»" + +#: refs/files-backend.c +msgid "Checking references consistency" +msgstr "S'està comprovant la consistència de les referències" + +#: refs/reftable-backend.c +#, c-format +msgid "refname is dangerous: %s" +msgstr "el nom de referència és perillós: %s" + +#: refs/reftable-backend.c +#, c-format +msgid "trying to write ref '%s' with nonexistent object %s" +msgstr "" +"s'està intentant escriure la referència «%s» amb l'objecte que no existeix %s" + +#: refs/reftable-backend.c +#, c-format +msgid "trying to write non-commit object %s to branch '%s'" +msgstr "" +"s'està intentant escriure un objecte no de comissió %s en la branca «%s»" + +#: refs/reftable-backend.c +#, c-format +msgid "" +"multiple updates for 'HEAD' (including one via its referent '%s') are not " +"allowed" +msgstr "" +"no es permeten actualitzacions múltiples de «HEAD» (inclosa una feta a " +"través del\n" +"seu referent «%s»)" + +# bloquejar → blocar +#: refs/reftable-backend.c +#, c-format +msgid "cannot lock ref '%s': unable to resolve reference '%s'" +msgstr "" +"no es pot bloquejar la referència «%s»: no s'ha pogut resoldre la referència " +"«%s»" + +#: refs/reftable-backend.c +#, c-format +msgid "cannot lock ref '%s': error reading reference" +msgstr "no es pot bloquejar la referència «%s»: error en llegir la referència" + +#: refs/reftable-backend.c +#, c-format +msgid "" +"multiple updates for '%s' (including one via symref '%s') are not allowed" +msgstr "" +"no es permeten les actualitzacions múltiples per a «%s» (inclosa una a\n" +"través de la referència simbòlica «%s»" + +# bloquejar→blocar? +#: refs/reftable-backend.c +#, c-format +msgid "cannot lock ref '%s': reference already exists" +msgstr "no puc bloquejar la referència «%s»: la referència ja existeix" + +# massa llarg? +#: refs/reftable-backend.c +#, c-format +msgid "cannot lock ref '%s': reference is missing but expected %s" +msgstr "" +"no puc bloquejar la referència «%s»: manca la referència però s'esperava %s" + +# blocar→bloquejar? +#: refs/reftable-backend.c +#, c-format +msgid "cannot lock ref '%s': is at %s but expected %s" +msgstr "no puc bloquejar la referència «%s»: és en %s però s'esperava %s" + +#: refs/reftable-backend.c +#, c-format +msgid "reftable: transaction prepare: %s" +msgstr "taula de referències: prepara transacció: %s" + +#: refs/reftable-backend.c +#, c-format +msgid "reftable: transaction failure: %s" +msgstr "taula de referències: fallada de transacció: %s" + +# stack→pila OK? +#: refs/reftable-backend.c +#, c-format +msgid "unable to compact stack: %s" +msgstr "no es pot compactar la pila: %s" + +#: refs/reftable-backend.c +#, c-format +msgid "refname %s not found" +msgstr "no s'ha trobat el nom de referència %s" + +#: refs/reftable-backend.c +#, c-format +msgid "refname %s is a symbolic ref, copying it is not supported" +msgstr "" +"el nom de referència %s és una referència simbòlica: no es permet copiar" + +#: refspec.c #, c-format msgid "invalid refspec '%s'" msgstr "refspec no vàlida: «%s»" +#: remote-curl.c #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "citació no vàlida en el valor de l'opció de pujada: «%s»" +# object-format no traduït perquè és part de --show-object-format +#: remote-curl.c +#, c-format +msgid "unknown value for object-format: %s" +msgstr "valor desconegut per a l'object-format: %s" + +#: remote-curl.c #, c-format msgid "%sinfo/refs not valid: is this a git repository?" msgstr "%sinfo/refs no vàlides: és un repositori git?" +#: remote-curl.c msgid "invalid server response; expected service, got flush packet" msgstr "" "resposta del servidor no és vàlida; el servei esperat, ha rebut in paquet de " "neteja" +#: remote-curl.c #, c-format msgid "invalid server response; got '%s'" msgstr "resposta del servidor no vàlida; s'ha obtingut «%s»" +#: remote-curl.c #, c-format msgid "repository '%s' not found" msgstr "no s'ha trobat el repositori «%s»" +#: remote-curl.c #, c-format msgid "Authentication failed for '%s'" msgstr "S'ha produït un error en autenticar per «%s»" +#: remote-curl.c #, c-format msgid "unable to access '%s' with http.pinnedPubkey configuration: %s" msgstr "no es pot accedir a «%s» la configuració de http.pinnedPubkey :%s" +#: remote-curl.c #, c-format msgid "unable to access '%s': %s" msgstr "no s'ha pogut accedir a «%s»: %s" +#: remote-curl.c #, c-format msgid "redirecting to %s" msgstr "s'està redirigint a %s" +#: remote-curl.c msgid "shouldn't have EOF when not gentle on EOF" msgstr "no hauria de tenir EOF quan s'és lax amb els EOF" +#: remote-curl.c msgid "remote server sent unexpected response end packet" msgstr "el servidor remot ha enviat un paquet de final de resposta inesperat" +#: remote-curl.c msgid "unable to rewind rpc post data - try increasing http.postBuffer" msgstr "" "no s'han pogut rebobinar les dades de publicació rpc - proveu d'augmentar " "http.postBuffer" +#: remote-curl.c #, c-format msgid "remote-curl: bad line length character: %.4s" msgstr "remote-curl: caràcter de longitud de línia erroni: %.4s" +#: remote-curl.c msgid "remote-curl: unexpected response end packet" msgstr "remote-curl: paquet final de resposta inesperat" +#: remote-curl.c #, c-format msgid "RPC failed; %s" msgstr "RPC ha fallat; %s" +#: remote-curl.c msgid "cannot handle pushes this big" msgstr "no es pot gestionar pujades tan grans" +#: remote-curl.c #, c-format msgid "cannot deflate request; zlib deflate error %d" msgstr "no es pot descomprimir la sol·licitud; error de deflate zlib %d" +#: remote-curl.c #, c-format msgid "cannot deflate request; zlib end error %d" msgstr "" "no es pot descomprimir la sol·licitud; error de finalització de zlib %d" +#: remote-curl.c #, c-format msgid "%d bytes of length header were received" -msgstr "s'han rebut %d bytes de longitud de capçalera" +msgstr "s'han rebut %d octets de longitud de capçalera" +#: remote-curl.c #, c-format msgid "%d bytes of body are still expected" -msgstr "encara s'esperen %d bytes del cos" +msgstr "encara s'esperen %d octets del cos" +#: remote-curl.c msgid "dumb http transport does not support shallow capabilities" msgstr "el transport ximple http no admet capacitats superficials" +#: remote-curl.c msgid "fetch failed." msgstr "l'obtenció ha fallat." +#: remote-curl.c msgid "cannot fetch by sha1 over smart http" msgstr "no s'ha pogut obtenir per sha1 a través de l'http intel·ligent" +#: remote-curl.c #, c-format msgid "protocol error: expected sha/ref, got '%s'" msgstr "error de protocol: s'esperava sha/ref, s'ha obtingut «%s»" +#: remote-curl.c #, c-format msgid "http transport does not support %s" msgstr "El transport http no admet %s" +#: remote-curl.c msgid "protocol error: expected '<url> <path>', missing space" msgstr "" "s'ha produït un error de protocol: s'esperava «<url> <camí>», falta espai" +#: remote-curl.c #, c-format msgid "failed to download file at URL '%s'" msgstr "no s'ha pogut baixar el fitxer a l'URL «%s»" +#: remote-curl.c msgid "git-http-push failed" msgstr "git-http-push ha fallat" +#: remote-curl.c msgid "remote-curl: usage: git remote-curl <remote> [<url>]" -msgstr "remote-curl: ús: git remote-curl <remote> [<url>]" +msgstr "remote-curl: ús: git remote-curl <remot> [<url>]" +#: remote-curl.c msgid "remote-curl: error reading command stream from git" msgstr "remote-curl: error en llegir el flux d'ordres del git" +#: remote-curl.c msgid "remote-curl: fetch attempted without a local repo" msgstr "remote-curl: s'ha intentat l'obtenció sense un repositori local" +#: remote-curl.c #, c-format msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: ordre «%s» desconeguda del git" +#: remote.c #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "" "l'abreviatura del fitxer de configuració remot no pot començar amb «/»: %s" +#: remote.c msgid "more than one receivepack given, using the first" msgstr "més d'un paquet de recepció donat, usant el primer" +#: remote.c msgid "more than one uploadpack given, using the first" msgstr "més d'un paquet de càrrega donat, usant el primer" +#: remote.c #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "valor no conegut per a transfer.credentialsInUrl: «%s»" +#: remote.c #, c-format msgid "URL '%s' uses plaintext credentials" msgstr "L'URL «%s» utilitza credencials en text pla" +#: remote.c #, c-format msgid "Cannot fetch both %s and %s to %s" msgstr "No es poden obtenir ambdós %s i %s a %s" +#: remote.c #, c-format msgid "%s usually tracks %s, not %s" msgstr "%s generalment segueix %s, no %s" +#: remote.c #, c-format msgid "%s tracks both %s and %s" msgstr "%s segueix ambdós %s i %s" +#: remote.c #, c-format msgid "key '%s' of pattern had no '*'" msgstr "la clau «%s» del patró no té «*»" +#: remote.c #, c-format msgid "value '%s' of pattern has no '*'" msgstr "el valor «%s» del patró no té «*»" +#: remote.c #, c-format msgid "src refspec %s does not match any" msgstr "l'especificació de referència font %s no coincideix amb cap referència" +#: remote.c #, c-format msgid "src refspec %s matches more than one" msgstr "" @@ -19726,6 +25410,7 @@ msgstr "" #. <remote> <src>:<dst>" push, and "being pushed ('%s')" is #. the <src>. #. +#: remote.c #, c-format msgid "" "The destination you provided is not a full refname (i.e.,\n" @@ -19748,6 +25433,7 @@ msgstr "" "\n" "Res d'això ha funcionat. Cal que proporcioneu una referència completa." +#: remote.c #, c-format msgid "" "The <src> part of the refspec is a commit object.\n" @@ -19759,6 +25445,7 @@ msgstr "" "Voleu crear una branca nova empenyent a\n" "«%s:refs/heads/%s»?" +#: remote.c #, c-format msgid "" "The <src> part of the refspec is a tag object.\n" @@ -19768,6 +25455,7 @@ msgstr "" "La part <src> de l'especificació de la referència és un objecte d'etiqueta.\n" "Voleu crear una etiqueta pujant-la a «%s:refs/tags/%s»?" +#: remote.c #, c-format msgid "" "The <src> part of the refspec is a tree object.\n" @@ -19777,6 +25465,7 @@ msgstr "" "La part <src> de l'especificació de la referència és un objecte d'arbre.\n" "Voleu crear una etiqueta pujant-la a «%s:refs/tags/%s»?" +#: remote.c #, c-format msgid "" "The <src> part of the refspec is a blob object.\n" @@ -19787,93 +25476,116 @@ msgstr "" "Voleu posar una etiqueta al blob nou mitjançant la pujada a\n" "?«%s:refs/tags/%s»?" +#: remote.c #, c-format msgid "%s cannot be resolved to branch" msgstr "«%s» no es pot resoldre a una branca" +#: remote.c #, c-format msgid "unable to delete '%s': remote ref does not exist" msgstr "no s'ha pogut suprimir «%s»: la referència remota no existeix" +#: remote.c #, c-format msgid "dst refspec %s matches more than one" msgstr "" "l'especificació de la referència dst %s coincideixen amb més d'una referència" +#: remote.c #, c-format msgid "dst ref %s receives from more than one src" msgstr "l'especificació de la referència dst %s rep més d'una referència src" +#: remote.c msgid "HEAD does not point to a branch" msgstr "HEAD no assenyala cap branca" +#: remote.c #, c-format msgid "no such branch: '%s'" msgstr "no existeix la branca: «%s»" +#: remote.c #, c-format msgid "no upstream configured for branch '%s'" msgstr "cap font configurada per a la branca «%s»" +#: remote.c #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" msgstr "la branca font «%s» no s'emmagatzema com a branca amb seguiment remot" +#: remote.c #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" msgstr "" "el destí de pujada «%s» en el remot «%s» no té cap branca amb seguiment remot" +#: remote.c #, c-format msgid "branch '%s' has no remote for pushing" msgstr "la branca «%s» no té cap remot al qual pujar" +#: remote.c #, c-format msgid "push refspecs for '%s' do not include '%s'" msgstr "les especificacions de referència de pujada «%s» no inclouen «%s»" +#: remote.c msgid "push has no destination (push.default is 'nothing')" msgstr "push no té destí (push.default és «nothing»)" +#: remote.c msgid "cannot resolve 'simple' push to a single destination" msgstr "no es pot resoldre una pujada «simple» a un sol destí" +#: remote.c #, c-format msgid "couldn't find remote ref %s" msgstr "no s'ha pogut trobar la referència remota %s" +#: remote.c #, c-format msgid "* Ignoring funny ref '%s' locally" msgstr "* S'estan ignorant les referències «%s» localment" +#: remote.c #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" msgstr "La vostra branca està basada en «%s», però la font no hi és.\n" +#: remote.c msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr " (useu «git branch --unset-upstream» per a arreglar-ho)\n" +#: remote.c #, c-format msgid "Your branch is up to date with '%s'.\n" msgstr "La vostra branca està al dia amb «%s».\n" +#: remote.c #, c-format msgid "Your branch and '%s' refer to different commits.\n" -msgstr "La vostra branca i «%s» es refereixen a diferents comissions.\n" +msgstr "La vostra branca i «%s» es refereixen a comissions.\n" +#: remote.c #, c-format msgid " (use \"%s\" for details)\n" msgstr " (useu «%s» per a detalls)\n" +#: remote.c #, 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] "La vostra branca està %2$d comissió per davant de «%1$s».\n" msgstr[1] "La vostra branca està %2$d comissions per davant de «%1$s».\n" +#: remote.c msgid " (use \"git push\" to publish your local commits)\n" msgstr " (useu «git push» per a publicar les vostres comissions locals)\n" +#: remote.c #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -19885,9 +25597,11 @@ msgstr[1] "" "La vostra branca està %2$d comissions per darrere de «%1$s», i pot avançar-" "se ràpidament.\n" +#: remote.c msgid " (use \"git pull\" to update your local branch)\n" msgstr " (useu «git pull» per a actualitzar la vostra branca local)\n" +#: remote.c #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -19902,285 +25616,387 @@ msgstr[1] "" "La vostra branca i «%s» han divergit,\n" "i tenen %d i %d comissions distintes cada una, respectivament.\n" +#: remote.c msgid "" " (use \"git pull\" if you want to integrate the remote branch with yours)\n" msgstr "" " (utilitzeu «git pull» si voleu integrar la branca remota amb la vostra)\n" +#: remote.c #, c-format msgid "cannot parse expected object name '%s'" msgstr "no es pot analitzar el nom de l'objecte esperat «%s»" +#: remote.c #, c-format msgid "cannot strip one component off url '%s'" msgstr "no es pot despullar un component de l'url «%s»" +#: replace-object.c #, c-format msgid "bad replace ref name: %s" msgstr "nom de la referència reemplaçada incorrecte: %s" +#: replace-object.c #, c-format msgid "duplicate replace ref: %s" msgstr "duplica les referències reemplaçades: %s" +#: replace-object.c #, c-format msgid "replace depth too high for object %s" msgstr "la profunditat de reemplaçament és massa alta per l'objecte %s" +#: rerere.c msgid "corrupt MERGE_RR" msgstr "MERGE_RR corrupte" +#: rerere.c msgid "unable to write rerere record" msgstr "no s'ha pogut escriure el registre «rerere»" +#: rerere.c #, c-format msgid "there were errors while writing '%s' (%s)" msgstr "s'han produït errors en escriure «%s» (%s)" +#: rerere.c #, c-format msgid "could not parse conflict hunks in '%s'" msgstr "no s'han pogut analitzar els pedaços en conflicte a «%s»" +#: rerere.c #, c-format msgid "failed utime() on '%s'" msgstr "s'ha produït un error en fer «failed utime()» a «%s»" +#: rerere.c #, c-format msgid "writing '%s' failed" msgstr "s'ha produït un error en escriure «%s»" +#: rerere.c #, c-format msgid "Staged '%s' using previous resolution." msgstr "«Staged» «%s» utilitzant una resolució anterior." +#: rerere.c #, c-format msgid "Recorded resolution for '%s'." msgstr "Es recorda la resolució per a «%s»." +#: rerere.c #, c-format msgid "Resolved '%s' using previous resolution." msgstr "S'ha resolt «%s» usant una resolució anterior." +#: rerere.c #, c-format msgid "cannot unlink stray '%s'" msgstr "no es pot desenllaçar «%s» (extraviat)" +#: rerere.c #, c-format msgid "Recorded preimage for '%s'" msgstr "Imatge prèvia registrada per a «%s»" +#: rerere.c #, c-format msgid "failed to update conflicted state in '%s'" msgstr "ha fallat en actualitzar l'estat en conflicte a «%s»" +#: rerere.c #, c-format msgid "no remembered resolution for '%s'" msgstr "no hi ha cap resolució recordada per a «%s»" +#: rerere.c #, c-format msgid "Updated preimage for '%s'" msgstr "Imatge prèvia actualitzada per a «%s»" +#: rerere.c #, c-format msgid "Forgot resolution for '%s'\n" msgstr "S'ha oblidat la resolució per a «%s»\n" +#: rerere.c msgid "unable to open rr-cache directory" msgstr "no s'ha pogut obrir el directori rr-cache" +#: rerere.h msgid "update the index with reused conflict resolution if possible" msgstr "" "actualitza l'índex amb la resolució de conflictes reusada si és possible" +#: reset.c msgid "could not determine HEAD revision" msgstr "no s'ha pogut determinar la revisió de HEAD" +#: reset.c sequencer.c #, c-format msgid "failed to find tree of %s" msgstr "s'ha produït un error en cercar l'arbre de %s" +#: revision.c #, c-format msgid "unsupported section for hidden refs: %s" msgstr "secció d'índex no compatible per a les referències ocultes: %s" +#: revision.c msgid "--exclude-hidden= passed more than once" msgstr "--exclude-hidden= passat més d'una vegada" +#: revision.c #, c-format msgid "resolve-undo records `%s` which is missing" msgstr "resolve-undo indica «%s» que manquen" +#: revision.c #, c-format -msgid "could not get commit for ancestry-path argument %s" -msgstr "no s'ha pogut obtenir la comissió per a l'argument d'ancestry-path %s" +msgid "%s exists but is a symbolic ref" +msgstr "%s existeix però és una referència simbòlica" + +#: revision.c +msgid "" +"--merge requires one of the pseudorefs MERGE_HEAD, CHERRY_PICK_HEAD, " +"REVERT_HEAD or REBASE_HEAD" +msgstr "" +"--merge requereix una de les pseudoreferències MERGE_HEAD, CHERRY_PICK_HEAD, " +"REVERT_HEAD o REBASE_HEAD" +#: revision.c +#, c-format +msgid "could not get commit for --ancestry-path argument %s" +msgstr "" +"no s'ha pogut obtenir una comissió per a l'argument %s d'--ancestry-path" + +#: revision.c msgid "--unpacked=<packfile> no longer supported" msgstr "--unpacked=<packfile> ja no s'admet" +#: revision.c #, c-format msgid "invalid option '%s' in --stdin mode" msgstr "opció no vàlida: «%s» en mode --stdin" +#: revision.c msgid "your current branch appears to be broken" msgstr "la vostra branca actual sembla malmesa" +#: revision.c #, c-format msgid "your current branch '%s' does not have any commits yet" msgstr "la branca actual «%s» encara no té cap comissió" +#: revision.c msgid "object filtering requires --objects" msgstr "el filtratge d'objectes requereix --objects" +#: revision.c msgid "-L does not yet support diff formats besides -p and -s" msgstr "-L no és encara compatible amb formats que no siguin «-p» o «-s»" +#: run-command.c #, c-format msgid "cannot create async thread: %s" msgstr "no s'ha pogut crear fil «async»: %s" +#: scalar.c worktree.c #, c-format msgid "'%s' does not exist" msgstr "«%s» no existeix" +#: scalar.c #, c-format msgid "could not switch to '%s'" msgstr "no s'ha pogut commutar a «%s»" +#: scalar.c msgid "need a working directory" msgstr "cal un directori de treball" +#: scalar.c msgid "Scalar enlistments require a worktree" msgstr "Els allistaments escalars requereixen un arbre de treball" +#: scalar.c #, c-format msgid "could not configure %s=%s" msgstr "no s'ha pogut configurar %s=%s" +#: scalar.c msgid "could not configure log.excludeDecoration" msgstr "no s'ha pogut configurar log.excludeDecoration" +#: scalar.c msgid "could not add enlistment" msgstr "no s'ha afegit a l'allistament" +#: scalar.c msgid "could not set recommended config" msgstr "no s'ha pogut establir la configuració recomanada" +#: scalar.c msgid "could not turn on maintenance" msgstr "no s'ha pogut activar el manteniment" +#: scalar.c msgid "could not start the FSMonitor daemon" msgstr "no s'ha pogut iniciar el dimoni del fsmonitor" +#: scalar.c msgid "could not turn off maintenance" msgstr "no s'ha pogut desactivar el manteniment" +#: scalar.c msgid "could not remove enlistment" msgstr "no s'ha pogut eliminar l'allistament" +#: scalar.c #, c-format msgid "remote HEAD is not a branch: '%.*s'" msgstr "la HEAD remota no és una branca: «%.*s»" +#: scalar.c msgid "failed to get default branch name from remote; using local default" msgstr "" "no s'ha pogut obtenir el nom de la branca per defecte del remot; s'usa ela " "predeterminada localment" +#: scalar.c msgid "failed to get default branch name" msgstr "s'ha produït un error en obtenir el nom de branca predeterminada" +#: scalar.c msgid "failed to unregister repository" msgstr "s'ha produït un error en desregistrar el repositori" +#: scalar.c msgid "failed to stop the FSMonitor daemon" msgstr "no s'ha pogut aturar el dimoni del FSMonitor" +#: scalar.c msgid "failed to delete enlistment directory" msgstr "s'ha produït un error en suprimir l'allistament del directori" +#: scalar.c msgid "branch to checkout after clone" msgstr "branca a agafar després de clonar" +#: scalar.c msgid "when cloning, create full working directory" msgstr "quan es clona, crear un directori de treball complet" +#: scalar.c 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à" +#: scalar.c msgid "create repository within 'src' directory" msgstr "crea un repositori dins del directori «src»" +#: scalar.c +msgid "specify if tags should be fetched during clone" +msgstr "especifica si les etiquetes s'han d'obtenir durant el clon" + +# Deixem <enlistment> sense traduir de moment +#: scalar.c msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" -"scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"scalar clone [--single-branch] [--branch <branca-principal>] [--full-clone]\n" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" +#: scalar.c #, c-format msgid "cannot deduce worktree name from '%s'" msgstr "no es pot deduir el nom de l'arbre de treball de «%s»" +#: scalar.c #, c-format msgid "directory '%s' exists already" msgstr "el directori «%s» ja existeix" +#: scalar.c #, c-format msgid "failed to get default branch for '%s'" msgstr "s'ha produït un error en obtenir la branca per defecte per a «%s»" +#: scalar.c #, c-format msgid "could not configure remote in '%s'" msgstr "no s'ha pogut configurar el remot a «%s»" +#: scalar.c +#, c-format +msgid "could not disable tags in '%s'" +msgstr "no s'han pogut inhabilitar les etiquetes en «%s»" + +#: scalar.c #, c-format msgid "could not configure '%s'" msgstr "no s'ha pogut configurar «%s»" +#: scalar.c msgid "partial clone failed; attempting full clone" msgstr "ha fallat la clonació parcial; s'està intentant la clonació completa" +#: scalar.c msgid "could not configure for full clone" msgstr "no s'ha pogut configurar per a una clonació completa" +#: scalar.c msgid "scalar diagnose [<enlistment>]" msgstr "scalar diagnose [<enlistment>]" +#: scalar.c msgid "`scalar list` does not take arguments" msgstr "«scalar list» no accepta arguments" +#: scalar.c msgid "scalar register [<enlistment>]" msgstr "scalar register [<enlistment>]" +#: scalar.c msgid "reconfigure all registered enlistments" msgstr "reconfigura tots els allistaments registrats" +#: scalar.c msgid "scalar reconfigure [--all | <enlistment>]" msgstr "scalar reconfigure [--all | <enlistment>]" +#: scalar.c msgid "--all or <enlistment>, but not both" msgstr "--all o <enlistment>, però no ambdós" +#: scalar.c #, c-format msgid "could not remove stale scalar.repo '%s'" msgstr "no s'ha pogut suprimir el scalar.repo «%s» estancat" +#: scalar.c #, c-format msgid "removed stale scalar.repo '%s'" msgstr "s'ha eliminat l'scalar.repo estancat «%s»" +#: scalar.c #, c-format msgid "repository at '%s' has different owner" msgstr "el dipòsit a «%s» té un propietari diferent" +#: scalar.c #, c-format msgid "repository at '%s' has a format issue" msgstr "el dipòsit a «%s» té un problema de format" +#: scalar.c #, c-format msgid "repository not found in '%s'" msgstr "no s'ha trobat el dipòsit a «%s»" +#: scalar.c #, c-format msgid "" "to unregister this repository from Scalar, run\n" @@ -20189,6 +26005,7 @@ msgstr "" "per a desregistrar aquest dipòsit de l'escalar, executeu\n" "\tgit config --global --unset --fixed-value scalar.repo «%s»" +#: scalar.c msgid "" "scalar run <task> [<enlistment>]\n" "Tasks:\n" @@ -20196,77 +26013,97 @@ msgstr "" "scalar run <task> {<enlistment>]\n" "Tasques:\n" +#: scalar.c #, c-format msgid "no such task: '%s'" msgstr "no existeix la tasca: «%s»" +#: scalar.c msgid "scalar unregister [<enlistment>]" msgstr "scalar unregister [<enlistment>]" +#: scalar.c msgid "scalar delete <enlistment>" msgstr "supressió de l'escalar <enlistment>" +#: scalar.c msgid "refusing to delete current working directory" msgstr "s'ha rebutjat suprimir el directori de treball actual" +#: scalar.c msgid "include Git version" msgstr "inclou la versió del Git" +#: scalar.c msgid "include Git's build options" msgstr "inclou les opcions de construcció del Git" +#: scalar.c msgid "scalar verbose [-v | --verbose] [--build-options]" msgstr "scalar verbose [-v | --verbose] [--build-options]" +#: scalar.c msgid "-C requires a <directory>" -msgstr "-C requereix un <directory>" +msgstr "-C requereix un <directori>" +#: scalar.c #, c-format msgid "could not change to '%s'" msgstr "no s'ha pogut canviar a «%s»" +#: scalar.c msgid "-c requires a <key>=<value> argument" -msgstr "-c requereix un argument <key>=<value>" +msgstr "-c requereix un argument <clau>=<valor>" +#: scalar.c msgid "" "scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n" "\n" "Commands:\n" msgstr "" -"scalar [-C <directory>] [-c <key>=<value>] <command> [<opcions>]\n" +"scalar [-C <directori>] [-c <clau>=<valor>] <ordre> [<opcions>]\n" "\n" "Ordres:\n" +#: send-pack.c msgid "unexpected flush packet while reading remote unpack status" msgstr "" "paquet de buidatge no esperat quan estava llegint l'estat del " "desempaquetament remot" +#: send-pack.c #, c-format msgid "unable to parse remote unpack status: %s" msgstr "no s'ha pogut analitzar l'estat del desempaquetament remot: %s" +#: send-pack.c #, c-format msgid "remote unpack failed: %s" msgstr "s'ha produït un error en el desempaquetament remot: %s" +#: send-pack.c msgid "failed to sign the push certificate" msgstr "s'ha produït un error en signar el certificat de pujada" +#: send-pack.c msgid "send-pack: unable to fork off fetch subprocess" msgstr "send-pack: no es pot bifurcar obtenint un subprocés" +#: send-pack.c msgid "push negotiation failed; proceeding anyway with push" msgstr "" "ha fallat la negociació de la pujada; s'està procedint igualment amb " "l'empenta" +#: send-pack.c msgid "the receiving end does not support this repository's hash algorithm" msgstr "el receptor de destí no admet l'algorisme de resum del repositori" +#: send-pack.c msgid "the receiving end does not support --signed push" msgstr "el destí receptor no admet pujar --signed" +#: send-pack.c msgid "" "not sending a push certificate since the receiving end does not support --" "signed push" @@ -20274,33 +26111,58 @@ msgstr "" "no s'està enviant una certificació de pujada perquè el destí receptor no " "admet pujar --signed" +#: send-pack.c msgid "the receiving end does not support --atomic push" msgstr "el destí receptor no admet pujar --atomic" +#: send-pack.c msgid "the receiving end does not support push options" msgstr "el receptor al destí no admet opcions de pujada" +#: sequencer.c #, c-format msgid "invalid commit message cleanup mode '%s'" msgstr "mode de neteja «%s» no vàlid en la comissió del missatge" +#: sequencer.c #, c-format msgid "could not delete '%s'" msgstr "no s'ha pogut suprimir «%s»" +#: sequencer.c msgid "revert" msgstr "revertir" +#: sequencer.c msgid "cherry-pick" msgstr "cherry-pick" +#: sequencer.c msgid "rebase" msgstr "rebase" +#: sequencer.c #, c-format msgid "unknown action: %d" msgstr "acció desconeguda: %d" +#: sequencer.c +msgid "" +"Resolve all conflicts manually, mark them as resolved with\n" +"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n" +"You can instead skip this commit: run \"git rebase --skip\".\n" +"To abort and get back to the state before \"git rebase\", run \"git rebase --" +"abort\"." +msgstr "" +"Resoleu tots els conflictes manualment, marqueu-los com a resolts amb\n" +"«git add/rm <fitxers_amb_conflicte>», llavors executeu «git rebase --" +"continue».\n" +"Alternativament podeu ometre aquesta comissió: executeu «git rebase --" +"skip».\n" +"Per a avortar i tornar a l'estat anterior abans de l'ordre «git rebase», " +"executeu «git rebase --abort»." + +#: sequencer.c msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -20308,6 +26170,7 @@ msgstr "" "després de resoldre els conflictes, marqueu els camins\n" "corregits amb «git add <camins>» o «git rm <camins>»" +#: sequencer.c msgid "" "After resolving the conflicts, mark them with\n" "\"git add/rm <pathspec>\", then run\n" @@ -20323,6 +26186,7 @@ msgstr "" "Per a interrompre i tornar a l'estat anterior abans de «git cherry-pick»,\n" "executeu «git cherry-pick --abort»." +#: sequencer.c msgid "" "After resolving the conflicts, mark them with\n" "\"git add/rm <pathspec>\", then run\n" @@ -20338,68 +26202,86 @@ msgstr "" "Per a interrompre i tornar a l'estat anterior abans de «git revert»,\n" "executeu «git revert --abort»." +#: sequencer.c #, c-format msgid "could not lock '%s'" msgstr "no s'ha pogut bloquejar «%s»" +#: sequencer.c #, c-format msgid "could not write eol to '%s'" msgstr "no s'ha pogut escriure el terminador de línia a «%s»" +#: sequencer.c #, c-format msgid "failed to finalize '%s'" msgstr "s'ha produït un error en finalitzar «%s»" +#: sequencer.c #, c-format msgid "your local changes would be overwritten by %s." msgstr "els vostres canvis locals se sobreescriurien per %s." +#: sequencer.c msgid "commit your changes or stash them to proceed." msgstr "cometeu els vostres canvis o feu un «stash» per a procedir." #. TRANSLATORS: %s will be "revert", "cherry-pick" or #. "rebase". #. +#: sequencer.c #, c-format msgid "%s: Unable to write new index file" msgstr "%s: No s'ha pogut escriure un fitxer d'índex nou" +#: sequencer.c msgid "unable to update cache tree" msgstr "no s'ha pogut actualitzar l'arbre cau" +#: sequencer.c msgid "could not resolve HEAD commit" msgstr "no s'ha pogut resoldre la comissió HEAD" +#: sequencer.c #, c-format msgid "no key present in '%.*s'" msgstr "no hi ha una clau a «%.*s»" +#: sequencer.c #, c-format msgid "unable to dequote value of '%s'" msgstr "no s'han pogut treure les cometes del valor de «%s»" +#: sequencer.c msgid "'GIT_AUTHOR_NAME' already given" msgstr "Ja s'ha donat «GIT_AUTHOR_NAME»" +#: sequencer.c msgid "'GIT_AUTHOR_EMAIL' already given" msgstr "Ja s'ha donat «GIT_AUTHOR_EMAIL»" +#: sequencer.c msgid "'GIT_AUTHOR_DATE' already given" msgstr "Ja s'ha donat «GIT_AUTHOR_DATE»" +#: sequencer.c #, c-format msgid "unknown variable '%s'" msgstr "variable «%s» desconeguda" +#: sequencer.c msgid "missing 'GIT_AUTHOR_NAME'" msgstr "falta «GIT_AUTHOR_NAME»" +#: sequencer.c msgid "missing 'GIT_AUTHOR_EMAIL'" msgstr "falta «GIT_AUTHOR_EMAIL»" +#: sequencer.c msgid "missing 'GIT_AUTHOR_DATE'" msgstr "falta «GIT_AUTHOR_DATE»" +#: sequencer.c #, c-format msgid "" "you have staged changes in your working tree\n" @@ -20429,9 +26311,11 @@ msgstr "" "\n" " git rebase --continue\n" +#: sequencer.c msgid "'prepare-commit-msg' hook failed" msgstr "el lligam «prepare-commit-msg» ha fallat" +#: sequencer.c msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -20458,6 +26342,7 @@ msgstr "" "\n" " git commit --amend --reset-author\n" +#: sequencer.c msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -20483,259 +26368,369 @@ msgstr "" "\n" " git commit --amend --reset-author\n" +#: sequencer.c msgid "couldn't look up newly created commit" msgstr "no s'ha pogut trobar la comissió novament creada" +#: sequencer.c msgid "could not parse newly created commit" msgstr "no s'ha pogut analitzar la comissió novament creada" +#: sequencer.c msgid "unable to resolve HEAD after creating commit" msgstr "no s'ha pogut resoldre HEAD després de crear la comissió" +#: sequencer.c msgid "detached HEAD" msgstr "HEAD separat" +#: sequencer.c msgid " (root-commit)" msgstr " (comissió arrel)" +#: sequencer.c msgid "could not parse HEAD" msgstr "no s'ha pogut analitzar HEAD" +#: sequencer.c #, c-format msgid "HEAD %s is not a commit!" msgstr "HEAD %s no és una comissió!" +#: sequencer.c msgid "unable to parse commit author" msgstr "no s'ha pogut analitzar l'autor de la comissió" +#: sequencer.c #, c-format msgid "unable to read commit message from '%s'" msgstr "no s'ha pogut llegir el missatge de comissió des de «%s»" +#: sequencer.c #, c-format msgid "invalid author identity '%s'" msgstr "identitat d'autor no vàlida: «%s»" +#: sequencer.c msgid "corrupt author: missing date information" msgstr "autor malmès: falta la informació de la data" +#: sequencer.c #, c-format msgid "could not update %s" msgstr "no s'ha pogut actualitzar %s" -#, c-format -msgid "could not parse commit %s" -msgstr "no s'ha pogut analitzar la comissió %s" - +#: sequencer.c #, c-format msgid "could not parse parent commit %s" msgstr "no s'ha pogut analitzar la comissió pare %s" +#: sequencer.c #, c-format msgid "unknown command: %d" msgstr "ordre desconeguda: %d" +#: sequencer.c msgid "This is the 1st commit message:" msgstr "Aquest és el missatge de la 1a comissió:" +#: sequencer.c #, c-format msgid "This is the commit message #%d:" msgstr "Aquest és el missatge de la #%d comissió:" +#: sequencer.c msgid "The 1st commit message will be skipped:" msgstr "El missatge de la primera comissió s'ometrà:" +#: sequencer.c #, c-format msgid "The commit message #%d will be skipped:" msgstr "El missatge de la comissió núm. #%d s'ometrà:" +#: sequencer.c #, c-format msgid "This is a combination of %d commits." msgstr "Això és una combinació de %d comissions." +#: sequencer.c #, c-format msgid "cannot write '%s'" msgstr "no es pot escriure «%s»" +#: sequencer.c msgid "need a HEAD to fixup" msgstr "cal un HEAD per a reparar-ho" +#: sequencer.c msgid "could not read HEAD" msgstr "no s'ha pogut llegir HEAD" +#: sequencer.c msgid "could not read HEAD's commit message" msgstr "no s'ha pogut llegir el missatge de comissió de HEAD" +#: sequencer.c #, c-format msgid "could not read commit message of %s" msgstr "no s'ha pogut llegir el missatge de comissió: %s" +#: sequencer.c msgid "your index file is unmerged." msgstr "el vostre fitxer d'índex està sense fusionar." +#: sequencer.c msgid "cannot fixup root commit" msgstr "no es pot arreglar la comissió arrel" +#: sequencer.c #, c-format msgid "commit %s is a merge but no -m option was given." msgstr "la comissió %s és una fusió però no s'ha donat cap opció -m." +#: sequencer.c #, c-format msgid "commit %s does not have parent %d" msgstr "la comissió %s no té pare %d" +#: sequencer.c #, c-format msgid "cannot get commit message for %s" msgstr "no es pot obtenir el missatge de comissió de %s" #. TRANSLATORS: The first %s will be a "todo" command like #. "revert" or "pick", the second %s a SHA1. +#: sequencer.c #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: no es pot analitzar la comissió pare %s" +#: sequencer.c #, c-format msgid "could not revert %s... %s" msgstr "no s'ha pogut revertir %s... %s" +#: sequencer.c #, c-format msgid "could not apply %s... %s" msgstr "no s'ha pogut aplicar %s... %s" +#: sequencer.c #, c-format msgid "dropping %s %s -- patch contents already upstream\n" msgstr "descartant %s %s -- el contingut del pedaç ja està a la font\n" +#: sequencer.c #, c-format msgid "git %s: failed to read the index" msgstr "git %s: s'ha produït un error en llegir l'índex" +#: sequencer.c #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: s'ha produït un error en actualitzar l'índex" +#: sequencer.c #, c-format msgid "'%s' is not a valid label" msgstr "«%s» no és una etiqueta vàlida" +#: sequencer.c #, c-format msgid "'%s' is not a valid refname" msgstr "«%s» no és un nom de referència vàlid" +#: sequencer.c #, c-format msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s" msgstr "" "«update-ref» requereix un refname plenament qualificat, p. ex. refs/heads/%s" +#: sequencer.c #, c-format -msgid "invalid command '%.*s'" -msgstr "ordre no vàlida «%.*s»" +msgid "'%s' does not accept merge commits" +msgstr "%s no accepta comissions de fusió" +#. TRANSLATORS: 'pick' and 'merge -C' should not be +#. translated. +#. +#: sequencer.c +msgid "" +"'pick' does not take a merge commit. If you wanted to\n" +"replay the merge, use 'merge -C' on the commit." +msgstr "" +"«pick» no accepta una comissió de fusió. Si volíeu\n" +"reproduir la fusió, utilitzeu «merge -C» en la comissió." + +#. TRANSLATORS: 'reword' and 'merge -c' should not be +#. translated. +#. +#: sequencer.c +msgid "" +"'reword' does not take a merge commit. If you wanted to\n" +"replay the merge and reword the commit message, use\n" +"'merge -c' on the commit" +msgstr "" +"«reword» no accepta una comissió de fusió. Si volíeu\n" +"reproduir la fusió i fer «reword» del missatge de comissió,\n" +"utilitzeu «merge -c» en la comissió" + +#. TRANSLATORS: 'edit', 'merge -C' and 'break' should +#. not be translated. +#. +#: sequencer.c +msgid "" +"'edit' does not take a merge commit. If you wanted to\n" +"replay the merge, use 'merge -C' on the commit, and then\n" +"'break' to give the control back to you so that you can\n" +"do 'git commit --amend && git rebase --continue'." +msgstr "" +"«edit» no accepta una comissió de fusió. Si volíeu\n" +"reproduir la fusió, utilitzeu «merge -C» en la comissió\n" +" i després «break» per a recuperar el control perquè pugueu\n" +"feu «git commit --amend && git rebase --continue»." + +#: sequencer.c +msgid "cannot squash merge commit into another commit" +msgstr "no es pot fer «squash» d'una comissió de fusió en una altra comissió" + +#: sequencer.c #, c-format -msgid "%s does not accept arguments: '%s'" -msgstr "%s no accepta arguments: «%s»" +msgid "invalid command '%.*s'" +msgstr "ordre no vàlida «%.*s»" +#: sequencer.c #, c-format msgid "missing arguments for %s" msgstr "falten els arguments per a %s" +#: sequencer.c #, c-format msgid "could not parse '%s'" msgstr "no s'ha pogut analitzar «%s»" +#: sequencer.c #, c-format msgid "invalid line %d: %.*s" msgstr "línia no vàlida %d: %.*s" +#: sequencer.c #, c-format msgid "cannot '%s' without a previous commit" msgstr "no es pot «%s» sense una comissió prèvia" +#: sequencer.c msgid "cancelling a cherry picking in progress" msgstr "s'està cancel·lant un «cherry pick» en curs" +#: sequencer.c msgid "cancelling a revert in progress" msgstr "s'està cancel·lant la reversió en curs" +#: sequencer.c msgid "please fix this using 'git rebase --edit-todo'." msgstr "corregiu-ho usant «git rebase --edit-todo»." +#: sequencer.c #, c-format msgid "unusable instruction sheet: '%s'" msgstr "full d'instruccions inusable: «%s»" +#: sequencer.c msgid "no commits parsed." msgstr "no s'ha analitzat cap comissió." +#: sequencer.c msgid "cannot cherry-pick during a revert." msgstr "no es pot fer «cherry pick» durant una reversió." +#: sequencer.c msgid "cannot revert during a cherry-pick." msgstr "no es pot revertir durant un «cherry pick»." +#: sequencer.c msgid "unusable squash-onto" msgstr "«squash-onto» no usable" +#: sequencer.c #, c-format msgid "malformed options sheet: '%s'" msgstr "full d'opcions mal format: «%s»" +#: sequencer.c msgid "empty commit set passed" msgstr "conjunt de comissions buit passat" +#: sequencer.c msgid "revert is already in progress" msgstr "una reversió ja està en curs" +#: sequencer.c #, c-format msgid "try \"git revert (--continue | %s--abort | --quit)\"" msgstr "intenteu «git revert (--continue | %s--abort | --quit)»" +#: sequencer.c msgid "cherry-pick is already in progress" msgstr "un «cherry pick» ja està en curs" +#: sequencer.c #, c-format msgid "try \"git cherry-pick (--continue | %s--abort | --quit)\"" msgstr "intenteu «git cherry-pick (--continue | %s--abort | --quit)»" +#: sequencer.c #, c-format msgid "could not create sequencer directory '%s'" msgstr "no s'ha pogut crear el directori de seqüenciador «%s»" +#: sequencer.c msgid "no cherry-pick or revert in progress" msgstr "ni hi ha cap «cherry pick» ni cap reversió en curs" +#: sequencer.c msgid "cannot resolve HEAD" msgstr "no es pot resoldre HEAD" +#: sequencer.c msgid "cannot abort from a branch yet to be born" msgstr "no es pot avortar des d'una branca que encara ha de nàixer" +#: sequencer.c #, c-format msgid "cannot read '%s': %s" msgstr "no es pot llegir «%s»: %s" +#: sequencer.c msgid "unexpected end of file" msgstr "final de fitxer inesperat" +#: sequencer.c #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "el fitxer HEAD emmagatzemat abans de fer «cherry pick» «%s» és malmès" +#: sequencer.c msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!" -msgstr "Sembla que heu mogut HEAD sense rebobinar, comproveu-ho HEAD" +msgstr "Sembla que heu mogut HEAD. No es fa el rebobinat, comproveu-ho HEAD" +#: sequencer.c msgid "no revert in progress" msgstr "no hi ha cap reversió en curs" +#: sequencer.c msgid "no cherry-pick in progress" msgstr "ni hi ha cap «cherry pick» en curs" +#: sequencer.c msgid "failed to skip the commit" msgstr "s'ha produït un error en ometre la comissió" +#: sequencer.c msgid "there is nothing to skip" msgstr "no hi ha res a ometre" +#: sequencer.c #, c-format msgid "" "have you committed already?\n" @@ -20744,13 +26739,15 @@ msgstr "" "heu fet ja una comissió?\n" "proveu «git %s --continue»" +#: sequencer.c msgid "cannot read HEAD" msgstr "no es pot llegir HEAD" -#, c-format -msgid "unable to copy '%s' to '%s'" -msgstr "no s'ha pogut copiar «%s» a «%s»" +#: sequencer.c +msgid "could not write commit message file" +msgstr "no s'ha pogut escriure el fitxer de missatge de comissió" +#: sequencer.c #, c-format msgid "" "You can amend the commit now, with\n" @@ -20769,18 +26766,22 @@ msgstr "" "\n" " git rebase --continue\n" +#: sequencer.c #, c-format msgid "Could not apply %s... %.*s" msgstr "No s'ha pogut aplicar %s... %.*s" +#: sequencer.c #, c-format msgid "Could not merge %.*s" msgstr "No s'ha pogut fusionar %.*s" +#: sequencer.c #, c-format msgid "Executing: %s\n" msgstr "S'està executant: %s\n" +#: sequencer.c #, c-format msgid "" "execution failed: %s\n" @@ -20795,9 +26796,11 @@ msgstr "" " git rebase --continue\n" "\n" +#: sequencer.c msgid "and made changes to the index and/or the working tree.\n" msgstr "i ha fet canvis a l'índex i/o a l'arbre de treball.\n" +#: sequencer.c #, c-format msgid "" "execution succeeded: %s\n" @@ -20814,52 +26817,65 @@ msgstr "" " git rebase --continue\n" "\n" +#: sequencer.c #, c-format msgid "illegal label name: '%.*s'" msgstr "nom d'etiqueta no permès: «%.*s»" +#: sequencer.c #, c-format msgid "could not resolve '%s'" msgstr "no s'ha pogut resoldre «%s»" +#: sequencer.c msgid "writing fake root commit" msgstr "s'està escrivint una comissió arrel falsa" +#: sequencer.c msgid "writing squash-onto" msgstr "s'està escrivint «squash-onto»" +#: sequencer.c msgid "cannot merge without a current revision" msgstr "no es pot fusionar sense una revisió actual" +#: sequencer.c #, c-format msgid "unable to parse '%.*s'" msgstr "no s'ha pogut analitzar «%.*s»" +#: sequencer.c #, c-format msgid "nothing to merge: '%.*s'" msgstr "no hi ha res per a fusionar «%.*s»" +#: sequencer.c msgid "octopus merge cannot be executed on top of a [new root]" msgstr "" "no es pot executar la fusió «octopus» a la part superior d'una [arrel nova]" +#: sequencer.c #, c-format msgid "could not get commit message of '%s'" msgstr "no s'ha pogut llegir el missatge de comissió de «%s»" +#: sequencer.c #, c-format msgid "could not even attempt to merge '%.*s'" msgstr "no s'ha pogut fusionar «%.*s»" +#: sequencer.c msgid "merge: Unable to write new index file" msgstr "fusió: no s'ha pogut escriure un fitxer d'índex nou" +#: sequencer.c #, c-format msgid "" "another 'rebase' process appears to be running; '%s.lock' already exists" msgstr "" "sembla que s'està executant un altre procés «rebase»: «%s.lock» ja existeix" +#: sequencer.c #, c-format msgid "" "Updated the following refs with %s:\n" @@ -20868,6 +26884,7 @@ msgstr "" "S'han actualitzat els següents refs amb %s:\n" "%s" +#: sequencer.c #, c-format msgid "" "Failed to update the following refs with %s:\n" @@ -20876,32 +26893,40 @@ msgstr "" "No s'han pogut actualitzar les referències següents amb %s:\n" "%s" +#: sequencer.c msgid "Cannot autostash" msgstr "No es pot fer un «stash» automàticament" +#: sequencer.c #, c-format msgid "Unexpected stash response: '%s'" msgstr "Resposta de «stash» inesperada: «%s»" +#: sequencer.c #, c-format msgid "Could not create directory for '%s'" msgstr "No s'ha pogut crear el directori per a «%s»" +#: sequencer.c #, c-format msgid "Created autostash: %s\n" msgstr "S'ha creat un «stash» automàticament: %s\n" +#: sequencer.c msgid "could not reset --hard" msgstr "no s'ha pogut fer reset --hard" +#: sequencer.c #, c-format msgid "Applied autostash.\n" msgstr "S'ha aplicat el «stash» automàticament.\n" +#: sequencer.c #, c-format msgid "cannot store %s" msgstr "no es pot emmagatzemar %s" +#: sequencer.c #, c-format msgid "" "%s\n" @@ -20912,27 +26937,34 @@ msgstr "" "Els vostres canvis estan segurs en el «stash».\n" "Podeu executar «git stash pop» o «git stash drop» en qualsevol moment.\n" +#: sequencer.c msgid "Applying autostash resulted in conflicts." msgstr "L'aplicació del «stash» automàticament ha donat conflictes." +#: sequencer.c msgid "Autostash exists; creating a new stash entry." msgstr "" "El «stash» automàtic ja existeix; s'està creant una entrada «stash» nova." +#: sequencer.c msgid "autostash reference is a symref" msgstr "la referència d'autostash és un symref" +#: sequencer.c msgid "could not detach HEAD" msgstr "no s'ha pogut separar HEAD" +#: sequencer.c #, c-format msgid "Stopped at HEAD\n" msgstr "Aturat a HEAD\n" +#: sequencer.c #, c-format msgid "Stopped at %s\n" msgstr "Aturat a %s\n" +#: sequencer.c #, c-format msgid "" "Could not execute the todo command\n" @@ -20953,46 +26985,58 @@ msgstr "" " git rebase --edit-todo\n" " git rebase --continue\n" +#: sequencer.c #, c-format msgid "Stopped at %s... %.*s\n" msgstr "Aturat a %s... %.*s\n" +#: sequencer.c #, c-format msgid "Rebasing (%d/%d)%s" msgstr "S'està fent «rebase» (%d/%d)%s" +#: sequencer.c #, c-format msgid "unknown command %d" msgstr "ordre %d desconeguda" +#: sequencer.c msgid "could not read orig-head" msgstr "no s'ha pogut llegir orig-head" +#: sequencer.c msgid "could not read 'onto'" msgstr "no s'ha pogut llegir «onto»" +#: sequencer.c #, c-format msgid "could not update HEAD to %s" msgstr "no s'ha pogut actualitzar HEAD a %s" +#: sequencer.c #, c-format msgid "Successfully rebased and updated %s.\n" msgstr "S'ha fet «rebase» i actualitzat %s amb èxit.\n" +#: sequencer.c msgid "cannot rebase: You have unstaged changes." msgstr "no es pot fer «rebase»: teniu canvis «unstaged»." +#: sequencer.c msgid "cannot amend non-existing commit" msgstr "no es pot esmenar una comissió no existent" +#: sequencer.c #, c-format msgid "invalid file: '%s'" msgstr "fitxer no vàlid: «%s»" +#: sequencer.c #, c-format msgid "invalid contents: '%s'" msgstr "contingut no vàlid: «%s»" +#: sequencer.c msgid "" "\n" "You have uncommitted changes in your working tree. Please, commit them\n" @@ -21002,57 +27046,73 @@ msgstr "" "Teniu canvis no comesos en el vostre arbre de treball. \n" "Cometeu-los primer i després executeu «git rebase --continue» de nou." +#: sequencer.c #, c-format msgid "could not write file: '%s'" msgstr "no s'ha pogut escriure el fitxer: «%s»" +#: sequencer.c msgid "could not remove CHERRY_PICK_HEAD" msgstr "no s'ha pogut eliminar CHERRY_PICK_HEAD" +#: sequencer.c msgid "could not commit staged changes." msgstr "no s'han pogut cometre els canvis «staged»." +#: sequencer.c #, c-format msgid "%s: can't cherry-pick a %s" msgstr "%s: no es pot fer «cherry pick» a %s" +#: sequencer.c #, c-format msgid "%s: bad revision" msgstr "%s: revisió incorrecta" +#: sequencer.c msgid "can't revert as initial commit" msgstr "no es pot revertir com a comissió inicial" +#: sequencer.c #, c-format msgid "skipped previously applied commit %s" msgstr "omet les comissions aplicades anteriorment %s" +#: sequencer.c msgid "use --reapply-cherry-picks to include skipped commits" msgstr "useu --reapply-cherry-picks per a incloure les comissions omeses" +#: sequencer.c msgid "make_script: unhandled options" msgstr "make_script: opcions no gestionades" +#: sequencer.c msgid "make_script: error preparing revisions" msgstr "make_script: s'ha produït un error en preparar les revisions" +#: sequencer.c msgid "nothing to do" msgstr "res a fer" +#: sequencer.c msgid "could not skip unnecessary pick commands" msgstr "no s'han pogut ometre les ordres «picks» no necessàries" +#: sequencer.c msgid "the script was already rearranged." msgstr "l'script ja estava endreçat." +#: sequencer.c #, c-format msgid "update-refs file at '%s' is invalid" msgstr "el fitxer update-refs a «%s» no és vàlid" +#: setup.c #, c-format msgid "'%s' is outside repository at '%s'" msgstr "«%s» està fora del repositori a «%s»" +#: setup.c #, c-format msgid "" "%s: no such path in the working tree.\n" @@ -21062,6 +27122,7 @@ msgstr "" "Useu «git <ordre> -- <camí>...» per a especificar camins que no existeixin " "localment." +#: setup.c #, c-format msgid "" "ambiguous argument '%s': unknown revision or path not in the working tree.\n" @@ -21073,10 +27134,12 @@ msgstr "" "Useu «--» per a separar els camins de les revisions:\n" "«git <ordre> [<revisió>...] -- [<fitxer>...]»" +#: setup.c #, c-format msgid "option '%s' must come before non-option arguments" msgstr "l'opció «%s» ha d'aparèixer abans que els arguments opcionals" +#: setup.c #, c-format msgid "" "ambiguous argument '%s': both revision and filename\n" @@ -21087,79 +27150,121 @@ msgstr "" "Useu «--» per a separar els camins de les revisions:\n" "«git <ordre> [<revisió>...] -- [<fitxer>...]»" +#: setup.c msgid "unable to set up work tree using invalid config" msgstr "" "no s'ha pogut configurar un arbre de treball utilitzant una configuració no " "vàlida" +#: setup.c +#, c-format +msgid "'%s' already specified as '%s'" +msgstr "«%s» ja especificat com a «%s»" + +#: setup.c #, c-format msgid "Expected git repo version <= %d, found %d" msgstr "S'esperava una versió de repositori de git <= %d, s'ha trobat %d" +#: setup.c msgid "unknown repository extension found:" msgid_plural "unknown repository extensions found:" msgstr[0] "s'ha trobat una extensió de repositori desconeguda:" msgstr[1] "s'han trobat extensions de repositori desconegudes:" +#: setup.c msgid "repo version is 0, but v1-only extension found:" msgid_plural "repo version is 0, but v1-only extensions found:" msgstr[0] "el repositori és versió 0, però només s'han trobat una extensió v1:" msgstr[1] "el repositori és versió 0, però només s'han trobat extensions v1:" +#: setup.c #, c-format msgid "error opening '%s'" msgstr "s'ha produït un error en obrir «%s»" +#: setup.c #, c-format msgid "too large to be a .git file: '%s'" msgstr "massa gran per a ser un fitxer .git: «%s»" +#: setup.c #, c-format msgid "error reading %s" msgstr "error en llegir %s" +#: setup.c #, c-format msgid "invalid gitfile format: %s" msgstr "format gitfile no vàlid: %s" +#: setup.c #, c-format msgid "no path in gitfile: %s" msgstr "sense camí al gitfile: %s" +#: setup.c #, c-format msgid "not a git repository: %s" msgstr "no és un repositori de git: %s" +#: setup.c #, c-format msgid "'$%s' too big" msgstr "«$%s» massa gran" +#: setup.c #, c-format msgid "not a git repository: '%s'" msgstr "no és un repositori de git: «%s»" +#: setup.c #, c-format msgid "cannot chdir to '%s'" msgstr "no es pot canviar de directori a «%s»" +#: setup.c msgid "cannot come back to cwd" msgstr "no es pot tornar al directori de treball actual" +#: setup.c #, c-format msgid "failed to stat '%*s%s%s'" msgstr "s'ha produït un error en fer stat a «%*s%s%s»" +#: setup.c +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "el safe.directory «%s» no és absolut" + +#: setup.c +#, c-format +msgid "" +"detected dubious ownership in repository at '%s'\n" +"%sTo add an exception for this directory, call:\n" +"\n" +"\tgit config --global --add safe.directory %s" +msgstr "" +"s'ha detectat una propietat dubtosa al repositori a «%s»\n" +"%sPer a afegir una excepció per a aquest directori, executeu:\n" +"\n" +"\tgit config --global --add safe.directory %s" + +#: setup.c msgid "Unable to read current working directory" msgstr "No s'ha pogut llegir el directori de treball actual" +#: setup.c #, c-format msgid "cannot change to '%s'" msgstr "no es pot canviar a «%s»" +#: setup.c #, c-format msgid "not a git repository (or any of the parent directories): %s" msgstr "no és un repositori de git (ni cap dels directoris pares): %s" +#: setup.c #, c-format msgid "" "not a git repository (or any parent up to mount point %s)\n" @@ -21170,22 +27275,12 @@ msgstr "" "S'atura a la frontera de sistema de fitxers (GIT_DISCOVERY_ACROSS_FILESYSTEM " "no està establert)." -#, c-format -msgid "" -"detected dubious ownership in repository at '%s'\n" -"%sTo add an exception for this directory, call:\n" -"\n" -"\tgit config --global --add safe.directory %s" -msgstr "" -"s'ha detectat una propietat dubtosa al repositori a «%s»\n" -"%sPer a afegir una excepció per a aquest directori, executeu:\n" -"\n" -"\tgit config --global --add safe.directory %s" - +#: setup.c #, c-format msgid "cannot use bare repository '%s' (safe.bareRepository is '%s')" msgstr "no es pot utilitzar el dipòsit nu «%s» (safe.bareRepository és «%s»)" +#: setup.c #, c-format msgid "" "problem with core.sharedRepository filemode value (0%.3o).\n" @@ -21196,185 +27291,246 @@ msgstr "" "El propietari dels fitxers sempre ha de tenir permisos de lectura i " "escriptura." +#: setup.c msgid "fork failed" msgstr "el «fork» ha fallat" +#: setup.c msgid "setsid failed" msgstr "«setsid» ha fallat" +#: setup.c #, c-format msgid "cannot stat template '%s'" msgstr "no es pot fer stat en la plantilla «%s»" +#: setup.c #, c-format msgid "cannot opendir '%s'" msgstr "no es pot fer opendir en el directori «%s»" +#: setup.c #, c-format msgid "cannot readlink '%s'" msgstr "no es pot fer readlink en «%s»" +#: setup.c #, c-format msgid "cannot symlink '%s' '%s'" msgstr "no es pot fer symlink en «%s» «%s»" +#: setup.c #, c-format msgid "cannot copy '%s' to '%s'" msgstr "no es pot copiar «%s» a «%s»" +#: setup.c #, c-format msgid "ignoring template %s" msgstr "s'està ignorant la plantilla %s" +#: setup.c #, c-format msgid "templates not found in %s" msgstr "plantilles no trobades a %s" +#: setup.c #, c-format msgid "not copying templates from '%s': %s" msgstr "no s'estan copiant plantilles de «%s»: %s" +#: setup.c #, c-format msgid "invalid initial branch name: '%s'" msgstr "nom de branca inicial no vàlid: «%s»" +#: setup.c #, c-format msgid "re-init: ignored --initial-branch=%s" msgstr "reinicialització: s'ha ignorat --initial-branch=%s" +#: setup.c #, c-format msgid "unable to handle file type %d" msgstr "no s'ha pogut gestionar el tipus de fitxer %d" +#: setup.c #, c-format msgid "unable to move %s to %s" msgstr "no s'ha pogut moure %s a %s" +#: setup.c msgid "attempt to reinitialize repository with different hash" msgstr "s'ha intentat reinicialitzar el repositori amb un resum diferent" +#: setup.c 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" +#: setup.c #, c-format msgid "%s already exists" msgstr "%s ja existeix" +#: setup.c #, 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" +#: setup.c #, c-format msgid "Reinitialized existing Git repository in %s%s\n" msgstr "S'ha reinicialitzat el repositori existent del Git en %s%s\n" +#: setup.c #, c-format msgid "Initialized empty shared Git repository in %s%s\n" msgstr "S'ha inicialitzat un repositori compartit buit del Git en %s%s\n" +#: setup.c #, c-format msgid "Initialized empty Git repository in %s%s\n" msgstr "S'ha inicialitzat un repositori buit del Git en %s%s\n" +#: sparse-index.c #, c-format msgid "index entry is a directory, but not sparse (%08x)" msgstr "l'entrada d'índex és un directori, però no dispers (%08x)" +#: split-index.c msgid "cannot use split index with a sparse index" msgstr "no es pot utilitzar l'índex partit amb un índex dispers" +#. TRANSLATORS: The first %s is a command like "ls-tree". +#: strbuf.c +#, c-format +msgid "bad %s format: element '%s' does not start with '('" +msgstr "format %s incorrecte: l'element «%s» no comença amb «(»" + +#. TRANSLATORS: The first %s is a command like "ls-tree". +#: strbuf.c +#, c-format +msgid "bad %s format: element '%s' does not end in ')'" +msgstr "format %s incorrecte: l'element «%s» no acaba en «)»" + +#. TRANSLATORS: %s is a command like "ls-tree". +#: strbuf.c +#, c-format +msgid "bad %s format: %%%.*s" +msgstr "format %s incorrecte: %%%.*s" + #. TRANSLATORS: IEC 80000-13:2008 gibibyte +#: strbuf.c #, c-format msgid "%u.%2.2u GiB" msgstr "%u.%2.2u GiB" #. TRANSLATORS: IEC 80000-13:2008 gibibyte/second +#: strbuf.c #, c-format msgid "%u.%2.2u GiB/s" msgstr "%u.%2.2u GiB/s" #. TRANSLATORS: IEC 80000-13:2008 mebibyte +#: strbuf.c #, c-format msgid "%u.%2.2u MiB" msgstr "%u.%2.2u MiB" #. TRANSLATORS: IEC 80000-13:2008 mebibyte/second +#: strbuf.c #, c-format msgid "%u.%2.2u MiB/s" msgstr "%u.%2.2u MiB/s" #. TRANSLATORS: IEC 80000-13:2008 kibibyte +#: strbuf.c #, c-format msgid "%u.%2.2u KiB" msgstr "%u.%2.2u KiB" #. TRANSLATORS: IEC 80000-13:2008 kibibyte/second +#: strbuf.c #, c-format msgid "%u.%2.2u KiB/s" msgstr "%u.%2.2u KiB/s" #. TRANSLATORS: IEC 80000-13:2008 byte +#: strbuf.c #, c-format msgid "%u byte" msgid_plural "%u bytes" -msgstr[0] "%u byte" -msgstr[1] "%u bytes" +msgstr[0] "%u octet" +msgstr[1] "%u octets" #. TRANSLATORS: IEC 80000-13:2008 byte/second +#: strbuf.c #, c-format msgid "%u byte/s" msgid_plural "%u bytes/s" -msgstr[0] "%u byte/s" -msgstr[1] "%u bytes/s" +msgstr[0] "%u octet/s" +msgstr[1] "%u octets/s" +#: submodule-config.c #, c-format msgid "ignoring suspicious submodule name: %s" msgstr "s'està ignorant el nom de submòdul sospitós %s" +#: submodule-config.c msgid "negative values not allowed for submodule.fetchJobs" msgstr "no es permeten els valors negatius a submodule.fetchJobs" +#: submodule-config.c #, c-format msgid "ignoring '%s' which may be interpreted as a command-line option: %s" msgstr "" "s'està ignorant «%s» que pot interpretar-se com a una opció de línia " "d'ordres: %s" +#: submodule-config.c #, c-format msgid "Could not update .gitmodules entry %s" msgstr "No s'ha pogut actualitzar l'entrada de .gitmodules %s" +#: submodule.c msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" msgstr "" "No es pot canviar un .gitmodules no fusionat, primer resoleu els conflictes " "de fusió" +#: submodule.c #, c-format msgid "Could not find section in .gitmodules where path=%s" msgstr "No s'ha pogut trobar la secció en .gitmodules on path=%s" +#: submodule.c #, c-format msgid "Could not remove .gitmodules entry for %s" msgstr "No s'ha pogut eliminar l'entrada de .gitmodules per a %s" +#: submodule.c msgid "staging updated .gitmodules failed" msgstr "l'allistament del .gitmodules actualitzat ha fallat" +#: submodule.c #, c-format msgid "in unpopulated submodule '%s'" msgstr "al submòdul sense popular «%s»" +#: submodule.c #, c-format msgid "Pathspec '%s' is in submodule '%.*s'" msgstr "L'especificació «%s» és en el submòdul «%.*s»" +#: submodule.c #, c-format msgid "bad --ignore-submodules argument: %s" msgstr "argument incorrecte --ignore-submodules: %s" +#: submodule.c #, c-format msgid "" "Submodule in commit %s at path: '%s' collides with a submodule named the " @@ -21383,10 +27539,12 @@ msgstr "" "El submòdul en la comissió %s al camí: «%s» col·lideix amb un submòdul amb " "el mateix nom. Ometent-lo." +#: submodule.c #, c-format msgid "submodule entry '%s' (%s) is a %s, not a commit" msgstr "l'entrada del submòdul «%s» (%s) és a %s, no és una comissió" +#: submodule.c #, c-format msgid "" "Could not run 'git rev-list <commits> --not --remotes -n 1' command in " @@ -21395,34 +27553,42 @@ msgstr "" "No s'ha pogut executar l'ordre «git rev-list <commits> --not --remotes -n 1» " "en el submòdul %s" +#: submodule.c #, c-format msgid "process for submodule '%s' failed" msgstr "ha fallat el procés per al submòdul «%s»" +#: submodule.c #, c-format msgid "Pushing submodule '%s'\n" msgstr "S'està pujant el submòdul «%s»\n" +#: submodule.c #, c-format msgid "Unable to push submodule '%s'\n" msgstr "No s'ha pogut pujar el submòdul «%s»\n" +#: submodule.c #, c-format msgid "Fetching submodule %s%s\n" msgstr "S'està obtenint el submòdul %s%s\n" +#: submodule.c #, c-format msgid "Could not access submodule '%s'\n" msgstr "No s'ha pogut accedir al submòdul «%s»\n" +#: submodule.c #, c-format msgid "Could not access submodule '%s' at commit %s\n" msgstr "No s'ha pogut accedir al submòdul «%s» en la comissió %s\n" +#: submodule.c #, c-format msgid "Fetching submodule %s%s at commit %s\n" msgstr "S'està obtenint el submòdul %s%s en la comissió %s\n" +#: submodule.c #, c-format msgid "" "Errors during submodule fetch:\n" @@ -21431,51 +27597,74 @@ msgstr "" "Errors durant l'obtenció de submòduls:\n" "%s" +#: submodule.c #, c-format msgid "'%s' not recognized as a git repository" msgstr "«%s» no reconegut com un repositori git" +#: submodule.c #, c-format msgid "Could not run 'git status --porcelain=2' in submodule %s" msgstr "No s'ha pogut executar «git status --porcelain=2» en el submòdul %s" +#: submodule.c #, c-format msgid "'git status --porcelain=2' failed in submodule %s" msgstr "«git status --porcelain=2» ha fallat en el submòdul %s" +#: submodule.c #, c-format msgid "could not start 'git status' in submodule '%s'" msgstr "no s'ha pogut iniciar «git status» al submòdul «%s»" +#: submodule.c #, c-format msgid "could not run 'git status' in submodule '%s'" msgstr "no s'ha pogut executar «git status» al submòdul «%s»" +#: submodule.c #, c-format msgid "Could not unset core.worktree setting in submodule '%s'" msgstr "" "No s'ha pogut desassignar el paràmetre «core.worktree» al submòdul «%s»" +#: submodule.c #, c-format msgid "could not recurse into submodule '%s'" msgstr "" "s'ha produït un error en cercar recursivament al camí del submòdul «%s»" +#: submodule.c msgid "could not reset submodule index" msgstr "no s'ha pogut restablir l'índex del submòdul" +#: submodule.c #, c-format msgid "submodule '%s' has dirty index" msgstr "el submòdul «%s» té l'índex brut" +#: submodule.c #, c-format msgid "Submodule '%s' could not be updated." msgstr "No s'ha pogut actualitzar el submòdul «%s»." +#: submodule.c #, c-format msgid "submodule git dir '%s' is inside git dir '%.*s'" msgstr "submodule git dir «%s» està dins git dir «%.*s»" +#: submodule.c +#, c-format +msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link" +msgstr "" +"s'esperava que «%.*s» en el camí del submòdul «%s» no fos un enllaç simbòlic" + +#: submodule.c +#, c-format +msgid "expected submodule path '%s' not to be a symbolic link" +msgstr "s'esperava que el camí del submòdul «%s» no fos un enllaç simbòlic" + +#: submodule.c #, c-format msgid "" "relocate_gitdir for submodule '%s' with more than one worktree not supported" @@ -21483,14 +27672,17 @@ msgstr "" "no està admès relocate_gitdir per al submòdul «%s» amb més d'un arbre de " "treball" +#: submodule.c #, c-format msgid "could not lookup name for submodule '%s'" msgstr "no s'ha trobat el nom pel submòdul «%s»" +#: submodule.c #, c-format msgid "refusing to move '%s' into an existing git dir" msgstr "s'ha refusat moure «%s» a un directori git existent" +#: submodule.c #, c-format msgid "" "Migrating git directory of '%s%s' from\n" @@ -21501,150 +27693,186 @@ msgstr "" "«%s» a\n" "«%s»\n" +#: submodule.c msgid "could not start ls-files in .." msgstr "no s'ha pogut iniciar ls-files a .." +#: submodule.c #, c-format msgid "ls-tree returned unexpected return code %d" msgstr "ls-tree ha retornat un codi de retorn %d no esperat" +#: symlinks.c #, c-format msgid "failed to lstat '%s'" msgstr "s'ha produït un error en fer lstat a «%s»" +#: t/helper/test-bundle-uri.c msgid "no remote configured to get bundle URIs from" msgstr "no hi ha cap remot configurat per a obtenir els URI del paquet" -#, c-format -msgid "remote '%s' has no configured URL" -msgstr "el remot «%s» no té cap URL configurat" - +#: t/helper/test-bundle-uri.c msgid "could not get the bundle-uri list" msgstr "no s'ha pogut obtenir la llista bundle-uri" +#: t/helper/test-cache-tree.c msgid "test-tool cache-tree <options> (control|prime|update)" msgstr "test-tool cache-tree <opcions> (control|prime|update)" +#: t/helper/test-cache-tree.c msgid "clear the cache tree before each iteration" msgstr "neteja l'arbre de la memòria cau abans de cada iteració" +#: t/helper/test-cache-tree.c 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)" +#: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" msgstr "la comissió %s no està marcada com abastable" +#: t/helper/test-reach.c msgid "too many commits marked reachable" msgstr "hi ha massa comissions marcades com abastables" +#: t/helper/test-serve-v2.c msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<opcions>]" +#: t/helper/test-serve-v2.c msgid "exit immediately after advertising capabilities" msgstr "surt immediatament després d'anunciar les funcionalitats" +#: t/helper/test-simple-ipc.c msgid "test-helper simple-ipc is-active [<name>] [<options>]" msgstr "test-helper simple-ipc is-active [<nom>] [<opcions>]" +#: t/helper/test-simple-ipc.c msgid "test-helper simple-ipc run-daemon [<name>] [<threads>]" msgstr "test-helper simple-ipc run-daemon [<nom>] [<fils>]" +#: t/helper/test-simple-ipc.c msgid "test-helper simple-ipc start-daemon [<name>] [<threads>] [<max-wait>]" msgstr "test-helper simple-ipc start-daemon [<nom>] [<fils>] [<max-wait>]" +#: t/helper/test-simple-ipc.c msgid "test-helper simple-ipc stop-daemon [<name>] [<max-wait>]" msgstr "test-helper simple-ipc stop-daemon [<nom>] [<max-wait>]" +#: t/helper/test-simple-ipc.c msgid "test-helper simple-ipc send [<name>] [<token>]" msgstr "test-helper simple-ipc send [<nom>] [<testimoni>]" +#: t/helper/test-simple-ipc.c msgid "test-helper simple-ipc sendbytes [<name>] [<bytecount>] [<byte>]" -msgstr "test-helper simple-ipc sendbytes [<nom>] [<bytecount>] [<byte>]" +msgstr "" +"test-helper simple-ipc sendbytes [<nom>] [<recompte-octets>] [<octet>]" +#: t/helper/test-simple-ipc.c msgid "" "test-helper simple-ipc multiple [<name>] [<threads>] [<bytecount>] " "[<batchsize>]" msgstr "" -"test-helper simple-ipc multiple [<nom>] [<fils>] [<bytecount>] " -"[<batchsize>]" +"test-helper simple-ipc multiple [<nom>] [<fils>] [<recompte-octets>] " +"[<mida-lot>]" +#: t/helper/test-simple-ipc.c msgid "name or pathname of unix domain socket" msgstr "nom o nom de camí del sòcol de domini unix" +#: t/helper/test-simple-ipc.c msgid "named-pipe name" msgstr "nom del conducte amb nom" +#: t/helper/test-simple-ipc.c msgid "number of threads in server thread pool" msgstr "nombre de fils en el conjunt de fils del servidor" +#: t/helper/test-simple-ipc.c msgid "seconds to wait for daemon to start or stop" msgstr "segons a esperar que el dimoni comenci o s'aturi" +#: t/helper/test-simple-ipc.c msgid "number of bytes" msgstr "nombre d'octets" +#: t/helper/test-simple-ipc.c msgid "number of requests per thread" msgstr "nombre de peticions per fil" +#: t/helper/test-simple-ipc.c msgid "byte" msgstr "octet" +#: t/helper/test-simple-ipc.c msgid "ballast character" msgstr "caràcter de llast" +#: t/helper/test-simple-ipc.c msgid "token" msgstr "testimoni" +#: t/helper/test-simple-ipc.c msgid "command token to send to the server" msgstr "testimoni d'ordre a enviar al servidor" +#: t/unit-tests/unit-test.c +msgid "unit-test [<options>]" +msgstr "unit-test [<opcions>]" + +#: t/unit-tests/unit-test.c +msgid "immediately exit upon the first failed test" +msgstr "sortir immediatament en fallar el primer test" + +# deixada sense traduir perquè pareix opció i no text +#: t/unit-tests/unit-test.c +msgid "suite[::test]" +msgstr "suite[::test]" + +#: t/unit-tests/unit-test.c +msgid "run only test suite or individual test <suite[::test]>" +msgstr "" +"executa només el conjunt de proves o la prova individual <suite[::test]>" + +#: t/unit-tests/unit-test.c +msgid "suite" +msgstr "suite" + +#: t/unit-tests/unit-test.c +msgid "exclude test suite <suite>" +msgstr "exclou conjunt de proves <conjunt>" + +#: trailer.c #, c-format msgid "running trailer command '%s' failed" msgstr "l'execució de l'ordre «trailer» «%s» ha fallat" +#: trailer.c #, c-format msgid "unknown value '%s' for key '%s'" msgstr "valor desconegut «%s» per a la clau «%s»" +#: trailer.c #, c-format msgid "empty trailer token in trailer '%.*s'" msgstr "testimoni de «trailer» buit en el «trailer» «%.*s»" -#, c-format -msgid "could not read input file '%s'" -msgstr "no s'ha pogut llegir el fitxer d'entrada «%s»" - -#, c-format -msgid "could not stat %s" -msgstr "no s'ha pogut fer stat a %s" - -#, c-format -msgid "file %s is not a regular file" -msgstr "el fitxer %s no és un fitxer regular" - -#, c-format -msgid "file %s is not writable by user" -msgstr "el fitxer %s no és gravable per l'usuari" - -msgid "could not open temporary file" -msgstr "no s'ha pogut obrir el fitxer temporal" - -#, c-format -msgid "could not rename temporary file to %s" -msgstr "no s'ha pogut canviar el nom del fitxer temporal a %s" - +#: transport-helper.c msgid "full write to remote helper failed" msgstr "l'escriptura completa a l'ajudant remot ha fallat" +#: transport-helper.c #, c-format msgid "unable to find remote helper for '%s'" msgstr "no s'ha pogut trobar l'ajudant remot per a «%s»" +#: transport-helper.c msgid "can't dup helper output fd" msgstr "no es pot duplicar la sortida de l'ajudant «fd»" +#: transport-helper.c #, c-format msgid "" "unknown mandatory capability %s; this remote helper probably needs newer " @@ -21653,93 +27881,118 @@ msgstr "" "funcionalitat obligatòria %s desconeguda; aquest ajudant remot probablement " "necessita una versió més nova del Git" +#: transport-helper.c msgid "this remote helper should implement refspec capability" msgstr "aquest ajudant remot ha d'implementar la funcionalitat de refspec" +#: transport-helper.c #, c-format msgid "%s unexpectedly said: '%s'" msgstr "%s ha dit inesperadament «%s»" +#: transport-helper.c #, c-format msgid "%s also locked %s" msgstr "%s també està bloquejat %s" +#: transport-helper.c msgid "couldn't run fast-import" msgstr "no s'ha pogut executar «fast-import»" +#: transport-helper.c msgid "error while running fast-import" msgstr "error en executar la importació ràpida" +#: transport-helper.c #, c-format msgid "could not read ref %s" msgstr "no s'ha pogut llegir la referència %s" +#: transport-helper.c #, c-format msgid "unknown response to connect: %s" msgstr "resposta desconeguda en connectar: %s" +#: transport-helper.c msgid "setting remote service path not supported by protocol" msgstr "el protocol no permet establir el camí del servei remot" +#: transport-helper.c msgid "invalid remote service path" msgstr "el camí del servei remot no és vàlid" +#: transport-helper.c #, c-format msgid "can't connect to subservice %s" msgstr "no es pot connectar al subservei %s" +#: transport-helper.c transport.c msgid "--negotiate-only requires protocol v2" msgstr "--negotiate-only requereix el protocol v2" +#: transport-helper.c msgid "'option' without a matching 'ok/error' directive" msgstr "«option» sense una directiva «ok/error» coincident" +#: transport-helper.c #, c-format msgid "expected ok/error, helper said '%s'" msgstr "s'esperava error/OK, l'ajudant ha dit «%s»" +#: transport-helper.c #, c-format msgid "helper reported unexpected status of %s" msgstr "l'ajudant ha informat d'un estat inesperat de %s" +#: transport-helper.c #, c-format msgid "helper %s does not support dry-run" msgstr "l'ajudant %s no admet dry-run" +#: transport-helper.c #, c-format msgid "helper %s does not support --signed" msgstr "l'ajudant %s no admet --signed" +#: transport-helper.c #, c-format msgid "helper %s does not support --signed=if-asked" msgstr "l'ajudant %s no admet --signed=if-asked" +#: transport-helper.c #, c-format msgid "helper %s does not support --atomic" msgstr "l'ajudant %s no admet --atomic" +#: transport-helper.c #, c-format msgid "helper %s does not support --%s" msgstr "l'ajudant %s no admet --%s" +#: transport-helper.c #, c-format msgid "helper %s does not support 'push-option'" msgstr "l'ajudant %s no admet «push-option»" +#: transport-helper.c msgid "remote-helper doesn't support push; refspec needed" msgstr "" -"remot-helper no permet pujar; es necessiten especificacions de referència" +"remote-helper no permet pujar; es necessiten especificacions de referència" +#: transport-helper.c #, c-format -msgid "helper %s does not support 'force'" -msgstr "l'ajudant %s no admet «force»" +msgid "helper %s does not support '--force'" +msgstr "l'ajudant %s no admet «--force»" +#: transport-helper.c msgid "couldn't run fast-export" msgstr "no s'ha pogut executar l'exportació ràpida" +#: transport-helper.c msgid "error while running fast-export" msgstr "error en executar l'exportació ràpida" +#: transport-helper.c #, c-format msgid "" "No refs in common and none specified; doing nothing.\n" @@ -21748,80 +28001,101 @@ msgstr "" "No hi ha referències en comú i no n'hi ha cap d'especificada.\n" "No es farà res. Potser hauríeu d'especificar una branca.\n" +#: transport-helper.c #, c-format msgid "unsupported object format '%s'" msgstr "format d'objecte no suportat «%s»" +#: transport-helper.c #, c-format msgid "malformed response in ref list: %s" msgstr "resposta mal formada al llistat de referències: %s" +#: transport-helper.c #, c-format msgid "read(%s) failed" msgstr "ha fallat la lectura(%s)" +#: transport-helper.c #, c-format msgid "write(%s) failed" msgstr "ha fallat l'escriptura(%s)" +#: transport-helper.c #, c-format msgid "%s thread failed" msgstr "%s ha fallat el fil" +#: transport-helper.c #, c-format msgid "%s thread failed to join: %s" msgstr "el fil %s no s'ha pogut unir: %s" +#: transport-helper.c #, c-format msgid "can't start thread for copying data: %s" msgstr "no es pot iniciar el fil per a copiar les dades: %s" +#: transport-helper.c #, c-format msgid "%s process failed to wait" msgstr "el procés %s no ha pogut esperar" +#: transport-helper.c #, c-format msgid "%s process failed" msgstr "el procés %s ha fallat" +#: transport-helper.c msgid "can't start thread for copying data" msgstr "no es pot iniciar el fil per a copiar dades" +#: transport.c #, c-format msgid "Would set upstream of '%s' to '%s' of '%s'\n" msgstr "Canviaria la font de «%s» a «%s» de «%s»\n" +#: transport.c #, c-format msgid "could not read bundle '%s'" msgstr "no s'ha pogut llegir el farcell «%s»" +#: transport.c #, c-format msgid "transport: invalid depth option '%s'" msgstr "transport: opció de profunditat no vàlida «%s»" +#: transport.c msgid "see protocol.version in 'git help config' for more details" msgstr "vegeu «protocol.version» a «git help config» per a més detalls" +#: transport.c msgid "server options require protocol version 2 or later" msgstr "les opcions del servidor requereixen el protocol versió 2 o posterior" +#: transport.c msgid "server does not support wait-for-done" msgstr "el servidor no admet «wait-for-done»" +#: transport.c msgid "could not parse transport.color.* config" msgstr "no s'ha pogut analitzar la configuració de transport.color.*" +#: transport.c msgid "support for protocol v2 not implemented yet" msgstr "" "encara no s'ha implementat la compatibilitat amb la versió v2 del protocol" +#: transport.c #, c-format msgid "transport '%s' not allowed" msgstr "no es permet el transport «%s»" +#: transport.c msgid "git-over-rsync is no longer supported" msgstr "git-over-rsync ja no s'admet" +#: transport.c #, c-format msgid "" "The following submodule paths contain changes that can\n" @@ -21830,6 +28104,7 @@ msgstr "" "Els camins de submòdul següents contenen canvis que no\n" "es poden trobar en cap remot:\n" +#: transport.c #, c-format msgid "" "\n" @@ -21855,34 +28130,44 @@ msgstr "" "\n" "per a pujar-los a un remot.\n" +#: transport.c msgid "Aborting." msgstr "S'està avortant." +#: transport.c msgid "failed to push all needed submodules" msgstr "no s'han pogut pujar tots els submòduls necessaris" +#: transport.c msgid "bundle-uri operation not supported by protocol" msgstr "L'operació bundle-uri no és compatible amb el protocol" +#: transport.c msgid "could not retrieve server-advertised bundle-uri list" msgstr "" "no s'ha pogut recuperar la llista de paquets d'URI anunciats pel servidor" +#: transport.c msgid "operation not supported by protocol" msgstr "opció no admesa pel protocol" +#: tree-walk.c msgid "too-short tree object" msgstr "objecte d'arbre massa curt" +#: tree-walk.c msgid "malformed mode in tree entry" msgstr "mode mal format en entrada d'arbre" +#: tree-walk.c msgid "empty filename in tree entry" msgstr "nom de fitxer buit en una entrada d'arbre" +#: tree-walk.c msgid "too-short tree file" msgstr "fitxer d'arbre massa curt" +#: unpack-trees.c #, c-format msgid "" "Your local changes to the following files would be overwritten by checkout:\n" @@ -21891,6 +28176,7 @@ msgstr "" "Els canvis locals als fitxers següents se sobreescriurien per a agafar:\n" "%%sCometeu els vostres canvis o feu «stash» abans de canviar de branca." +#: unpack-trees.c #, c-format msgid "" "Your local changes to the following files would be overwritten by checkout:\n" @@ -21899,6 +28185,7 @@ msgstr "" "Els canvis locals als fitxers següents se sobreescriurien per a agafar:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -21907,6 +28194,7 @@ msgstr "" "Els canvis locals als fitxers següents se sobreescriurien per a fusionar:\n" "%%sCometeu els vostres canvis o feu «stash» abans de fusionar." +#: unpack-trees.c #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -21915,6 +28203,7 @@ msgstr "" "Els canvis locals als fitxers següents se sobreescriurien per a fusionar:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" @@ -21923,6 +28212,7 @@ msgstr "" "Els vostres canvis locals als fitxers següents se sobreescriurien per %s:\n" "%%sCometeu els vostres canvis o feu «stash» abans de %s." +#: unpack-trees.c #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" @@ -21931,6 +28221,7 @@ msgstr "" "Els vostres canvis locals als fitxers següents se sobreescriurien per %s:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "Updating the following directories would lose untracked files in them:\n" @@ -21939,6 +28230,7 @@ msgstr "" "En actualitzar els directoris següents perdria fitxers no seguits en el:\n" "%s" +#: unpack-trees.c #, c-format msgid "" "Refusing to remove the current working directory:\n" @@ -21947,6 +28239,7 @@ msgstr "" "S'ha rebutjat suprimir el directori de treball actual:\n" "%s" +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be removed by checkout:\n" @@ -21956,6 +28249,7 @@ msgstr "" "agafar:\n" "%%sMoveu-los o elimineu-los abans de canviar de branca." +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be removed by checkout:\n" @@ -21965,6 +28259,7 @@ msgstr "" "agafar:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be removed by merge:\n" @@ -21974,6 +28269,7 @@ msgstr "" "fusionar:\n" "%%sMoveu-los o elimineu-los abans de fusionar." +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be removed by merge:\n" @@ -21983,6 +28279,7 @@ msgstr "" "fusionar:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" @@ -21991,6 +28288,7 @@ msgstr "" "Els següents fitxers no seguits en l'arbre de treball s'eliminarien per %s:\n" "%%sMoveu-los o elimineu-los abans de %s." +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" @@ -21999,6 +28297,7 @@ msgstr "" "Els següents fitxers no seguits en l'arbre de treball s'eliminarien per %s:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be overwritten by " @@ -22009,6 +28308,7 @@ msgstr "" "a agafar:\n" "%%sMoveu-los o elimineu-los abans de canviar de branca." +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be overwritten by " @@ -22019,6 +28319,7 @@ msgstr "" "a agafar:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be overwritten by merge:\n" @@ -22028,6 +28329,7 @@ msgstr "" "a fusionar:\n" "%%sMoveu-los o elimineu-los abans de fusionar." +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be overwritten by merge:\n" @@ -22037,6 +28339,7 @@ msgstr "" "a fusionar:\n" "%%s" +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" @@ -22046,6 +28349,7 @@ msgstr "" "%s:\n" "%%sMoveu-los o elimineu-los abans de %s." +#: unpack-trees.c #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" @@ -22055,10 +28359,12 @@ msgstr "" "%s:\n" "%%s" +#: unpack-trees.c #, c-format msgid "Entry '%s' overlaps with '%s'. Cannot bind." msgstr "L'entrada «%s» encavalca amb «%s». No es pot vincular." +#: unpack-trees.c #, c-format msgid "" "Cannot update submodule:\n" @@ -22067,6 +28373,7 @@ msgstr "" "No es pot actualitzar el submòdul:\n" "%s" +#: unpack-trees.c #, c-format msgid "" "The following paths are not up to date and were left despite sparse " @@ -22077,6 +28384,7 @@ msgstr "" "patrons dispersos:\n" "%s" +#: unpack-trees.c #, c-format msgid "" "The following paths are unmerged and were left despite sparse patterns:\n" @@ -22086,6 +28394,7 @@ msgstr "" "dispersos:\n" "%s" +#: unpack-trees.c #, c-format msgid "" "The following paths were already present and thus not updated despite sparse " @@ -22096,10 +28405,12 @@ msgstr "" "malgrat els patrons dispersos.:\n" "%s" +#: unpack-trees.c #, c-format msgid "Aborting\n" msgstr "S'està avortant\n" +#: unpack-trees.c #, c-format msgid "" "After fixing the above paths, you may want to run `git sparse-checkout " @@ -22108,9 +28419,11 @@ msgstr "" "Després de corregir els camins anteriors és possible que vulgueu executar " "«git sparse-checkout reapply».\n" +#: unpack-trees.c msgid "Updating files" msgstr "S'estan actualitzant els fitxers" +#: unpack-trees.c msgid "" "the following paths have collided (e.g. case-sensitive paths\n" "on a case-insensitive filesystem) and only one from the same\n" @@ -22121,273 +28434,358 @@ msgstr "" "minúscules). Només un camí del mateix grup de col·lisió es troba a l'arbre\n" "de treball:\n" +#: unpack-trees.c msgid "Updating index flags" msgstr "Actualitzant els indicadors d'índex" +#: unpack-trees.c #, c-format msgid "worktree and untracked commit have duplicate entries: %s" msgstr "" "l'arbre de treball i la comissió no seguida tenen entrades duplicades: %s" +#: upload-pack.c msgid "expected flush after fetch arguments" msgstr "s'esperava una neteja després dels arguments del «fetch»" +#: urlmatch.c msgid "invalid URL scheme name or missing '://' suffix" msgstr "l'esquema d'URL no és vàlid o li manca el sufix «://»" +#: urlmatch.c #, c-format msgid "invalid %XX escape sequence" msgstr "seqüència d'escapament %XX no vàlida" +#: urlmatch.c msgid "missing host and scheme is not 'file:'" msgstr "manca la màquina i l'esquema no és «file:»" +#: urlmatch.c msgid "a 'file:' URL may not have a port number" msgstr "un URL «file:» no pot tenir número de port" +#: urlmatch.c msgid "invalid characters in host name" msgstr "hi ha caràcters no vàlids en el nom de màquina" +#: urlmatch.c msgid "invalid port number" msgstr "número de port no vàlid" +#: urlmatch.c msgid "invalid '..' path segment" msgstr "segment de camí «..» no vàlid" +#: usage.c +#, c-format +msgid "error: unable to format message: %s\n" +msgstr "error: no s'ha pogut formatar el missatge: %s\n" + +#: usage.c msgid "usage: " msgstr "ús: " +#: usage.c msgid "fatal: " msgstr "fatal: " +#: usage.c msgid "error: " msgstr "error: " +#: usage.c msgid "warning: " msgstr "avís: " +#: walker.c msgid "Fetching objects" msgstr "S'estan obtenint objectes" +#: worktree.c #, c-format msgid "'%s' at main working tree is not the repository directory" msgstr "«%s» a l'arbre de treball principal no és al directori del repositori" +#: worktree.c #, c-format msgid "'%s' file does not contain absolute path to the working tree location" msgstr "" "El fitxer «%s» no conté el camí absolut a la ubicació de l'arbre de treball" +#: worktree.c #, c-format msgid "'%s' is not a .git file, error code %d" msgstr "«%s» no és un fitxer .git, codi d'error %d" +#: worktree.c #, c-format msgid "'%s' does not point back to '%s'" msgstr "«%s» no assenyala de tornada a «%s»" +#: worktree.c msgid "not a directory" msgstr "no és en un directori" +#: worktree.c msgid ".git is not a file" msgstr ".git no és un fitxer" +#: worktree.c msgid ".git file broken" msgstr "fitxer .git malmès" +#: worktree.c msgid ".git file incorrect" msgstr "fitxer .git incorrecte" +#: worktree.c msgid "not a valid path" msgstr "no és un camí vàlid" +#: worktree.c msgid "unable to locate repository; .git is not a file" msgstr "no s'ha pogut trobar el repositori; .git no és un fitxer" +#: worktree.c msgid "unable to locate repository; .git file does not reference a repository" msgstr "" "no s'ha pogut trobar el repositori; el fitxer .git no fa referència a un " "repositori" +#: worktree.c msgid "unable to locate repository; .git file broken" msgstr "no s'ha pogut trobar el repositori; el fitxer .git està malmès" +#: worktree.c msgid "gitdir unreadable" msgstr "gitdir illegible" +#: worktree.c msgid "gitdir incorrect" msgstr "gitdir incorrecte" +#: worktree.c msgid "not a valid directory" msgstr "no és en un directori vàlid" +#: worktree.c msgid "gitdir file does not exist" msgstr "el fitxer gitdir no existeix" +#: worktree.c #, c-format msgid "unable to read gitdir file (%s)" msgstr "no s'ha pogut llegir el fitxer gitdir (%s)" +#: worktree.c #, c-format msgid "short read (expected %<PRIuMAX> bytes, read %<PRIuMAX>)" -msgstr "lectura curta (s'esperaven %<PRIuMAX> bytes, llegits %<PRIuMAX>)" +msgstr "lectura curta (s'esperaven %<PRIuMAX> octets, s'han llegit %<PRIuMAX>)" +#: worktree.c msgid "invalid gitdir file" msgstr "fitxer gitdir no vàlid" +#: worktree.c msgid "gitdir file points to non-existent location" msgstr "el fitxer gitdir indica una ubicació no existent" +#: worktree.c #, c-format msgid "unable to set %s in '%s'" msgstr "no s'han pogut establir %s en «%s»" +#: worktree.c #, c-format msgid "unable to unset %s in '%s'" msgstr "no s'ha pogut desassignar %s en «%s»" +#: worktree.c msgid "failed to set extensions.worktreeConfig setting" msgstr "no s'ha pogut establir el paràmetre extensions.worktreeConfig" +#: wrapper.c #, c-format msgid "could not setenv '%s'" msgstr "no s'ha pogut fer setenv «%s»" +#: wrapper.c #, c-format msgid "unable to create '%s'" msgstr "no s'ha pogut crear «%s»" +#: wrapper.c #, c-format msgid "could not open '%s' for reading and writing" msgstr "no s'ha pogut obrir «%s» per a lectura i escriptura" +#: wrapper.c #, c-format msgid "unable to access '%s'" msgstr "no s'ha pogut accedir a «%s»" +#: wrapper.c msgid "unable to get current working directory" msgstr "no s'ha pogut obtenir el directori de treball actual" +#: wrapper.c msgid "unable to get random bytes" -msgstr "no s'han pogut obtenir bytes aleatoris" +msgstr "no s'han pogut obtenir octets aleatoris" +#: wt-status.c msgid "Unmerged paths:" msgstr "Camins sense fusionar:" +#: wt-status.c msgid " (use \"git restore --staged <file>...\" to unstage)" msgstr " (useu «git restore --staged <fitxer>...» per a fer «unstage»)" +#: wt-status.c #, c-format msgid " (use \"git restore --source=%s --staged <file>...\" to unstage)" msgstr "" " (useu «git restore --source=%s --staged <fitxer>...» per a fer «unstage»)" +#: wt-status.c msgid " (use \"git rm --cached <file>...\" to unstage)" msgstr " (useu «git rm --cached <fitxer>...» per a fer «unstage»)" +#: wt-status.c msgid " (use \"git add <file>...\" to mark resolution)" msgstr " (useu «git add <fitxer>...» per a senyalar resolució)" +#: wt-status.c msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)" msgstr "" " (useu «git add/rm <fitxer>...» segons sigui apropiat per a senyalar " "resolució)" +#: wt-status.c msgid " (use \"git rm <file>...\" to mark resolution)" msgstr " (useu «git rm <fitxer>...» per a senyalar resolució)" +#: wt-status.c msgid "Changes to be committed:" msgstr "Canvis a cometre:" +#: wt-status.c msgid "Changes not staged for commit:" msgstr "Canvis no «staged» per a cometre:" +#: wt-status.c msgid " (use \"git add <file>...\" to update what will be committed)" msgstr " (useu «git add <fitxer>...» per a actualitzar què es cometrà)" +#: wt-status.c msgid " (use \"git add/rm <file>...\" to update what will be committed)" msgstr " (useu «git add/rm <fitxer>...» per a actualitzar què es cometrà)" +#: wt-status.c msgid "" " (use \"git restore <file>...\" to discard changes in working directory)" msgstr "" " (useu «git restore <fitxer>...» per a descartar canvis en el directori de " "treball)" +#: wt-status.c msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" " (cometeu o descarteu el contingut modificat o no seguit en els submòduls)" +#: wt-status.c #, c-format msgid " (use \"git %s <file>...\" to include in what will be committed)" msgstr " (useu «git %s <fitxer>...» per a incloure'ls en la comissió)" +#: wt-status.c msgid "both deleted:" msgstr "suprimit per ambdós:" +#: wt-status.c msgid "added by us:" msgstr "afegit per nosaltres:" +#: wt-status.c msgid "deleted by them:" msgstr "suprimit per ells:" +#: wt-status.c msgid "added by them:" msgstr "afegit per ells:" +#: wt-status.c msgid "deleted by us:" msgstr "suprimit per nosaltres:" +#: wt-status.c msgid "both added:" msgstr "afegit per ambdós:" +#: wt-status.c msgid "both modified:" msgstr "modificat per ambdós:" +#: wt-status.c msgid "new file:" msgstr "fitxer nou:" +#: wt-status.c msgid "copied:" msgstr "copiat:" +#: wt-status.c msgid "deleted:" msgstr "suprimit:" +#: wt-status.c msgid "modified:" msgstr "modificat:" +#: wt-status.c msgid "renamed:" msgstr "canviat de nom:" +#: wt-status.c msgid "typechange:" msgstr "canviat de tipus:" +#: wt-status.c msgid "unknown:" msgstr "desconegut:" +#: wt-status.c msgid "unmerged:" msgstr "sense fusionar:" +#: wt-status.c msgid "new commits, " msgstr "comissions noves, " +#: wt-status.c msgid "modified content, " msgstr "contingut modificat, " +#: wt-status.c msgid "untracked content, " msgstr "contingut no seguit, " +#: wt-status.c #, c-format msgid "Your stash currently has %d entry" msgid_plural "Your stash currently has %d entries" msgstr[0] "L'«stash» té actualment %d entrada" msgstr[1] "L'«stash» té actualment %d entrades" +#: wt-status.c msgid "Submodules changed but not updated:" msgstr "Submòduls canviats però no actualitzats:" +#: wt-status.c msgid "Submodule changes to be committed:" msgstr "Canvis de submòdul a cometre:" +#: wt-status.c msgid "" "Do not modify or remove the line above.\n" "Everything below it will be ignored." @@ -22395,6 +28793,7 @@ msgstr "" "No modifiqueu ni elimineu la línia de dalt.\n" "Tot el que hi ha a sota s'ignorarà." +#: wt-status.c #, c-format msgid "" "\n" @@ -22406,90 +28805,115 @@ msgstr "" "darrere.\n" "Podeu utilitzar «--no-ahead-behind» per a evitar-ho.\n" +#: wt-status.c msgid "You have unmerged paths." msgstr "Teniu camins sense fusionar." +#: wt-status.c msgid " (fix conflicts and run \"git commit\")" msgstr " (arregleu els conflictes i executeu «git commit»)" +#: wt-status.c msgid " (use \"git merge --abort\" to abort the merge)" msgstr " (useu «git merge --abort» per a avortar la fusió)" +#: wt-status.c msgid "All conflicts fixed but you are still merging." msgstr "Tots els conflictes estan arreglats però encara esteu fusionant." +#: wt-status.c msgid " (use \"git commit\" to conclude merge)" msgstr " (useu «git commit» per a concloure la fusió)" +#: wt-status.c msgid "You are in the middle of an am session." msgstr "Esteu enmig d'una sessió am." +#: wt-status.c msgid "The current patch is empty." msgstr "El pedaç actual està buit." +#: wt-status.c msgid " (fix conflicts and then run \"git am --continue\")" msgstr " (arregleu els conflictes i després executeu «git am --continue»)" +#: wt-status.c msgid " (use \"git am --skip\" to skip this patch)" msgstr " (useu «git am --skip» per a ometre aquest pedaç)" +#: wt-status.c msgid "" " (use \"git am --allow-empty\" to record this patch as an empty commit)" msgstr "" " (useu «git am --allow-empty» per a enregistrar aquest pedaç com una " "comissió buida)" +#: wt-status.c msgid " (use \"git am --abort\" to restore the original branch)" msgstr " (useu «git am --abort» per a restaurar la branca original)" +#: wt-status.c msgid "git-rebase-todo is missing." msgstr "Manca git-rebase-todo." +#: wt-status.c msgid "No commands done." msgstr "No s'ha fet cap ordre." +#: wt-status.c #, c-format msgid "Last command done (%<PRIuMAX> command done):" msgid_plural "Last commands done (%<PRIuMAX> commands done):" msgstr[0] "Darrera ordre acabada (%<PRIuMAX> ordre acabada):" msgstr[1] "Darreres ordres acabades (%<PRIuMAX> ordres acabades):" +#: wt-status.c #, c-format msgid " (see more in file %s)" msgstr " (vegeu més en el fitxer %s)" +#: wt-status.c msgid "No commands remaining." msgstr "No manca cap ordre." +#: wt-status.c #, c-format msgid "Next command to do (%<PRIuMAX> remaining command):" msgid_plural "Next commands to do (%<PRIuMAX> remaining commands):" msgstr[0] "Següent ordre a fer (%<PRIuMAX> ordre restant):" msgstr[1] "Següents ordres a fer (%<PRIuMAX> ordres restants):" +#: wt-status.c msgid " (use \"git rebase --edit-todo\" to view and edit)" msgstr " (useu «git rebase --edit-todo» per a veure i editar)" +#: wt-status.c #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "Actualment esteu fent «rebase» de la branca «%s» en «%s»." +#: wt-status.c msgid "You are currently rebasing." msgstr "Actualment esteu fent «rebase»." +#: wt-status.c msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr " (arregleu els conflictes i després executeu «git rebase --continue»)" +#: wt-status.c msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (useu «git rebase --skip» per a ometre aquest pedaç)" +#: wt-status.c msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr " (useu «git rebase --abort» per a agafar la branca original)" +#: wt-status.c msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr "" " (tots els conflictes estan arreglats: executeu «git rebase --continue»)" +#: wt-status.c #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." @@ -22497,128 +28921,164 @@ msgstr "" "Actualment esteu dividint una comissió mentre es fa «rebase» de la branca " "«%s» en «%s»." +#: wt-status.c msgid "You are currently splitting a commit during a rebase." msgstr "Actualment esteu dividint una comissió durant un «rebase»." +#: wt-status.c msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" " (Una vegada que el vostre directori de treball sigui net, executeu «git " "rebase --continue»)" +#: wt-status.c #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "Actualment esteu editant una comissió mentre es fa «rebase» de la branca " "«%s» en «%s»." +#: wt-status.c msgid "You are currently editing a commit during a rebase." msgstr "Actualment esteu editant una comissió durant un «rebase»." +#: wt-status.c msgid " (use \"git commit --amend\" to amend the current commit)" msgstr " (useu «git commit --amend» per a esmenar la comissió actual)" +#: wt-status.c msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" " (useu «git rebase --continue» una vegada que estigueu satisfet amb els " "vostres canvis)" +#: wt-status.c msgid "Cherry-pick currently in progress." msgstr "Hi ha «cherry pick» actualment en curs." +#: wt-status.c #, c-format msgid "You are currently cherry-picking commit %s." msgstr "Actualment esteu fent «cherry pick» a la comissió %s." +#: wt-status.c msgid " (fix conflicts and run \"git cherry-pick --continue\")" msgstr " (arregleu els conflictes i executeu «git cherry-pick --continue»)" +#: wt-status.c msgid " (run \"git cherry-pick --continue\" to continue)" msgstr " (executeu «git cherry-pick --continue» per a continuar)" +#: wt-status.c msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" msgstr "" " (tots els conflictes estan arreglats: executeu «git cherry-pick --" "continue»)" +#: wt-status.c msgid " (use \"git cherry-pick --skip\" to skip this patch)" msgstr " (useu «git cherry-pick --skip» per a ometre aquest pedaç)" +#: wt-status.c msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" msgstr "" " (useu «git cherry-pick --abort» per a cancel·lar l'operació de «cherry " "pick»)" +#: wt-status.c msgid "Revert currently in progress." msgstr "Una reversió està actualment en curs." +#: wt-status.c #, c-format msgid "You are currently reverting commit %s." msgstr "Actualment esteu revertint la comissió %s." +#: wt-status.c msgid " (fix conflicts and run \"git revert --continue\")" msgstr " (arregleu els conflictes i executeu «git revert --continue»)" +#: wt-status.c msgid " (run \"git revert --continue\" to continue)" msgstr " (executeu «git revert --continue» per a continuar)" +#: wt-status.c msgid " (all conflicts fixed: run \"git revert --continue\")" msgstr "" " (tots els conflictes estan arreglats: executeu «git revert --continue»)" +#: wt-status.c msgid " (use \"git revert --skip\" to skip this patch)" msgstr " (useu «git revert --skip» per a ometre aquest pedaç)" +#: wt-status.c msgid " (use \"git revert --abort\" to cancel the revert operation)" msgstr " (useu «git revert --abort» per a cancel·lar l'operació de reversió)" +#: wt-status.c #, c-format msgid "You are currently bisecting, started from branch '%s'." msgstr "Actualment esteu bisecant, heu començat des de la branca «%s»." +#: wt-status.c msgid "You are currently bisecting." msgstr "Actualment esteu bisecant." +#: wt-status.c msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr " (useu «git bisect reset» per a tornar a la branca original)" +#: wt-status.c msgid "You are in a sparse checkout." msgstr "Esteu en un «sparse-checkout»." +#: wt-status.c #, c-format msgid "You are in a sparse checkout with %d%% of tracked files present." msgstr "Esteu en un «sparse-checkout» amb un %d%% de fitxers seguits presents." +#: wt-status.c msgid "On branch " msgstr "En la branca " +#: wt-status.c msgid "interactive rebase in progress; onto " msgstr "«rebase» interactiu en curs; sobre " +#: wt-status.c msgid "rebase in progress; onto " msgstr "«rebase» en curs; sobre " +#: wt-status.c msgid "HEAD detached at " msgstr "HEAD separat a " +#: wt-status.c msgid "HEAD detached from " msgstr "HEAD separat des de " +#: wt-status.c msgid "Not currently on any branch." msgstr "Actualment no s'és en cap branca." +#: wt-status.c msgid "Initial commit" msgstr "Comissió inicial" +#: wt-status.c msgid "No commits yet" msgstr "No s'ha fet cap comissió encara" +#: wt-status.c msgid "Untracked files" msgstr "Fitxers no seguits" +#: wt-status.c msgid "Ignored files" msgstr "Fitxers ignorats" +#: wt-status.c #, c-format msgid "" "It took %.2f seconds to enumerate untracked files,\n" @@ -22628,32 +29088,40 @@ msgstr "" "però els resultats es van emmagatzemar a la memòria cau, i les\n" "execucions posteriors podrien ser més ràpides." +#: wt-status.c #, c-format msgid "It took %.2f seconds to enumerate untracked files." msgstr "S'han trigat %.2f segons a enumerar els fitxers sense seguiment." +#: wt-status.c msgid "See 'git help status' for information on how to improve this." msgstr "" "Vegeu «git help status» per a obtenir informació sobre com millorar-ho." +#: wt-status.c #, c-format msgid "Untracked files not listed%s" msgstr "Els fitxers no seguits no estan llistats%s" +#: wt-status.c msgid " (use -u option to show untracked files)" msgstr " (useu l'opció -u per a mostrar els fitxers no seguits)" +#: wt-status.c msgid "No changes" msgstr "Sense canvis" +#: wt-status.c #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "no hi ha canvis afegits a cometre (useu «git add» o «git commit -a»)\n" +#: wt-status.c #, c-format msgid "no changes added to commit\n" msgstr "no hi ha canvis afegits a cometre\n" +#: wt-status.c #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -22662,60 +29130,75 @@ msgstr "" "no hi ha res afegit a cometre però hi ha fitxers no seguits (useu «git add» " "per a seguir-los)\n" +#: wt-status.c #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "no hi ha res afegit a cometre però hi ha fitxers no seguits\n" +#: wt-status.c #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" "no hi ha res a cometre (creeu/copieu fitxers i useu «git add» per a seguir-" "los)\n" +#: wt-status.c #, c-format msgid "nothing to commit\n" msgstr "no hi ha res a cometre\n" +#: wt-status.c #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" "no hi ha res a cometre (useu -u per a mostrar els fitxers no seguits)\n" +#: wt-status.c #, c-format msgid "nothing to commit, working tree clean\n" msgstr "no hi ha res a cometre, l'arbre de treball està net\n" +#: wt-status.c msgid "No commits yet on " msgstr "No s'ha fet cap comissió encara a " +#: wt-status.c msgid "HEAD (no branch)" msgstr "HEAD (sense branca)" +#: wt-status.c msgid "different" msgstr "diferent" +#: wt-status.c msgid "behind " msgstr "darrere " +#: wt-status.c msgid "ahead " msgstr "davant per " #. TRANSLATORS: the action is e.g. "pull with rebase" +#: wt-status.c #, c-format msgid "cannot %s: You have unstaged changes." msgstr "no es pot %s: Teniu canvis «unstaged»." +#: wt-status.c msgid "additionally, your index contains uncommitted changes." msgstr "addicionalment, el vostre índex conté canvis sense cometre." +#: wt-status.c #, c-format msgid "cannot %s: Your index contains uncommitted changes." msgstr "no es pot %s: El vostre índex conté canvis sense cometre." +#: xdiff-interface.c #, c-format msgid "unknown style '%s' given for '%s'" msgstr "estil desconegut «%s» donat per a «%s»" +#: git-merge-octopus.sh git-merge-resolve.sh msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" @@ -22723,92 +29206,120 @@ msgstr "" "Error: Els vostres canvis locals als fitxers següents se sobreescriurien per " "a fusionar" +#: git-merge-octopus.sh msgid "Automated merge did not work." msgstr "La fusió automàtica no ha funcionat." +#: git-merge-octopus.sh msgid "Should not be doing an octopus." msgstr "No s'ha de fer un «octopus»." +#: git-merge-octopus.sh #, sh-format msgid "Unable to find common commit with $pretty_name" msgstr "No s'ha pogut trobar cap comissió en comú amb $pretty_name" +#: git-merge-octopus.sh #, sh-format msgid "Already up to date with $pretty_name" msgstr "Ja està al dia amb $pretty_name" +#: git-merge-octopus.sh #, sh-format msgid "Fast-forwarding to: $pretty_name" msgstr "S'està avançant ràpidament a: $pretty_name" +#: git-merge-octopus.sh #, sh-format msgid "Trying simple merge with $pretty_name" msgstr "S'està intentant una fusió simple amb $pretty_name" +#: git-merge-octopus.sh msgid "Simple merge did not work, trying automatic merge." msgstr "" "La fusió simple no ha funcionat, s'està intentant una fusió automàtica." +#: git-sh-setup.sh #, sh-format msgid "usage: $dashless $USAGE" msgstr "ús: $dashless $USAGE" +#: git-sh-setup.sh #, sh-format msgid "Cannot chdir to $cdup, the toplevel of the working tree" msgstr "" "No es pot canviar de directori a $cdup, el nivell superior de l'arbre de " "treball" +#: git-sh-setup.sh #, sh-format msgid "fatal: $program_name cannot be used without a working tree." msgstr "fatal: no es pot usar $program_name sense un arbre de treball." +#: git-sh-setup.sh msgid "Cannot rewrite branches: You have unstaged changes." msgstr "No es poden reescriure branques: Teniu canvis «unstaged»." +#: git-sh-setup.sh #, sh-format msgid "Cannot $action: You have unstaged changes." msgstr "No es pot $action: Teniu canvis «unstaged»." +#: git-sh-setup.sh #, sh-format msgid "Cannot $action: Your index contains uncommitted changes." msgstr "No es pot $action: El vostre índex conté canvis sense cometre." +#: git-sh-setup.sh msgid "Additionally, your index contains uncommitted changes." msgstr "Addicionalment, el vostre índex conté canvis sense cometre." +#: git-sh-setup.sh msgid "You need to run this command from the toplevel of the working tree." msgstr "" "Heu d'executar aquesta ordre des del nivell superior de l'arbre de treball." +#: git-sh-setup.sh msgid "Unable to determine absolute path of git directory" msgstr "No s'ha pogut determinar el camí absolut del directori de git" +#: git-send-email.perl msgid "local zone differs from GMT by a non-minute interval\n" msgstr "la zona local difereix de GMT per un interval que no és de minuts\n" +#: git-send-email.perl msgid "local time offset greater than or equal to 24 hours\n" msgstr "el desplaçament de la zona local és més gran o igual a 24 hores\n" +#: git-send-email.perl #, perl-format msgid "fatal: command '%s' died with exit code %d" msgstr "fatal: l'ordre «%s» ha mort amb el codi de sortida %d" +#: git-send-email.perl msgid "the editor exited uncleanly, aborting everything" msgstr "l'editor no ha sortit correctament, avortant-ho tot" +#: git-send-email.perl #, perl-format msgid "" "'%s' contains an intermediate version of the email you were composing.\n" msgstr "«%s» conté una versió intermèdia del correu que estàveu redactant.\n" +#: git-send-email.perl #, perl-format msgid "'%s.final' contains the composed email.\n" msgstr "«%s.final» conté el correu redactat.\n" +#: git-send-email.perl msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases és incompatible amb altres opcions\n" +#: git-send-email.perl +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases i --translate-aliases s'exclouen mútuament\n" + +#: git-send-email.perl msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -22819,9 +29330,11 @@ msgstr "" "la «e». Establiu sendemail.forbidSendmailVariables a false per a desactivar\n" "la comprovació.\n" +#: git-send-email.perl msgid "Cannot run git format-patch from outside a repository\n" msgstr "No es pot executar git format-patch des de fora del repositori\n" +#: git-send-email.perl msgid "" "`batch-size` and `relogin` must be specified together (via command-line or " "configuration option)\n" @@ -22829,30 +29342,37 @@ msgstr "" "«batch-size» i «relogin» s'han d'especificar junts (a través de la línia " "d'ordres o l'opció de configuració)\n" +#: git-send-email.perl #, perl-format msgid "Unknown --suppress-cc field: '%s'\n" msgstr "Camp --suppress-cc desconegut: «%s»\n" +#: git-send-email.perl #, perl-format msgid "Unknown --confirm setting: '%s'\n" msgstr "Paràmetre --confirm desconegut: «%s»\n" +#: git-send-email.perl #, perl-format msgid "warning: sendmail alias with quotes is not supported: %s\n" msgstr "avís: no s'admet l'àlies de sendmail amb cometes: %s\n" +#: git-send-email.perl #, perl-format msgid "warning: `:include:` not supported: %s\n" msgstr "avís: «:include:» no s'admet: %s\n" +#: git-send-email.perl #, perl-format msgid "warning: `/file` or `|pipe` redirection not supported: %s\n" msgstr "avís: les redireccions «/file» ni «|pipe» no s'admeten: %s\n" +#: git-send-email.perl #, perl-format msgid "warning: sendmail line is not recognized: %s\n" msgstr "avís: no es pot reconèixer la línia sendmail: %s\n" +#: git-send-email.perl #, perl-format msgid "" "File '%s' exists but it could also be the range of commits\n" @@ -22867,10 +29387,12 @@ msgstr "" " * Dient «./%s» si volíeu especificar un fitxer; o\n" " * Proporcionant l'opció «--format-patch» si volíeu especificar un rang.\n" +#: git-send-email.perl #, perl-format msgid "Failed to opendir %s: %s" msgstr "S'ha produït un error en obrir el directori %s: %s" +#: git-send-email.perl msgid "" "\n" "No patch files specified!\n" @@ -22880,14 +29402,17 @@ msgstr "" "No s'han especificat fitxers de pedaç\n" "\n" +#: git-send-email.perl #, perl-format msgid "No subject line in %s?" msgstr "Sense assumpte a %s?" +#: git-send-email.perl #, perl-format msgid "Failed to open for writing %s: %s" msgstr "S'ha produït un error en obrir per escriptura %s: %s" +#: git-send-email.perl msgid "" "Lines beginning in \"GIT:\" will be removed.\n" "Consider including an overall diffstat or table of contents\n" @@ -22901,22 +29426,27 @@ msgstr "" "\n" "Esborreu el contingut del cos si no voleu enviar cap resum.\n" +#: git-send-email.perl #, perl-format msgid "Failed to open %s.final: %s" msgstr "S'ha produït un error en obrir %s.final: %s" +#: git-send-email.perl #, perl-format msgid "Failed to open %s: %s" msgstr "S'ha produït un error en obrir %s: %s" +#: git-send-email.perl msgid "Summary email is empty, skipping it\n" msgstr "El correu electrònic de resum està buit, s'omet\n" #. TRANSLATORS: please keep [y/N] as is. +#: git-send-email.perl #, perl-format msgid "Are you sure you want to use <%s> [y/N]? " msgstr "Esteu segur que voleu usar <%s> [y/N]? " +#: git-send-email.perl msgid "" "The following files are 8bit, but do not declare a Content-Transfer-" "Encoding.\n" @@ -22924,9 +29454,11 @@ msgstr "" "Els fitxers següents són 8bit, però no declaren un Content-Transfer-" "Encoding.\n" +#: git-send-email.perl msgid "Which 8bit encoding should I declare [UTF-8]? " msgstr "Quina codificació de 8 bits hauria de declarar [UTF-8]? " +#: git-send-email.perl #, perl-format msgid "" "Refusing to send because the patch\n" @@ -22939,19 +29471,23 @@ msgstr "" "perquè la plantilla té l'assumpte «*** SUBJECT HERE ***». Passeu --force si " "realment voleu enviar-ho.\n" +#: git-send-email.perl msgid "To whom should the emails be sent (if anyone)?" msgstr "" "A qui s'haurien d'enviar els correus electrònics (si s'han d'enviar a algú)?" +#: git-send-email.perl #, perl-format msgid "fatal: alias '%s' expands to itself\n" msgstr "fatal: l'àlies «%s» s'expandeix a si mateix\n" +#: git-send-email.perl msgid "Message-ID to be used as In-Reply-To for the first email (if any)? " msgstr "" "S'ha d'usar el Message-ID com a In-Reply-To pel primer correu (si n'hi ha " "cap)? " +#: git-send-email.perl #, perl-format msgid "error: unable to extract a valid address from: %s\n" msgstr "error: no s'ha pogut extreure una adreça vàlida de: %s\n" @@ -22959,13 +29495,16 @@ msgstr "error: no s'ha pogut extreure una adreça vàlida de: %s\n" #. TRANSLATORS: Make sure to include [q] [d] [e] in your #. translation. The program will only accept English input #. at this point. +#: git-send-email.perl msgid "What to do with this address? ([q]uit|[d]rop|[e]dit): " msgstr "Què cal fer amb aquesta adreça? ([q]surt|[d]escarta|[e]dita): " +#: git-send-email.perl #, perl-format msgid "CA path \"%s\" does not exist" msgstr "el camí CA «%s» no existeix" +#: git-send-email.perl msgid "" " The Cc list above has been expanded by additional\n" " addresses found in the patch commit message. By default\n" @@ -22992,95 +29531,121 @@ msgstr "" #. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your #. translation. The program will only accept English input #. at this point. +#: git-send-email.perl msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): " msgstr "" "Voleu enviar aquest correu electrònic? ([y]sí|[n]o|[e]dita|[q]surt|[a]tot): " +#: git-send-email.perl msgid "Send this email reply required" msgstr "Requereix resposta en enviar el correu" +#: git-send-email.perl msgid "The required SMTP server is not properly defined." msgstr "El servidor SMTP requerit no està correctament definit." +#: git-send-email.perl #, perl-format msgid "Server does not support STARTTLS! %s" msgstr "El servidor no admet STARTTLS! %s" +#: git-send-email.perl #, perl-format msgid "STARTTLS failed! %s" msgstr "STARTTLS ha fallat! %s" +#: git-send-email.perl msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug." msgstr "" "No s'ha pogut inicialitzar SMTP correctament. Comproveu-ho la configuració i " "useu --smtp-debug." +#: git-send-email.perl #, perl-format msgid "Failed to send %s\n" msgstr "S'ha produït un error en enviar %s\n" +#: git-send-email.perl #, perl-format -msgid "Dry-Sent %s\n" -msgstr "Simulació d'enviament %s\n" +msgid "Dry-Sent %s" +msgstr "Prova-Enviat %s" +#: git-send-email.perl #, perl-format -msgid "Sent %s\n" -msgstr "Enviat %s\n" +msgid "Sent %s" +msgstr "Enviat %s" -msgid "Dry-OK. Log says:\n" -msgstr "Simulació de correcte. El registre diu:\n" +#: git-send-email.perl +msgid "Dry-OK. Log says:" +msgstr "Prova correcta. El registre diu:" -msgid "OK. Log says:\n" -msgstr "Correcte. El registre diu: \n" +#: git-send-email.perl +msgid "OK. Log says:" +msgstr "Correcte. El registre diu:" +#: git-send-email.perl msgid "Result: " msgstr "Resultat: " -msgid "Result: OK\n" -msgstr "Resultat: correcte\n" +# OK = correcte? +#: git-send-email.perl +msgid "Result: OK" +msgstr "Resultat: correcte" +#: git-send-email.perl #, perl-format msgid "can't open file %s" msgstr "no es pot obrir el fitxer %s" +#: git-send-email.perl #, perl-format msgid "(mbox) Adding cc: %s from line '%s'\n" msgstr "(mbox) S'està afegint cc: %s des de la línia «%s»\n" +#: git-send-email.perl #, perl-format msgid "(mbox) Adding to: %s from line '%s'\n" msgstr "(mbox) S'està afegint a: %s des de la línia «%s»\n" +#: git-send-email.perl #, perl-format msgid "(non-mbox) Adding cc: %s from line '%s'\n" msgstr "(no mbox) S'està afegint cc: %s des de la línia «%s»\n" +#: git-send-email.perl #, perl-format msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(cos) S'està afegint cc: %s des de la línia «%s»\n" +#: git-send-email.perl #, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) no s'ha pogut executar «%s»" +#: git-send-email.perl #, perl-format msgid "(%s) Malformed output from '%s'" msgstr "(%s) Sortida mal formada de «%s»" +#: git-send-email.perl #, perl-format msgid "(%s) failed to close pipe to '%s'" msgstr "(%s) s'ha produït un error en tancar el conducte «%s»" +#: git-send-email.perl #, perl-format msgid "(%s) Adding %s: %s from: '%s'\n" msgstr "(%s) S'està afegint %s: %s des de: «%s»\n" +#: git-send-email.perl msgid "cannot send message as 7bit" msgstr "no es pot enviar el missatge en 7 bits" +#: git-send-email.perl msgid "invalid transfer encoding" msgstr "codificació de transferència no vàlida" +#: git-send-email.perl #, perl-format msgid "" "fatal: %s: rejected by %s hook\n" @@ -23091,10 +29656,12 @@ msgstr "" "%s\n" "avís: no s'ha enviat cap pedaç\n" +#: git-send-email.perl #, perl-format msgid "unable to open %s: %s\n" msgstr "no s'ha pogut obrir %s: %s\n" +#: git-send-email.perl #, perl-format msgid "" "fatal: %s:%d is longer than 998 characters\n" @@ -23103,11 +29670,91 @@ msgstr "" "fatal: %s:%d té més de 998 caràcters\n" "avís: no s'ha enviat cap pedaç\n" +#: git-send-email.perl #, perl-format msgid "Skipping %s with backup suffix '%s'.\n" msgstr "S'està ometent %s amb el sufix de còpia de seguretat «%s».\n" #. TRANSLATORS: please keep "[y|N]" as is. +#: git-send-email.perl #, perl-format msgid "Do you really want to send %s? [y|N]: " msgstr "Esteu segur que voleu enviar %s? [y|N]: " + +#~ msgid "revision walk setup failed\n" +#~ msgstr "la configuració del recorregut de revisions ha fallat\n" + +#, c-format +#~ msgid "unable to parse contact: %s" +#~ msgstr "no s'ha pogut analitzar el contacte: %s" + +#, c-format +#~ msgid "truncating .rej filename to %.*s.rej" +#~ msgstr "s'està truncant el nom del fitxer .rej a %.*s.rej" + +#~ msgid "" +#~ "the add.interactive.useBuiltin setting has been removed!\n" +#~ "See its entry in 'git help config' for details." +#~ msgstr "" +#~ "s'ha eliminat la configuració add.interactive.useBuiltin\n" +#~ "Per a més detalls, vegeu la seva entrada a «git help config»." + +#~ msgid "" +#~ "Use -f if you really want to add them.\n" +#~ "Turn this message off by running\n" +#~ "\"git config advice.addIgnoredFile false\"" +#~ msgstr "" +#~ "Utilitzeu -f si realment voleu afegir-los.\n" +#~ "Desactiveu aquest missatge executant\n" +#~ "«git config advice.addIgnoredFile false»" + +#~ msgid "" +#~ "Maybe you wanted to say 'git add .'?\n" +#~ "Turn this message off by running\n" +#~ "\"git config advice.addEmptyPathspec false\"" +#~ msgstr "" +#~ "Potser voleu dir «git add .»?\n" +#~ "Desactiveu aquest missatge executant\n" +#~ "«git config advice.addEmptyPathspec false»" + +#~ msgid "git archive: Remote with no URL" +#~ msgstr "git archive: Remot sense URL" + +#~ msgid "" +#~ "clean.requireForce defaults to true and neither -i, -n, nor -f given; " +#~ "refusing to clean" +#~ msgstr "" +#~ "clean.requireForce és per defecte cert i ni -i, -n ni -f s'han indicat; " +#~ "refusant netejar" + +#~ msgid "only one action at a time" +#~ msgstr "només una acció cada cop" + +#~ msgid "use [RFC PATCH] instead of [PATCH]" +#~ msgstr "useu [RFC PATCH] en comptes de [PATCH]" + +#, c-format +#~ msgid "bad ls-files format: element '%s' does not start with '('" +#~ msgstr "format incorrecte del ls-files: l'element «%s» no comença amb «(»" + +#, c-format +#~ msgid "bad ls-files format: element '%s' does not end in ')'" +#~ msgstr "format incorrecte del ls-files: l'element «%s» no acaba amb «)»" + +#, c-format +#~ msgid "bad ls-files format: %%%.*s" +#~ msgstr "format incorrecte de ls-files: %%%.*s" + +#, c-format +#~ msgid "no URLs configured for remote '%s'" +#~ msgstr "cap URL configurat per al remot «%s»" + +#~ msgid "keep redundant, empty commits" +#~ msgstr "retén les comissions redundants i buides" + +#~ msgid "core.commentChar should only be one ASCII character" +#~ msgstr "core.commentChar només hauria de ser un caràcter ASCII" + +#, c-format +#~ msgid "remote '%s' has no configured URL" +#~ msgstr "el remot «%s» no té cap URL configurat" diff --git a/po/de.po b/po/de.po index e271476cd2c1d0..4d9c46fb19de01 100644 --- a/po/de.po +++ b/po/de.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-19 19:21+0200\n" -"PO-Revision-Date: 2024-07-19 19:25+0200\n" +"POT-Creation-Date: 2025-03-06 18:29+0100\n" +"PO-Revision-Date: 2025-03-07 17:28+0100\n" "Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n" "Language-Team: German\n" "Language: de\n" @@ -366,11 +366,11 @@ msgstr "" #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Modusänderung vom Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? " +"Modusänderung im Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? " #, c-format msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? " -msgstr "Löschung vom Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? " +msgstr "Löschung im Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? " #, c-format msgid "Discard addition from index and worktree [y,n,q,a,d%s,?]? " @@ -379,7 +379,7 @@ msgstr "Ergänzung im Index und Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? " #, c-format msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Diesen Patch-Block vom Index und Arbeitsverzeichnis verwerfen [y,n,q,a," +"Diesen Patch-Block im Index und Arbeitsverzeichnis verwerfen [y,n,q,a," "d%s,?]? " msgid "" @@ -566,7 +566,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - diesen Patch-Block unbestimmt lassen, nächsten unbestimmten Patch-Block " @@ -579,7 +579,7 @@ msgstr "" "/ - nach Patch-Block suchen, der regulärem Ausdruck entspricht\n" "s - aktuellen Patch-Block in kleinere Patch-Blöcke aufteilen\n" "e - aktuellen Patch-Block manuell editieren\n" -"p - aktuellen Patch-Block anzeigen\n" +"p - aktuellen Patch-Block anzeigen, 'P' um Anzeigeprogramm zu benutzen\n" "? - Hilfe anzeigen\n" #, c-format @@ -650,10 +650,10 @@ msgstr "Nur Binärdateien geändert." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Deaktivieren Sie diese Nachricht mit \"git config advice.%s false\"" +"Deaktivieren Sie diese Meldung mit \"git config set advice.%s false\"" #, c-format msgid "%shint:%s%.*s%s\n" @@ -1280,6 +1280,15 @@ msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "" "versuche 3-Wege-Merge, weiche auf normalen Patch aus, wenn dies fehlschlägt" +msgid "for conflicts, use our version" +msgstr "bei Konflikten unsere Variante verwenden" + +msgid "for conflicts, use their version" +msgstr "bei Konflikten ihre Variante verwenden" + +msgid "for conflicts, use a union version" +msgstr "bei Konflikten eine gemeinsame Variante verwenden" + msgid "build a temporary index based on embedded index information" msgstr "" "einen temporären Index, basierend auf den integrierten Index-Informationen, " @@ -1329,6 +1338,9 @@ msgstr "<Wurzelverzeichnis> vor alle Dateinamen stellen" msgid "don't return error for empty patches" msgstr "keinen Fehler für leere Patches zurückgeben" +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs, und --union erfordern --3way" + #, c-format msgid "cannot stream blob %s" msgstr "kann Blob %s nicht streamen" @@ -1401,6 +1413,10 @@ msgstr "Kein gültiger Objektname: %s" msgid "not a tree object: %s" msgstr "Kein Tree-Objekt: %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "Tree-Objekt %s konnte nicht entpackt werden" + #, c-format msgid "File not found: %s" msgstr "Datei nicht gefunden: %s" @@ -2384,6 +2400,18 @@ msgstr "git archive: Protokollfehler" msgid "git archive: expected a flush" msgstr "git archive: erwartete eine Spülung (flush)" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "Problem beim Laden von sparse-checkout" + +msgid "Minimum number of objects to request at a time" +msgstr "Mindestanzahl der gleichzeitig anzufordernden Objekte" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "fehlenden Objekte im aktuellen sparse-checkout beschränken" + msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2525,9 +2553,6 @@ msgstr "" "Ungültiges Argument %s für 'git bisect terms'.\n" "Unterstützte Optionen sind: --term-good|--term-old und --term-bad|--term-new." -msgid "revision walk setup failed\n" -msgstr "Einrichtung des Revisionsgangs fehlgeschlagen\n" - #, c-format msgid "could not open '%s' for appending" msgstr "konnte '%s' nicht zum Anhängen öffnen" @@ -3154,10 +3179,6 @@ msgstr "" msgid "git version:\n" msgstr "git Version:\n" -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() ist fehlgeschlagen mit Fehler '%s' (%d)\n" - msgid "compiler info: " msgstr "Compiler Info: " @@ -3533,9 +3554,14 @@ msgstr "git check-mailmap [<Optionen>] <Kontakt>..." msgid "also read contacts from stdin" msgstr "ebenfalls Kontakte von der Standard-Eingabe lesen" -#, c-format -msgid "unable to parse contact: %s" -msgstr "konnte Kontakt nicht parsen: %s" +msgid "read additional mailmap entries from file" +msgstr "zusätzliche mailmap-Einträge aus Datei lesen" + +msgid "blob" +msgstr "Blob" + +msgid "read additional mailmap entries from blob" +msgstr "zusätzliche mailmap-Einträge aus Blob lesen" msgid "no contacts specified" msgstr "keine Kontakte angegeben" @@ -3897,6 +3923,10 @@ msgstr "Pfade können nicht beim Wechseln von Branches verwendet werden" msgid "'%s' cannot be used with switching branches" msgstr "'%s' kann nicht beim Wechseln von Branches verwendet werden" +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "'%s' benötigt die Pfade zum Auschecken" + #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s' kann nicht mit '%s' verwendet werden" @@ -3940,10 +3970,9 @@ msgstr "neuer ungeborener Branch" msgid "update ignored files (default)" msgstr "ignorierte Dateien aktualisieren (Standard)" -msgid "do not check if another worktree is holding the given ref" +msgid "do not check if another worktree is using this branch" msgstr "" -"Prüfung, ob die Referenz bereits in einem anderen Arbeitsverzeichnis " -"ausgecheckt wurde, deaktivieren" +"nicht prüfen, ob ein anderes Arbeitsverzeichnis diesen Branch verwendet" msgid "checkout our version for unmerged files" msgstr "unsere Variante für nicht zusammengeführte Dateien auschecken" @@ -4180,8 +4209,95 @@ msgstr "" "clean.requireForce ist 'true' und -f ist nicht angegeben: clean wird " "verweigert" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<Optionen>] [--] <Repository> [<Verzeichnis>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info: Konnte Alternative für '%s' nicht hinzufügen: %s\n" + +#, c-format +msgid "failed to stat '%s'" +msgstr "Konnte '%s' nicht lesen" + +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s existiert und ist kein Verzeichnis" + +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "" +"'%s' ist eine symbolische Verknüpfung, verweigere das Klonen mit --local" + +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "Fehler beim Starten der Iteration über '%s'" + +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "" +"symbolische Verknüpfung '%s' existiert, verweigere das Klonen mit --local" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "Konnte '%s' nicht entfernen." + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "Hardlink bei '%s' kann nicht geprüft werden" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "Hardlink unterscheidet sich von der Quelle bei '%s'" + +#, c-format +msgid "failed to create link '%s'" +msgstr "Konnte Verweis '%s' nicht erstellen" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "Konnte Datei nicht nach '%s' kopieren" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "Fehler beim Iterieren über '%s'" + +#, c-format +msgid "done.\n" +msgstr "Fertig.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Klonen erfolgreich, Auschecken ist aber fehlgeschlagen.\n" +"Sie können mit 'git status' prüfen, was ausgecheckt worden ist\n" +"und das Auschecken mit 'git restore --source=HEAD :/' erneut versuchen.\n" + +msgid "remote did not send all necessary objects" +msgstr "Remote-Repository hat nicht alle erforderlichen Objekte gesendet" + +#, c-format +msgid "unable to update %s" +msgstr "kann %s nicht aktualisieren" + +msgid "failed to initialize sparse-checkout" +msgstr "Fehler beim Initialisieren vom partiellen Checkout." + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "" +"HEAD des Remote-Repositories verweist auf nicht existierende Referenz, kann " +"nicht ausgecheckt werden" + +msgid "unable to checkout working tree" +msgstr "Arbeitsverzeichnis konnte nicht ausgecheckt werden" + +msgid "unable to write parameters to config file" +msgstr "konnte Parameter nicht in Konfigurationsdatei schreiben" + +msgid "cannot repack to clean up" +msgstr "Kann \"repack\" zum Aufräumen nicht aufrufen" + +msgid "cannot unlink temporary alternates file" +msgstr "Kann temporäre \"alternates\"-Datei nicht entfernen" msgid "don't clone shallow repository" msgstr "Repository mit unvollständiger Historie nicht klonen" @@ -4234,6 +4350,9 @@ msgstr "<Name> statt 'origin' für Upstream-Repository verwenden" msgid "checkout <branch> instead of the remote's HEAD" msgstr "<Branch> auschecken, anstatt HEAD des Remote-Repositories" +msgid "clone single revision <rev> and check out" +msgstr "einzelnen Commit <Commit> klonen und auschecken" + msgid "path to git-upload-pack on the remote" msgstr "Pfad zu \"git-upload-pack\" auf der Gegenseite" @@ -4250,19 +4369,17 @@ msgstr "" "Zeit\n" "erstellen" -msgid "revision" -msgstr "Commit" +msgid "ref" +msgstr "Referenz" -msgid "deepen history of shallow clone, excluding rev" -msgstr "" -"die Historie eines Klons mit unvollständiger Historie (shallow) mittels\n" -"Ausschluss eines Commits vertiefen" +msgid "deepen history of shallow clone, excluding ref" +msgstr "Historie eines flachen Klons vertiefen, Referenz exkludiert" msgid "clone only one branch, HEAD or --branch" msgstr "nur einen Branch klonen, HEAD oder --branch" -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "keine Tags klonen, und auch bei späteren Abrufen nicht beachten" +msgid "clone tags, and make later fetches not to follow them" +msgstr "Tags klonen und dafür sorgen, dass spätere Abrufe ihnen nicht folgen" msgid "any cloned submodules will be shallow" msgstr "jedes geklonte Submodul mit unvollständiger Historie (shallow)" @@ -4307,99 +4424,8 @@ msgstr "" "eine URI für das Herunterladen von Bundles vor dem Abruf\n" "aus dem ursprünglichen Remote-Repository" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: Konnte Alternative für '%s' nicht hinzufügen: %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "Konnte '%s' nicht lesen" - -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s existiert und ist kein Verzeichnis" - -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "" -"'%s' ist eine symbolische Verknüpfung, verweigere das Klonen mit --local" - -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "Fehler beim Starten der Iteration über '%s'" - -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "" -"symbolische Verknüpfung '%s' existiert, verweigere das Klonen mit --local" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "Konnte '%s' nicht entfernen." - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "Hardlink bei '%s' kann nicht geprüft werden" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "Hardlink unterscheidet sich von der Quelle bei '%s'" - -#, c-format -msgid "failed to create link '%s'" -msgstr "Konnte Verweis '%s' nicht erstellen" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "Konnte Datei nicht nach '%s' kopieren" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "Fehler beim Iterieren über '%s'" - -#, c-format -msgid "done.\n" -msgstr "Fertig.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Klonen erfolgreich, Auschecken ist aber fehlgeschlagen.\n" -"Sie können mit 'git status' prüfen, was ausgecheckt worden ist\n" -"und das Auschecken mit 'git restore --source=HEAD :/' erneut versuchen.\n" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Konnte zu klonenden Remote-Branch %s nicht finden." - -msgid "remote did not send all necessary objects" -msgstr "Remote-Repository hat nicht alle erforderlichen Objekte gesendet" - -#, c-format -msgid "unable to update %s" -msgstr "kann %s nicht aktualisieren" - -msgid "failed to initialize sparse-checkout" -msgstr "Fehler beim Initialisieren vom partiellen Checkout." - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "" -"HEAD des Remote-Repositories verweist auf nicht existierende Referenz, kann " -"nicht ausgecheckt werden" - -msgid "unable to checkout working tree" -msgstr "Arbeitsverzeichnis konnte nicht ausgecheckt werden" - -msgid "unable to write parameters to config file" -msgstr "konnte Parameter nicht in Konfigurationsdatei schreiben" - -msgid "cannot repack to clean up" -msgstr "Kann \"repack\" zum Aufräumen nicht aufrufen" - -msgid "cannot unlink temporary alternates file" -msgstr "Kann temporäre \"alternates\"-Datei nicht entfernen" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<Optionen>] [--] <Repository> [<Verzeichnis>]" msgid "Too many arguments." msgstr "Zu viele Argumente." @@ -4512,6 +4538,10 @@ msgstr "Remoteübertragung meldete Fehler" msgid "Remote branch %s not found in upstream %s" msgstr "Remote-Branch %s nicht im Upstream-Repository %s gefunden" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "Remote-Commit %s nicht im Upstream-Repository %s gefunden" + msgid "You appear to have cloned an empty repository." msgstr "Sie scheinen ein leeres Repository geklont zu haben." @@ -4691,9 +4721,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree: Fehler beim Lesen" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4701,14 +4731,14 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<Modus>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<Modus>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <Commit> | --fixup [(amend|" -"reword):]<Commit>)]\n" +"reword):]<Commit>]\n" " [-F <Datei> | -m <Nachricht>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<Autor>]\n" " [--date=<Datum>] [--cleanup=<Modus>] [--[no-]status]\n" " [-i | -o] [--pathspec-from-file=<Datei> [--pathspec-file-nul]]\n" -" [(--trailer <Token>[(=|:)<Wert>])...] [-S[<Key-Id>]]\n" +" [(--trailer <Token>[(=|:)<Wert>])...] [-S[<Key-ID>>]]\n" " [--] [<Pfadspezifikation>...]" msgid "git status [<options>] [--] [<pathspec>...]" @@ -5207,12 +5237,10 @@ msgstr "git config list [<Datei-Option>] [<Anzeige-Option>] [--includes]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" "git config get [<Datei-Option>] [<Anzeige-Option>] [--includes] [--all] [--" -"regexp=<Regex>] [--value=<Wert>] [--fixed-value] [--default=<Standardwert>] " -"<Name>" +"regexp] [--value=<Wert>] [--fixed-value] [--default=<Standardwert>] <Name>" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5223,10 +5251,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" "git config unset [<Datei-Option>] [--all] [--value=<Wert>] [--fixed-value] " -"<Name> <Wert>" +"<Name>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [<Datei-Option>] <alter-Name> <neuer-Name>" @@ -5242,6 +5270,15 @@ msgstr "" "git config [<Datei-Option>] --get-colorbool <Name> [<Standard-Ausgabe-ist-" "Terminal>]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<Datei-Option>] [<Anzeige-Option>] [--includes] [--all] [--" +"regexp=<Regex>] [--value=<Wert>] [--fixed-value] [--default=<Standardwert>] " +"<Name>" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5665,12 +5702,8 @@ msgid "traversed %lu commits\n" msgstr "%lu Commits durchlaufen\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"mehr als %i Tags gefunden; führe die ersten %i auf\n" -"Suche bei %s aufgegeben\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "%i Tags gefunden; Suche bei %s aufgegeben\n" #, c-format msgid "describe %s\n" @@ -6061,8 +6094,8 @@ msgstr "" "zu umgehen.\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s hat nicht alle erforderlichen Objekte gesendet\n" +msgid "%s did not send all necessary objects" +msgstr "%s hat nicht alle erforderlichen Objekte gesendet" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -6101,8 +6134,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "Option \"%s\" Wert \"%s\" ist nicht gültig für %s" #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "Option \"%s\" wird ignoriert für %s\n" +msgid "option \"%s\" is ignored for %s" +msgstr "Option \"%s\" wird für %s ignoriert" #, c-format msgid "%s is not a valid object" @@ -6112,6 +6145,21 @@ msgstr "%s ist kein gültiges Objekt" msgid "the object %s does not exist" msgstr "das Objekt %s ist nicht vorhanden" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Führen Sie 'git remote set-head %s %s' aus, um der Änderung zu folgen,\n" +"oder setzen Sie die Konfiguration 'remote.%s.followRemoteHEAD' auf einen\n" +"anderen Wert wenn Sie diese Meldung nicht sehen wollen. Speziell der Befehl\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"wird die Warnung deaktivieren, bis das Remote-Repository HEAD in etwas\n" +"anderes ändert." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "mehrere Branches erkannt, inkompatibel mit --set-upstream" @@ -6257,6 +6305,9 @@ msgstr "Refmap" msgid "specify fetch refmap" msgstr "Refmap für 'fetch' angeben" +msgid "revision" +msgstr "Commit" + msgid "report that we have only objects reachable from this object" msgstr "" "ausgeben, dass wir nur Objekte haben, die von diesem Objekt aus erreichbar " @@ -6792,6 +6843,9 @@ msgstr "mehr Gründlichkeit (erhöht Laufzeit)" msgid "enable auto-gc mode" msgstr "\"auto-gc\" Modus aktivieren" +msgid "perform garbage collection in the background" +msgstr "Garbage Collection im Hintergrund ausführen" + msgid "force running gc even if there may be another gc running" msgstr "" "Ausführung von \"git gc\" erzwingen, selbst wenn ein anderes\n" @@ -6800,6 +6854,9 @@ msgstr "" msgid "repack all other packs except the largest pack" msgstr "alle anderen Pakete, außer das größte Paket, neu packen" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "pack-Präfix zum Speichern eines Pakets mit gelöschten Objekten" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "Fehler beim Parsen des Wertes '%s' von gc.logExpiry" @@ -6895,6 +6952,9 @@ msgstr "Aufgabe '%s' kann nicht mehrfach ausgewählt werden" msgid "run tasks based on the state of the repository" msgstr "Aufgaben abhängig vom Zustand des Repositories ausführen" +msgid "perform maintenance in the background" +msgstr "Wartung im Hintergrund ausführen" + msgid "frequency" msgstr "Häufigkeit" @@ -6994,8 +7054,26 @@ msgstr "weder Timer von systemd, noch crontab ist verfügbar" msgid "%s scheduler is not available" msgstr "%s Scheduler ist nicht verfügbar" -msgid "another process is scheduling background maintenance" -msgstr "ein anderer Prozess plant die Hintergrundwartung" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"Konnte '%s.lock' nicht erstellen: %s.\n" +"\n" +"Ein weiterer geplanter git-maintenance(1)-Prozess scheint in diesem\n" +"Repository zu laufen. Bitte stellen Sie sicher, dass keine anderen\n" +"Wartungsprozesse laufen und versuchen Sie es dann erneut. Wenn es\n" +"immer noch fehlschlägt, ist möglicherweise ein git-maintenance(1)-Prozess\n" +"in diesem Repository abgestürzt: Entfernen Sie die Datei manuell, um\n" +"fortzufahren." + +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "kann keine Sperre für die geplante Hintergrundwartung erhalten" msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=<Scheduler>]" @@ -7576,9 +7654,29 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "Länge der Objekt-Liste = %d: %lu Objekt" msgstr[1] "Länge der Objekt-Liste = %d: %lu Objekte" +msgid "could not start pack-objects to repack local links" +msgstr "" +"konnte pack-objects nicht starten, um lokale Verknüpfungen neu zu packen" + +msgid "failed to feed local object to pack-objects" +msgstr "lokales Objekt konnte nicht an pack-objects übergeben werden" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: Erwarte vollständige Hex-Objekt-ID-Zeilen nur von pack-objects." + +msgid "could not finish pack-objects to repack local links" +msgstr "" +"konnte pack-objects nicht vollständig ausführen, um lokale Verknüpfungen neu " +"zu packen" + msgid "Cannot come back to cwd" msgstr "Kann nicht zurück zum Arbeitsverzeichnis wechseln" +#, c-format +msgid "bad --pack_header: %s" +msgstr "ungültiger --pack_header: %s" + #, c-format msgid "bad %s" msgstr "%s ist ungültig" @@ -7587,6 +7685,9 @@ msgstr "%s ist ungültig" msgid "unknown hash algorithm '%s'" msgstr "unbekannter Hash-Algorithmus '%s'" +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor kann nicht mit einem Paketnamen verwendet werden" + msgid "--stdin requires a git repository" msgstr "--stdin erfordert ein Git-Repository" @@ -7771,9 +7872,6 @@ msgstr "-L<Bereich>:<Datei> kann nicht mit Pfadspezifikation verwendet werden" msgid "Final output: %d %s\n" msgstr "letzte Ausgabe: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "konnte temporäres Objektverzeichnis nicht erstellen" - #, c-format msgid "git show %s: bad file" msgstr "git show %s: ungültige Datei" @@ -8353,15 +8451,6 @@ msgstr "einen diff3 basierten Merge verwenden" msgid "use a zealous diff3 based merge" msgstr "einen eifrigen diff3 basierten Merge verwenden" -msgid "for conflicts, use our version" -msgstr "bei Konflikten unsere Variante verwenden" - -msgid "for conflicts, use their version" -msgstr "bei Konflikten ihre Variante verwenden" - -msgid "for conflicts, use a union version" -msgstr "bei Konflikten eine gemeinsame Variante verwenden" - msgid "<algorithm>" msgstr "<Algorithmus>" @@ -8467,11 +8556,6 @@ msgstr "unbekannte Strategie-Option: -X%s" msgid "malformed input line: '%s'." msgstr "Fehlerhafte Eingabezeile: '%s'." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "" -"Merge kann nicht fortgesetzt werden; unsauberes Ergebnis von %d erhalten" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<Optionen>] [<Commit>...]" @@ -8841,6 +8925,9 @@ msgstr "" msgid "write multi-pack bitmap" msgstr "schreibe Multi-Pack-Bitmap" +msgid "write a new incremental MIDX" +msgstr "ein neues inkrementelles MIDX schreiben" + msgid "write multi-pack index containing only given indexes" msgstr "Multi-Pack-Index schreiben, der nur die gegebenen Indexe enthält" @@ -8976,11 +9063,11 @@ msgstr "git notes [--ref <Notiz-Referenz>] [list [<Objekt>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <Notiz-Referenz>] add [-f] [--allow-empty] [--" "[no-]separator|--separator=<Absatz-Unterbrechung>] [--[no-]stripspace] [-m " -"<Nachricht> | -F <Datei> | (-c | -C) <Objekt>] [<Objekt>]" +"<Nachricht> | -F <Datei> | (-c | -C) <Objekt>] [<Objekt>] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" @@ -8989,11 +9076,11 @@ msgstr "" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <Notiz-Referenz>] append [--allow-empty] [--" "[no-]separator|--separator=<Absatz-Unterbrechnung>] [--[no-]stripspace] [-m " -"<Nachricht> | -F <Datei> | (-c | -C) <Objekt>] [<Object>]" +"<Nachricht> | -F <Datei> | (-c | -C) <Objekt>] [<Objekt>] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref <Notiz-Referenz>] edit [--allow-empty] [<Objekt>]" @@ -9115,6 +9202,9 @@ msgstr "Notizinhalte in einer Datei" msgid "reuse and edit specified note object" msgstr "Wiederverwendung und Bearbeitung des angegebenen Notiz-Objektes" +msgid "edit note message in editor" +msgstr "Notizmeldung im Editor bearbeiten" + msgid "reuse specified note object" msgstr "Wiederverwendung des angegebenen Notiz-Objektes" @@ -9305,6 +9395,13 @@ msgstr "" "git pack-objects [<Optionen>] <Basis-Name> [< <Referenzliste> | < " "<Objektliste>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "ungültige Option für --name-hash-version: %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "derzeit erfordert --write-bitmap-index --name-hash-version=1" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9628,6 +9725,9 @@ msgstr "" "keine Objekte aus Packdateien von partiell geklonten Remote-Repositories " "packen" +msgid "implies --missing=allow-any" +msgstr "impliziert --missing=allow-any" + msgid "respect islands during delta compression" msgstr "Delta-Islands bei Delta-Kompression beachten" @@ -9639,6 +9739,11 @@ msgstr "" "jegliche konfigurierte uploadpack.blobpackfileuri für dieses Protkoll " "ausschließen" +msgid "use the specified name-hash function to group similar objects" +msgstr "" +"die angegebene Name-Hash-Funktion verwenden, um ähnliche Objekte zu " +"gruppieren" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "Tiefe für Verkettung von Unterschieden %d ist zu tief, erzwinge %d" @@ -10927,8 +11032,11 @@ msgstr "Kein Reflog zum Löschen angegeben." msgid "invalid ref format: %s" msgstr "Ungültiges Format für Referenzen: %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<Format> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<Format> [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "das Referenzformat angeben, in das konvertiert werden soll" @@ -10936,6 +11044,9 @@ msgstr "das Referenzformat angeben, in das konvertiert werden soll" msgid "perform a non-destructive dry-run" msgstr "einen zerstörungsfreien Trockenlauf durchführen" +msgid "drop reflogs entirely during the migration" +msgstr "Reflogs während der Migration vollständig zu löschen" + msgid "missing --ref-format=<format>" msgstr "fehlendes --ref-format=<Format>" @@ -10943,6 +11054,12 @@ msgstr "fehlendes --ref-format=<Format>" msgid "repository already uses '%s' format" msgstr "das Repository verwendet bereits das Format '%s'" +msgid "enable strict checking" +msgstr "strenge Kontrolle aktivieren" + +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' nimmt keine Argumente an" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -11281,6 +11398,30 @@ msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Lokale Referenz konfiguriert für 'git push'%s:" msgstr[1] " Lokale Referenzen konfiguriert für 'git push'%s:" +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "'%s/HEAD' ist unverändert und zeigt auf '%s'\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' hat sich von '%s' geändert und zeigt jetzt auf '%s'\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "'%s/HEAD' ist nun erstellt und zeigt auf '%s'\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' war losgelöst bei '%s' und zeigt nun auf '%s'\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"'%s/HEAD' zeigte vorher auf '%s' (was kein Remote-Branch ist), zeigt jetzt " +"aber auf '%s'\n" + msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "setzt refs/remotes/<Name>/HEAD gemäß dem Remote-Repository" @@ -11304,7 +11445,7 @@ msgid "Not a valid ref: %s" msgstr "keine gültige Referenz: %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "Konnte %s nicht einrichten" #, c-format @@ -11376,8 +11517,14 @@ msgstr "Werde keine URLs entfernen, die nicht für \"push\" bestimmt sind" msgid "be verbose; must be placed before a subcommand" msgstr "erweiterte Ausgaben; muss vor einem Unterbefehl angegeben werden" -msgid "git repack [<options>]" -msgstr "git repack [<Optionen>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<Paketname>]\n" +"[--write-midx] [--name-hash-version=<n>]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11456,6 +11603,12 @@ msgstr "--no-reuse-delta an git-pack-objects übergeben" msgid "pass --no-reuse-object to git-pack-objects" msgstr "--no-reuse-object an git-pack-objects übergeben" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"die Version des Hash-Namens angeben, die für die Gruppierung ähnlicher " +"Objekte nach Pfad verwendet werden soll" + msgid "do not run git-update-server-info" msgstr "git-update-server-info nicht ausführen" @@ -11507,9 +11660,6 @@ msgstr "eine geometrische Progression mit Faktor <N> finden" msgid "write a multi-pack index of the resulting packs" 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" @@ -11727,9 +11877,6 @@ 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" @@ -12397,11 +12544,11 @@ msgstr "Referenz nicht vorhanden" msgid "failed to look up reference" msgstr "Fehler beim Nachschlagen der Referenz" -msgid "only show tags (can be combined with branches)" -msgstr "nur Tags anzeigen (kann mit Branches kombiniert werden)" +msgid "only show tags (can be combined with --branches)" +msgstr "nur Tags anzeigen (kann mit --branches kombiniert werden)" -msgid "only show branches (can be combined with tags)" -msgstr "nur Branches anzeigen (kann mit Tags kombiniert werden)" +msgid "only show branches (can be combined with --tags)" +msgstr "nur Branches anzeigen (kann mit --tags kombiniert werden)" msgid "check for reference existence without resolving" msgstr "Prüfung auf Vorhandensein einer Referenz, ohne diese aufzulösen" @@ -12460,6 +12607,10 @@ msgstr "" "Fehler beim Erstellen eines Verzeichnisses für Datei eines partiellen " "Checkouts" +#, c-format +msgid "unable to fdopen %s" +msgstr "kann %s nicht öffnen" + msgid "failed to initialize worktree config" msgstr "Fehler beim Initialisieren der Arbeitsverzeichnis-Konfiguration" @@ -12927,8 +13078,8 @@ msgid "couldn't hash object from '%s'" msgstr "Hash eines Objektes von '%s' konnte nicht erzeugt werden" #, c-format -msgid "unexpected mode %o\n" -msgstr "unerwarteter Modus %o\n" +msgid "unexpected mode %o" +msgstr "unerwarteter Modus %o" msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "" @@ -14102,6 +14253,9 @@ msgstr "" "versuchen, eine Übereinstimmung des Branchnamens mit einem\n" "Remote-Tracking-Branch herzustellen" +msgid "use relative paths for worktrees" +msgstr "relative Pfade für Arbeitsverzeichnisse verwenden" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "" @@ -14386,6 +14540,28 @@ msgstr "kann '%s' nicht erstellen" msgid "index-pack died" msgstr "Erstellung der Paketindexdatei abgebrochen" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "Verzeichnis '%s' ist im Index vorhanden, aber nicht partiell" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "" +"das beschädigte Cache-Verzeichnis enthält Einträge, die nicht im Index " +"enthalten sind" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s mit Flags 0x%x sollte nicht im Cache-Verzeichnis sein" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "ungültiges Unterverzeichnis '%.*s'" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "" +"Cache-Verzeichnis für Pfad %.*s stimmt nicht überein. Erwartete %s bekam %s" + msgid "terminating chunk id appears earlier than expected" msgstr "abschließende Chunk-ID erscheint eher als erwartet" @@ -14430,6 +14606,9 @@ msgstr "ein GNU Arch Repository in Git importieren" msgid "Create an archive of files from a named tree" msgstr "Dateiarchiv von angegebenem Verzeichnis erstellen" +msgid "Download missing objects in a partial clone" +msgstr "fehlender Objekte in einem partiellen Klon herunterladen" + msgid "Use binary search to find the commit that introduced a bug" msgstr "" "Binärsuche verwenden, um den Commit zu finden, der einen Fehler verursacht " @@ -15282,17 +15461,18 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "Die Unterstützung für <GIT_DIR>/info/grafts ist veraltet\n" -"und wird in zukünftigen Git Versionen entfernt.\n" +"und wird in einer zukünftigen Git-Version entfernt.\n" "\n" -"Bitte benutzen Sie \"git replace --convert-graft-file\"\n" -"zum Konvertieren der künstlichen Vorgänger (\"grafts\")\n" -"in ersetzende Referenzen.<\n" +"Bitte verwenden Sie \"git replace --convert-graft-file\"\n" +"um die künstlichen Vorgänger (\"graft\") in ersetzende Referenzen\n" +"zu konvertieren.\n" "\n" -"Sie können diese Meldung unterdrücken, indem Sie\n" -"\"git config advice.graftFileDeprecated false\" ausführen." +"Deaktivieren Sie diese Meldung, indem Sie\n" +"\"git config set advice.graftFileDeprecated false\"\n" +"ausführen." #, c-format msgid "commit %s exists in commit-graph but not in the object database" @@ -16126,6 +16306,18 @@ msgstr "URL hat kein Schema: %s" msgid "credential url cannot be parsed: %s" msgstr "URL mit Zugangsdaten konnte nicht geparst werden: %s" +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "ungültiger timeout '%s', nicht-negative ganze Zahl erwartet" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "ungültiger init-timeout '%s', nicht-negative ganze Zahl erwartet" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "ungültiges max-connections '%s', ganze Zahl erwartet" + msgid "in the future" msgstr "in der Zukunft" @@ -16389,6 +16581,12 @@ msgstr "ungültiges Argument für %s" msgid "invalid regex given to -I: '%s'" msgstr "ungültiger regulärer Ausdruck für -I gegeben: '%s'" +msgid "-G requires a non-empty argument" +msgstr "-G erfordert ein nicht leeres Argument" + +msgid "-S requires a non-empty argument" +msgstr "-S erfordert ein nicht leeres Argument" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "Fehler beim Parsen des --submodule Optionsparameters: '%s'" @@ -16856,6 +17054,22 @@ msgstr "ungültiger Git-Namespace-Pfad \"%s\"" msgid "too many args to run %s" msgstr "zu viele Argumente angegeben, um %s auszuführen" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Sie versuchen %s zu holen, welches sich in der Commit-Graph-Datei, aber " +"nicht in der Objektdatenbank befindet.\n" +"Dies ist wahrscheinlich auf eine Beschädigung des Repositories " +"zurückzuführen.\n" +"Wenn Sie versuchen, die Beschädigung des Repositories zu beheben, indem Sie " +"das fehlende Objekt erneut holen,\n" +"verwenden Sie 'git fetch --refetch' mit dem fehlenden Objekt." + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: erwartete shallow-Liste" @@ -17289,8 +17503,8 @@ msgid "" "given pattern contains NULL byte (via -f <file>). This is only supported " "with -P under PCRE v2" msgstr "" -"Angegebenes Muster enthält NULL Byte (über -f <Datei>). Das wird nur mit -" -"Punter PCRE v2 unterstützt." +"Angegebenes Muster enthält NULL Byte (über -f <Datei>). Das wird nur mit -P " +"unter PCRE v2 unterstützt." #, c-format msgid "'%s': unable to read %s" @@ -17443,10 +17657,11 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" -"Der '%s' Hook wurde ignoriert, weil er nicht als ausführbar markiert ist.\n" -"Sie können diese Warnung mit `git config advice.ignoredHook false` " +"Der '%s'-Hook wurde ignoriert, weil er nicht als ausführbar eingestellt " +"ist.\n" +"Sie können diese Warnung mit `git config set advice.ignoredHook false` " "deaktivieren." msgid "not a git repository" @@ -17463,17 +17678,9 @@ msgstr "negativer Wert für http.postBuffer; benutze Standardwert %d" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Kontrolle über Delegation wird mit cURL < 7.22.0 nicht unterstützt" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "" -"Das Anheften des öffentlichen Schlüssels wird mit cURL < 7.39.0 nicht " -"unterstützt" - msgid "Unknown value for http.proactiveauth" msgstr "Unbekannter Wert für http.proactiveauth" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE wird mit cURL < 7.44.0 nicht unterstützt." - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "Nicht unterstütztes SSL-Backend '%s'. Unterstützte SSL-Backends:" @@ -17635,13 +17842,16 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "Konnte '%s.lock' nicht erstellen: %s" +msgid "unable to create temporary object directory" +msgstr "konnte temporäres Objektverzeichnis nicht erstellen" + #, c-format msgid "could not write loose object index %s" msgstr "konnte den losen Objektindex %s nicht schreiben" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "Fehler beim Schreiben des losen Objektindexes %s\n" +msgid "failed to write loose object index %s" +msgstr "Fehler beim Schreiben des losen Objektindex %s" #, c-format msgid "unexpected line: '%s'" @@ -17657,6 +17867,10 @@ msgstr "angeführtes CRLF entdeckt" msgid "unable to format message: %s" msgstr "Meldung kann nicht formatiert werden: %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "ungültige marker-size '%s', ganze Zahl erwartet" + #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Fehler beim Merge von Submodul %s (nicht ausgecheckt)." @@ -18213,6 +18427,17 @@ msgstr "Paket konnte nicht geladen werden" msgid "could not open index for %s" msgstr "konnte Index für %s nicht öffnen" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "kann '%s' nicht mit '%s' verknüpfen" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "Fehler beim Löschen des Multi-Pack-Index bei %s" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "kann kein inkrementelles MIDX mit Bitmap schreiben" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "" "ignoriere existierenden Multi-Pack-Index; Prüfsumme stimmt nicht überein" @@ -18242,18 +18467,34 @@ msgstr "keine Packdateien zum Indizieren." msgid "refusing to write multi-pack .bitmap without any objects" msgstr "Schreiben der Multi-Pack-Bitmap ohne Objekte abgelehnt" +msgid "unable to create temporary MIDX layer" +msgstr "konnte keine temporäre MIDX-Ebene erstellen" + msgid "could not write multi-pack bitmap" msgstr "Multi-Pack-Bitmap konnte nicht geschrieben werden" +msgid "unable to open multi-pack-index chain file" +msgstr "Multi-Pack-Indexketten-Datei kann nicht geöffnet werden" + +msgid "unable to rename new multi-pack-index layer" +msgstr "neue Multi-Pack-Index-Ebene konnte nicht umbenannt werden" + msgid "could not write multi-pack-index" msgstr "Multi-Pack-Index konnte nicht geschrieben werden" +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "" +"kann Pakete aus einem inkrementellen Multi-Pack-Index nicht ablaufen lassen" + msgid "Counting referenced objects" msgstr "Referenzierte Objekte zählen" msgid "Finding and deleting unreferenced packfiles" msgstr "Suchen und Löschen von unreferenzierten Pack-Dateien" +msgid "cannot repack an incremental multi-pack-index" +msgstr "kann einen inkrementellen Multi-Pack-Index nicht neu packen" + msgid "could not start pack-objects" msgstr "Konnte 'pack-objects' nicht ausführen" @@ -18316,6 +18557,27 @@ msgstr "multi-pack-index Pack-Name Chunk ist zu klein" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "Falsche Reihenfolge bei Multi-Pack-Index Pack-Namen: '%s' vor '%s'" +msgid "multi-pack-index chain file too small" +msgstr "Multi-Pack-Index-Kettendatei zu klein" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "Paketanzahl im Basis-MIDX zu hoch: %<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "Objektanzahl in Basis-MIDX zu hoch: %<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "ungültige Multi-Pack-Index-Kette: Zeile '%s' ist kein Hash" + +msgid "unable to find all multi-pack index files" +msgstr "konnte nicht alle Multi-Pack-Indexdateien finden" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "ungültige MIDX-Objektposition, MIDX ist wahrscheinlich beschädigt" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "Ungültige pack-int-id: %u (%u Pakete insgesamt)" @@ -18334,10 +18596,6 @@ msgstr "" 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 clear multi-pack-index at %s" -msgstr "Fehler beim Löschen des Multi-Pack-Index bei %s" - msgid "multi-pack-index file exists, but failed to parse" msgstr "Multi-Pack-Index-Datei existiert, aber das Parsen schlug fehl" @@ -18555,10 +18813,22 @@ msgstr "Gepacktes Objekt %s (gespeichert in %s) ist beschädigt." msgid "missing mapping of %s to %s" msgstr "fehlende Abbildung von %s auf %s" +#, c-format +msgid "unable to open %s" +msgstr "kann %s nicht öffnen" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "die Dateien '%s' und '%s' unterscheiden sich im Inhalt" + #, c-format msgid "unable to write file %s" msgstr "Konnte Datei %s nicht schreiben." +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "konnte nicht in eine wiederholt verschwindende Datei %s schreiben" + #, c-format msgid "unable to set permission to '%s'" msgstr "Konnte Zugriffsberechtigung auf '%s' nicht setzen." @@ -18641,10 +18911,6 @@ msgstr "%s: nicht unterstützte Dateiart" msgid "%s is not a valid '%s' object" msgstr "%s ist kein gültiges '%s' Objekt" -#, c-format -msgid "unable to open %s" -msgstr "kann %s nicht öffnen" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "Hash für %s stimmt nicht überein (%s erwartet)." @@ -18746,19 +19012,18 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" -"Git erzeugt normalerweise keine Referenzen die mit\n" -"40 Hex-Zeichen enden, da diese ignoriert werden wenn\n" -"Sie diese angeben. Diese Referenzen könnten aus Versehen\n" -"erzeugt worden sein. Zum Beispiel,\n" +"Git erstellt normalerweise nie eine Referenz, die mit 40-Hex-Zeichen endet,\n" +"weil sie ignoriert wird, wenn Sie nur 40-Hex-Zeichen angeben. Diese\n" +"Referenzen können aus Versehen erstellt werden. Zum Beispiel,\n" "\n" " git switch -c $br $(git rev-parse ...)\n" "\n" -"wobei \"$br\" leer ist und eine 40-Hex-Referenz erzeugt\n" -"wurde. Bitte prüfen Sie diese Referenzen und löschen\n" -"Sie sie gegebenenfalls. Unterdrücken Sie diese Meldung\n" -"indem Sie \"git config advice.objectNameWarning false\"\n" +"wobei \"$br\" irgendwie leer ist und eine 40-Hex-Referenz erstellt wird.\n" +"Bitte überprüfen Sie die Referenzen und löschen Sie diese gegebenenfalls.\n" +"Schalten Sie diese Meldung aus, indem Sie\n" +"\"git config set advice.objectNameWarning false\"\n" "ausführen." #, c-format @@ -18919,13 +19184,6 @@ 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" - msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "Bitmap-Lookup-Tabelle beschädigt: Triplet-Position außerhalb des Index" @@ -19145,6 +19403,52 @@ msgstr "Unbekannter Schalter `%c'" msgid "unknown non-ascii option in string: `%s'" msgstr "Unbekannte nicht-Ascii Option in String: `%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " <%s>" + msgid "..." msgstr "..." @@ -19231,6 +19535,21 @@ msgstr "falscher boolescher Wert von Umgebungsvariable '%s' für '%s'" msgid "failed to parse %s" msgstr "Fehler beim Parsen von %s." +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "Fehlen beim Durchlaufen der Kinder von Baum %s: nicht gefunden" + +#, c-format +msgid "failed to find object %s" +msgstr "Objekt nicht gefunden: %s" + +#, c-format +msgid "failed to find tag %s" +msgstr "Tag nicht gefunden: %s" + +msgid "failed to setup revision walk" +msgstr "Einrichtung des Revisionsgangs fehlgeschlagen" + #, c-format msgid "Could not make %s writable by group" msgstr "Konnte Gruppenschreibrecht für %s nicht setzen." @@ -19381,6 +19700,25 @@ msgstr "Promisor-Remote-Name kann nicht mit '/' beginnen: %s" msgid "could not fetch %s from promisor remote" msgstr "konnte %s nicht von Promisor-Remote abrufen" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "" +"bekanntes Remote-Repository mit dem Namen '%s', aber mit der URL '%s' statt " +"'%s'" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "unbekannter '%s'-Wert für '%s'-Konfigurationsoption" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "unbekanntes Element '%s' aus Information aus Remote-Repository" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "" +"akzeptiertes partiell geklontes \"Remote-Repository '%s' nicht gefunden" + msgid "object-info: expected flush after arguments" msgstr "object-info: erwartete Flush nach Argumenten" @@ -19881,6 +20219,10 @@ msgstr "Positive Breitenangabe für %%(align) erwartet" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "erwartetes Format: %%(ahead-behind:<Commit>)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "erwartetes Format: %%(is-base:<committish>)" + #, c-format msgid "malformed field name: %.*s" msgstr "Fehlerhafter Feldname: %.*s" @@ -20056,17 +20398,25 @@ msgstr "Log für Referenz %s unerwartet bei %s beendet." msgid "log for %s is empty" msgstr "Log für %s ist leer." -msgid "refusing to force and skip creation of reflog" -msgstr "Erzwingen der Aktion verweigert; überspringe Erstellung des Reflogs" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "verweigere Aktualisierung einer Referenz mit fehlerhaftem Namen '%s'" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "Aktualisierung des Reflogs für Pseudoreferenz '%s' verweigert" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "Aktualisierung von Pseudoreferenz '%s' verweigert" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "Aktualisierung des Reflogs mit fehlerhaftem Namen '%s' verweigert" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "verweigere Aktualisierung einer Referenz mit fehlerhaftem Namen '%s'" + +msgid "refusing to force and skip creation of reflog" +msgstr "Erzwingen der Aktion verweigert; überspringe Erstellung des Reflogs" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "update_ref für Referenz '%s' fehlgeschlagen: %s" @@ -20120,6 +20470,17 @@ msgstr "" "kann Referenz '%s' nicht sperren: erwartete symbolische Referenz mit Ziel " "'%s': ist aber eine reguläre Referenz" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "kann Ref-Datei '%s' nicht lesen" + +#, c-format +msgid "cannot open directory %s" +msgstr "Verzeichnis %s kann nicht geöffnet werden" + +msgid "Checking references consistency" +msgstr "Überprüfung der Konsistenz der Referenzen" + #, c-format msgid "refname is dangerous: %s" msgstr "Referenzname ist gefährlich: %s" @@ -20194,6 +20555,14 @@ msgstr "" msgid "invalid refspec '%s'" msgstr "ungültige Refspec '%s'" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "Muster '%s' hat keinen '*'" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "Ersetzung '%s' hat keinen '*'" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "Ungültiges Quoting beim \"push-option\"-Wert: '%s'" @@ -20316,6 +20685,28 @@ msgstr "remote-curl: \"fetch\" ohne lokales Repository versucht" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: Unbekannter Befehl '%s' von Git" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"Lese von Remote-Repository \"%s/%s\", das zum Entfernen vorgeschlagen wird.\n" +"\n" +"Wenn Sie noch das Verzeichnis \"remotes/\" verwenden, wird empfohlen\n" +"auf konfigurationsbasierte Remote-Repositories umzusteigen:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"Wenn dies nicht möglich ist, teilen Sie uns bitte mit, warum Sie das noch\n" +"verwenden müssen, indem Sie eine E-Mail an <git@vger.kernel.org> senden." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "" @@ -20328,6 +20719,10 @@ msgstr "Mehr als ein receivepack-Befehl angegeben, benutze den ersten." msgid "more than one uploadpack given, using the first" msgstr "Mehr als ein uploadpack-Befehl angegeben, benutze den ersten." +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "nicht erkannter followRemoteHEAD-Wert '%s' ignoriert" + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "unbekannter Wert transfer.credentialsInUrl: '%s'" @@ -20348,14 +20743,6 @@ msgstr "%s folgt üblicherweise %s, nicht %s" msgid "%s tracks both %s and %s" msgstr "%s folgt sowohl %s als auch %s" -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "Schlüssel '%s' des Musters hatte kein '*'." - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "Wert '%s' des Musters hat kein '*'." - #, c-format msgid "src refspec %s does not match any" msgstr "Src-Refspec %s entspricht keiner Referenz." @@ -20766,12 +21153,15 @@ msgstr "lade nur Metadaten des Branches herunter, der ausgecheckt wird" msgid "create repository within 'src' directory" msgstr "Repository im Verzeichnis 'src' erstellen" +msgid "specify if tags should be fetched during clone" +msgstr "Angabe, ob Tags während des Klonens abgerufen werden sollen" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <Haupt-Branch>] [--full-clone]\n" -"\t[--[no-]src] <URL> [<Eintragung>]" +"\t[--[no-]src] [--[no-]tags] <URL> [<Eintragung>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20789,6 +21179,10 @@ msgstr "Fehler beim Abfragen des Default-Branches für '%s'" msgid "could not configure remote in '%s'" msgstr "konnte Remote-Repository in '%s' nicht konfigurieren" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "konnte die Tags in '%s' nicht deaktivieren" + #, c-format msgid "could not configure '%s'" msgstr "konnte '%s' nicht konfigurieren" @@ -21871,6 +22265,10 @@ msgstr "Kann nicht zum aktuellen Arbeitsverzeichnis zurückwechseln." msgid "failed to stat '%*s%s%s'" msgstr "Konnte '%*s%s%s' nicht lesen." +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' nicht absolut" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -22271,6 +22669,27 @@ msgstr "" "Anzahl der Einträge im Cache-Verzeichnis, die ungültig gemacht werden sollen " "(Standardwert 0)" +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <Optionen> -- <Commit-Optionen>" + +msgid "toggle inclusion of blob objects" +msgstr "Einbeziehung von Blob-Objekten umschalten" + +msgid "toggle inclusion of commit objects" +msgstr "Einbeziehung von Commit-Objekten umschalten" + +msgid "toggle inclusion of tag objects" +msgstr "Einbeziehung von Tag-Objekten umschalten" + +msgid "toggle inclusion of tree objects" +msgstr "Einbeziehung von Tree-Objekten umschalten" + +msgid "toggle pruning of uninteresting paths" +msgstr "Auslassen von uninteressanten Pfaden umschalten" + +msgid "read a pattern list over stdin" +msgstr "Liste von Mustern von der Standard-Eingabe lesen" + #, c-format msgid "commit %s is not marked reachable" msgstr "Commit %s ist nicht als erreichbar gekennzeichnet." @@ -22278,6 +22697,9 @@ msgstr "Commit %s ist nicht als erreichbar gekennzeichnet." msgid "too many commits marked reachable" msgstr "Zu viele Commits als erreichbar gekennzeichnet." +msgid "could not determine MIDX preferred pack" +msgstr "konnte das von MIDX bevorzugte Paket nicht ermitteln" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<Optionen>]" @@ -22339,6 +22761,24 @@ msgstr "Token" msgid "command token to send to the server" msgstr "Befehlstoken, der an den Server gesendet werden soll" +msgid "unit-test [<options>]" +msgstr "unit-test [<Optionen>]" + +msgid "immediately exit upon the first failed test" +msgstr "beim ersten fehlgeschlagenen Test sofort abbrechen" + +msgid "suite[::test]" +msgstr "suite[::test]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "nur Testsuite oder einzelnen Test ausführen <suite[::test]>" + +msgid "suite" +msgstr "Suite" + +msgid "exclude test suite <suite>" +msgstr "Testsuite <Suite> ausschließen" + #, c-format msgid "running trailer command '%s' failed" msgstr "Ausführen des Anhang-Befehls '%s' fehlgeschlagen" @@ -22899,6 +23339,10 @@ msgstr "Fehler: " msgid "warning: " msgstr "Warnung: " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() ist fehlgeschlagen mit Fehler '%s' (%d)\n" + msgid "Fetching objects" msgstr "Anfordern der Objekte" @@ -22930,6 +23374,9 @@ msgstr ".git-Datei kaputt" msgid ".git file incorrect" msgstr ".git-Datei fehlerhaft" +msgid ".git file absolute/relative path mismatch" +msgstr "absoluter/relativer Pfad der .git-Datei stimmt nicht überein" + msgid "not a valid path" msgstr "kein gültiger Pfad" @@ -22946,6 +23393,9 @@ msgstr "Konnte Repository nicht finden; .git-Datei ist kaputt" msgid "gitdir unreadable" msgstr "gitdir nicht lesbar" +msgid "gitdir absolute/relative path mismatch" +msgstr "absolute/relative Pfadabweichung in gitdir" + msgid "gitdir incorrect" msgstr "gitdir fehlerhaft" @@ -22980,6 +23430,14 @@ msgstr "konnte %s nicht in '%s' aufheben" msgid "failed to set extensions.worktreeConfig setting" msgstr "Einstellung für extensions.worktreeConfig konnte nicht gesetzt werden" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"Repository-Format konnte nicht aktualisiert werden, um relative " +"Arbeitsverzeichnisse zu unterstützen" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "Einstellung extensions.relativeWorktrees kann nicht gesetzt werden" + #, c-format msgid "could not setenv '%s'" msgstr "konnte '%s' nicht setzen" @@ -23588,6 +24046,10 @@ msgstr "'%s.final' enthält die verfasste E-Mail.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases ist mit anderen Optionen inkompatibel\n" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "" +"--dump-aliases und --translate-aliases schließen sich gegenseitig aus\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" diff --git a/po/fr.po b/po/fr.po index 7b03f2c25b7dbc..8e3339030761a1 100644 --- a/po/fr.po +++ b/po/fr.po @@ -29,6 +29,7 @@ # to debug | déboguer # debugging | débogage # to deflate | compresser +# directory | répertoire # email | courriel # enlistment | enrôlement # entry | élément @@ -45,18 +46,23 @@ # hunk | section # to inflate | décompresser # to list | afficher +# loose object | objet esseulé # mapping | mise en correspondance # merge | fusion # pack | paquet -# patches | patchs +# patch (v) | appliquer une/des rustine(s) +# patches | rustines # pattern | motif # to prune | élaguer # to push | pousser # to rebase | rebaser # scheduler | planificateur # trailers | lignes terminales -# repository | dépôt +# regex | regex +# regular | +# expression | expression régulière # remote | distante (ou serveur distant) +# repository | dépôt # revision | révision # shallow | superficiel # shell | interpréteur de commandes @@ -64,6 +70,7 @@ # split (index) | index scindé # stash | remisage # to stash | remiser +# superproject | super-projet # tag | étiquette # template | modèle # thread | fil @@ -80,8 +87,8 @@ msgid "" msgstr "" "Project-Id-Version: git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-17 21:57+0000\n" -"PO-Revision-Date: 2024-07-19 20:25+0200\n" +"POT-Creation-Date: 2025-03-05 22:57+0000\n" +"PO-Revision-Date: 2025-03-06 16:46+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" @@ -169,7 +176,7 @@ msgid "No changes.\n" msgstr "Aucune modification.\n" msgid "Patch update" -msgstr "Mise à jour par patch" +msgstr "Mise à jour par rustine" msgid "Review diff" msgstr "Réviser la différence" @@ -267,7 +274,7 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "staging." msgstr "" -"Si le patch s'applique proprement, la section éditée sera immédiatement " +"Si la rustine s'applique proprement, la section éditée sera immédiatement " "marquée comme indexée." msgid "" @@ -303,7 +310,7 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "stashing." msgstr "" -"Si le patch s'applique proprement, la section éditée sera immédiatement " +"Si la rustine s'applique proprement, la section éditée sera immédiatement " "marquée comme remisée." msgid "" @@ -339,7 +346,7 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "unstaging." msgstr "" -"Si le patch s'applique proprement, la section éditée sera immédiatement " +"Si la rustine s'applique proprement, la section éditée sera immédiatement " "marquée comme desindexée." msgid "" @@ -375,7 +382,7 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "applying." msgstr "" -"Si le patch s'applique proprement, la section éditée sera immédiatement " +"Si la rustine s'applique proprement, la section éditée sera immédiatement " "marquée comme appliquée." msgid "" @@ -411,7 +418,7 @@ msgid "" "If the patch applies cleanly, the edited hunk will immediately be marked for " "discarding." msgstr "" -"Si le patch s'applique proprement, la section éditée sera immédiatement " +"Si la rustine s'applique proprement, la section éditée sera immédiatement " "marquée comme éliminée." msgid "" @@ -461,14 +468,14 @@ msgstr "" #, c-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Appliquer le changement de mode dans l'index et l'arbre de travail [y,n,q,a," -"d%s,?] ? " +"Appliquer le changement de mode dans l'index et l'arbre de travail " +"[y,n,q,a,d%s,?] ? " #, c-format msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Appliquer la suppression dans l'index et l'arbre de travail [y,n,q,a," -"d%s,?] ? " +"Appliquer la suppression dans l'index et l'arbre de travail " +"[y,n,q,a,d%s,?] ? " #, c-format msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? " @@ -628,7 +635,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - laisser cette section non décidée et aller à la suivante non-décidée\n" @@ -639,7 +646,7 @@ msgstr "" "/ - rechercher une section correspondant à une regex donnée\n" "s - découper la section en sections plus petites\n" "e - éditer manuellement la section actuelle\n" -"p - afficher la section actuelle\n" +"p - afficher la section actuelle, 'P' pour utiliser un paginateur\n" "? - afficher l'aide\n" #, c-format @@ -710,10 +717,10 @@ msgstr "Seuls des fichiers binaires ont changé." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Désactivez ce message avec \"git config advice.%s false\"" +"Désactivez ce message avec \"git config set advice.%s false\"" #, c-format msgid "%shint:%s%.*s%s\n" @@ -837,8 +844,8 @@ msgstr "" "\n" " git switch -\n" "\n" -"Désactivez ce conseil en renseignant la variable de configuration advice." -"detachedHead à false\n" +"Désactivez ce conseil en renseignant la variable de configuration " +"advice.detachedHead à false\n" "\n" #, c-format @@ -893,7 +900,7 @@ msgstr "la rustine est trop grosse" #, c-format msgid "Cannot prepare timestamp regexp %s" -msgstr "Impossible de préparer la regexp d'horodatage %s" +msgstr "Impossible de préparer la regex d'horodatage %s" #, c-format msgid "regexec returned %d for input: %s" @@ -901,7 +908,7 @@ msgstr "regexec a retourné %d pour l'entrée : %s" #, c-format msgid "unable to find filename in patch at line %d" -msgstr "nom de fichier du patch introuvable à la ligne %d" +msgstr "nom de fichier de la rustine introuvable à la ligne %d" #, c-format msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d" @@ -912,14 +919,14 @@ msgstr "" #, c-format msgid "git apply: bad git-diff - inconsistent new filename on line %d" msgstr "" -"git apply : mauvais format de git-diff - nouveau nom de fichier inconsistant " -"à la ligne %d" +"git apply : mauvais format de git-diff - nouveau nom de fichier incohérent à " +"la ligne %d" #, c-format msgid "git apply: bad git-diff - inconsistent old filename on line %d" msgstr "" -"git apply : mauvais format de git-diff - ancien nom de fichier inconsistant " -"à la ligne %d" +"git apply : mauvais format de git-diff - ancien nom de fichier incohérent à " +"la ligne %d" #, c-format msgid "git apply: bad git-diff - expected /dev/null on line %d" @@ -959,7 +966,7 @@ msgstr "recomptage : ligne inattendue : %.*s" #, c-format msgid "patch fragment without header at line %d: %.*s" -msgstr "fragment de patch sans en-tête à la ligne %d : %.*s" +msgstr "fragment de rustine sans en-tête à la ligne %d : %.*s" msgid "new file depends on old contents" msgstr "le nouveau fichier dépend de contenus anciens" @@ -969,7 +976,7 @@ msgstr "le fichier supprimé a encore du contenu" #, c-format msgid "corrupt patch at line %d" -msgstr "patch corrompu à la ligne %d" +msgstr "rustine corrompue à la ligne %d" #, c-format msgid "new file %s depends on old contents" @@ -985,15 +992,15 @@ msgstr "** attention : le fichier %s devient vide mais n'est pas supprimé" #, c-format msgid "corrupt binary patch at line %d: %.*s" -msgstr "patch binaire corrompu à la ligne %d : %.*s" +msgstr "rustine binaire corrompue à la ligne %d : %.*s" #, c-format msgid "unrecognized binary patch at line %d" -msgstr "patch binaire non reconnu à la ligne %d" +msgstr "rustine binaire non reconnue à la ligne %d" #, c-format msgid "patch with only garbage at line %d" -msgstr "patch totalement incompréhensible à la ligne %d" +msgstr "rustine totalement incompréhensible à la ligne %d" #, c-format msgid "unable to read symlink %s" @@ -1027,28 +1034,30 @@ msgstr "" #, c-format msgid "missing binary patch data for '%s'" -msgstr "données de patch binaire manquantes pour '%s'" +msgstr "données de rustine binaire manquantes pour '%s'" #, c-format msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'" msgstr "" -"impossible d'appliquer l'inverse d'un patch binaire à '%s' sans la section " -"inverse" +"impossible d'appliquer l'inverse d'une rustine binaire à '%s' sans la " +"section inverse" #, c-format msgid "cannot apply binary patch to '%s' without full index line" msgstr "" -"impossible d'appliquer un patch binaire à '%s' sans la ligne complète d'index" +"impossible d'appliquer une rustine binaire à '%s' sans la ligne complète " +"d'index" #, c-format msgid "" "the patch applies to '%s' (%s), which does not match the current contents." msgstr "" -"le patch s'applique à '%s' (%s), ce qui ne correspond pas au contenu actuel." +"la rustine s'applique à '%s' (%s), ce qui ne correspond pas au contenu " +"actuel." #, c-format msgid "the patch applies to an empty '%s' but it is not empty" -msgstr "le patch s'applique à un '%s' vide mais ce n'est pas vide" +msgstr "la rustine s'applique à un '%s' vide mais ce n'est pas vide" #, c-format msgid "the necessary postimage %s for '%s' cannot be read" @@ -1056,17 +1065,17 @@ msgstr "l'image postérieure nécessaire %s pour '%s' ne peut pas être lue" #, c-format msgid "binary patch does not apply to '%s'" -msgstr "le patch binaire ne s'applique par correctement à '%s'" +msgstr "la rustine binaire ne s'applique par correctement à '%s'" #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" -"le patch binaire sur '%s' crée un résultat incorrect (%s attendu, mais %s " +"la rustine binaire sur '%s' crée un résultat incorrect (%s attendu, mais %s " "trouvé)" #, c-format msgid "patch failed: %s:%ld" -msgstr "le patch a échoué : %s:%ld" +msgstr "l'application de la rustine a échoué : %s:%ld" #, c-format msgid "cannot checkout %s" @@ -1110,18 +1119,18 @@ msgstr "Échec de l'application de la fusion à 3 points…\n" #, c-format msgid "Applied patch to '%s' with conflicts.\n" -msgstr "Patch %s appliqué avec des conflits.\n" +msgstr "Rustine %s appliquée avec des conflits.\n" #, c-format msgid "Applied patch to '%s' cleanly.\n" -msgstr "Patch %s appliqué proprement.\n" +msgstr "Rustine %s appliquée proprement.\n" #, c-format msgid "Falling back to direct application...\n" msgstr "Retour à une application directe…\n" msgid "removal patch leaves file contents" -msgstr "le patch de suppression laisse un contenu dans le fichier" +msgstr "la rustine de suppression laisse un contenu dans le fichier" #, c-format msgid "%s: wrong type" @@ -1158,11 +1167,11 @@ msgstr "le fichier affecté '%s' est au-delà d'un lien symbolique" #, c-format msgid "%s: patch does not apply" -msgstr "%s : le patch ne s'applique pas" +msgstr "%s : la rustine ne s'applique pas" #, c-format msgid "Checking patch %s..." -msgstr "Vérification du patch %s..." +msgstr "Vérification de la rustine %s..." #, c-format msgid "sha1 information is lacking or useless for submodule %s" @@ -1191,7 +1200,7 @@ msgstr "suppression de %s dans l'index impossible" #, c-format msgid "corrupt patch for submodule %s" -msgstr "patch corrompu pour le sous-module %s" +msgstr "rustine corrompue pour le sous-module %s" #, c-format msgid "unable to stat newly created file '%s'" @@ -1221,7 +1230,7 @@ msgstr "écriture du fichier '%s' mode %o impossible" #, c-format msgid "Applied patch %s cleanly." -msgstr "Patch %s appliqué proprement." +msgstr "Rustine %s appliquée proprement." msgid "internal error" msgstr "erreur interne" @@ -1229,8 +1238,8 @@ msgstr "erreur interne" #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." -msgstr[0] "Application du patch %%s avec %d rejet..." -msgstr[1] "Application du patch %%s avec %d rejets..." +msgstr[0] "Application de la rustine %%s avec %d rejet..." +msgstr[1] "Application de la rustine %%s avec %d rejets..." #, c-format msgid "cannot open %s" @@ -1260,7 +1269,7 @@ msgstr "lecture du fichier d'index impossible" #, c-format msgid "can't open patch '%s': %s" -msgstr "ouverture impossible du patch '%s' :%s" +msgstr "ouverture impossible de la rustine '%s' :%s" #, c-format msgid "squelched %d whitespace error" @@ -1296,40 +1305,49 @@ msgid "remove <num> leading slashes from traditional diff paths" msgstr "supprimer <num> barres obliques des chemins traditionnels de diff" msgid "ignore additions made by the patch" -msgstr "ignorer les additions réalisées par le patch" +msgstr "ignorer les additions réalisées par la rustine" msgid "instead of applying the patch, output diffstat for the input" -msgstr "au lieu d'appliquer le patch, afficher le diffstat de l'entrée" +msgstr "au lieu d'appliquer la rustine, afficher le diffstat de l'entrée" msgid "show number of added and deleted lines in decimal notation" msgstr "" "afficher le nombre de lignes ajoutées et supprimées en notation décimale" msgid "instead of applying the patch, output a summary for the input" -msgstr "au lieu d'appliquer le patch, afficher un résumé de l'entrée" +msgstr "au lieu d'appliquer la rustine, afficher un résumé de l'entrée" msgid "instead of applying the patch, see if the patch is applicable" -msgstr "au lieu d'appliquer le patch, voir si le patch est applicable" +msgstr "au lieu d'appliquer la rustine, voir si la rustine est applicable" msgid "make sure the patch is applicable to the current index" -msgstr "s'assurer que le patch est applicable sur l'index actuel" +msgstr "s'assurer que la rustine est applicable sur l'index actuel" msgid "mark new files with `git add --intent-to-add`" msgstr "marquer les nouveaux fichiers `git add --intent-to-add`" msgid "apply a patch without touching the working tree" -msgstr "appliquer les patch sans toucher à la copie de travail" +msgstr "appliquer les rustines sans toucher à la copie de travail" msgid "accept a patch that touches outside the working area" -msgstr "accepter un patch qui touche hors de la copie de travail" +msgstr "accepter une rustine qui touche hors de la copie de travail" msgid "also apply the patch (use with --stat/--summary/--check)" -msgstr "appliquer aussi le patch (à utiliser avec --stat/--summary/--check)" +msgstr "appliquer aussi la rustine (à utiliser avec --stat/--summary/--check)" msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "" "tenter une fusion à 3 points, revenir à un rustinage normal en cas d'échec" +msgid "for conflicts, use our version" +msgstr "pour les conflits, utiliser notre version (our)" + +msgid "for conflicts, use their version" +msgstr "pour les conflits, utiliser leur version (their)" + +msgid "for conflicts, use a union version" +msgstr "pour les conflits, utiliser l'union des versions" + msgid "build a temporary index based on embedded index information" msgstr "" "construire un index temporaire fondé sur l'information de l'index embarqué" @@ -1352,7 +1370,7 @@ msgid "ignore changes in whitespace when finding context" msgstr "ignorer des modifications d'espace lors de la recherche de contexte" msgid "apply the patch in reverse" -msgstr "appliquer le patch en sens inverse" +msgstr "appliquer la rustine en sens inverse" msgid "don't expect at least one line of context" msgstr "ne pas s'attendre à au moins une ligne de contexte" @@ -1380,6 +1398,9 @@ msgstr "préfixer tous les noms de fichier avec <root>" msgid "don't return error for empty patches" msgstr "ne pas renvoyer d'erreur pour les rustines vides" +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs et --union requièrent --3way" + #, c-format msgid "cannot stream blob %s" msgstr "impossible de transmettre le blob %s en flux" @@ -1453,6 +1474,10 @@ msgstr "nom d'objet invalide : %s" msgid "not a tree object: %s" msgstr "objet arbre invalide : %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "échec du dépaquetage de l'objet arbre %s" + #, c-format msgid "File not found: %s" msgstr "Fichier non trouvé : %s" @@ -1908,7 +1933,7 @@ msgid "could not read the index" msgstr "impossible de lire l'index" msgid "editing patch failed" -msgstr "échec de l'édition du patch" +msgstr "échec de l'édition de la rustine" #, c-format msgid "could not stat '%s'" @@ -2016,7 +2041,7 @@ msgid "adding embedded git repository: %s" msgstr "dépôt git embarqué ajouté : %s" msgid "Use -f if you really want to add them." -msgstr "Utilisez -f si vous voulez vraiment les ajouter<." +msgstr "Utilisez -f si vous voulez vraiment les ajouter." msgid "adding files failed" msgstr "échec de l'ajout de fichiers" @@ -2088,10 +2113,10 @@ msgstr "impossible d'ouvrir '%s' en écriture" #, c-format msgid "could not parse patch '%s'" -msgstr "impossible d'analyser le patch '%s'" +msgstr "impossible d'analyser la rustine '%s'" msgid "Only one StGIT patch series can be applied at once" -msgstr "Seulement une série de patchs StGIT peut être appliquée à la fois" +msgstr "Seulement une série de rustines StGIT peut être appliquée à la fois" msgid "invalid timestamp" msgstr "horodatage invalide" @@ -2103,14 +2128,14 @@ msgid "invalid timezone offset" msgstr "décalage horaire invalide" msgid "Patch format detection failed." -msgstr "Échec de détection du format du patch." +msgstr "Échec de détection du format de la rustine." #, c-format msgid "failed to create directory '%s'" msgstr "échec de la création du répertoire '%s'" msgid "Failed to split patches." -msgstr "Échec de découpage des patchs." +msgstr "Échec de découpage des rustines." #, c-format msgid "When you have resolved this problem, run \"%s --continue\".\n" @@ -2130,8 +2155,8 @@ msgstr "" #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "" -"Pour restaurer la branche originale et arrêter de patcher, lancez \"%s --" -"abort\"." +"Pour restaurer la branche originale et arrêter d'appliquer des rustines, " +"lancez \"%s --abort\"." msgid "Patch sent with format=flowed; space at the end of lines might be lost." msgstr "" @@ -2163,11 +2188,11 @@ msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." msgstr "" -"Avez-vous édité le patch à la main ?\n" +"Avez-vous édité la rustine à la main ?\n" "Il ne s'applique pas aux blobs enregistrés dans son index." msgid "Falling back to patching base and 3-way merge..." -msgstr "Retour à un patch de la base et fusion à 3 points..." +msgstr "Retour à une rustine de la base et fusion à 3 points..." msgid "Failed to merge in the changes." msgstr "Échec d'intégration des modifications." @@ -2201,7 +2226,7 @@ msgstr "impossible d'écrire le fichier d'index" #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" -msgstr "Index sale : impossible d'appliquer des patchs (sales : %s)" +msgstr "Index sale : impossible d'appliquer des rustines (sales : %s)" #, c-format msgid "Skipping: %.*s" @@ -2212,7 +2237,7 @@ msgid "Creating an empty commit: %.*s" msgstr "Création d'un commit vide : %.*s" msgid "Patch is empty." -msgstr "Le patch actuel est vide." +msgstr "La rustine actuelle est vide." #, c-format msgid "Applying: %.*s" @@ -2227,7 +2252,8 @@ msgstr "l'application de la rustine a échoué à %s %.*s" msgid "Use 'git am --show-current-patch=diff' to see the failed patch" msgstr "" -"Utilisez 'git am --show-current-patch=diff' pour visualiser le patch en échec" +"Utilisez 'git am --show-current-patch=diff' pour visualiser la rustine en " +"échec" msgid "No changes - recorded it as an empty commit." msgstr "aucune modification - enregistré comme un commit vide." @@ -2239,8 +2265,8 @@ msgid "" msgstr "" "Aucun changement - avez-vous oublié d'utiliser 'git add' ?\n" "S'il n'y a plus rien à indexer, il se peut qu'autre chose ait déjà\n" -"introduit les mêmes changements ; vous pourriez avoir envie de sauter ce " -"patch." +"introduit les mêmes changements ; vous pourriez avoir envie de sauter cette " +"rustine." msgid "" "You still have unmerged paths in your index.\n" @@ -2327,28 +2353,30 @@ msgid "format" msgstr "format" msgid "format the patch(es) are in" -msgstr "format de présentation des patchs" +msgstr "format de présentation des rustines" msgid "override error message when patch failure occurs" -msgstr "surcharger le message d'erreur lors d'un échec d'application de patch" +msgstr "" +"surcharger le message d'erreur lors d'un échec d'application d'une rustine" msgid "continue applying patches after resolving a conflict" -msgstr "continuer à appliquer les patchs après résolution d'un conflit" +msgstr "continuer à appliquer les rustines après résolution d'un conflit" msgid "synonyms for --continue" msgstr "synonymes de --continue" msgid "skip the current patch" -msgstr "sauter le patch courant" +msgstr "sauter la rustine courante" msgid "restore the original branch and abort the patching operation" -msgstr "restaurer la branche originale et abandonner les applications de patch" +msgstr "" +"restaurer la branche originale et abandonner les applications de rustines" msgid "abort the patching operation but keep HEAD where it is" -msgstr "abandonne l'opération de patch mais garde HEAD où il est" +msgstr "abandonne l'opération de rustine mais garde HEAD où il est" msgid "show the patch being applied" -msgstr "afficher le patch en cours d'application" +msgstr "afficher la rustine en cours d'application" msgid "try to apply current patch again" msgstr "essayer d'appliquer de nouveau la rustine" @@ -2424,6 +2452,18 @@ msgstr "git archive : erreur de protocole" msgid "git archive: expected a flush" msgstr "git archive : vidage attendu" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "problème lors du chargement de l'extraction clairsemée" + +msgid "Minimum number of objects to request at a time" +msgstr "Nombre minimum d'objets à demander à chaque fois" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Restreindre les objets manquants à l'extraction clairsemée actuelle" + msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2566,9 +2606,6 @@ msgstr "" "Les options supportées sont : --term-good|--term-old et --term-bad|--term-" "new." -msgid "revision walk setup failed\n" -msgstr "échec de la préparation du parcours des révisions\n" - #, c-format msgid "could not open '%s' for appending" msgstr "impossible d'ouvrir '%s' en ajout" @@ -3114,11 +3151,11 @@ msgid "HEAD not found below refs/heads!" msgstr "HEAD non trouvée sous refs/heads !" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" -"brancher avec --recurse-submodules ne peut être utilisé que si submodule." -"propagateBranches est activé" +"brancher avec --recurse-submodules ne peut être utilisé que si " +"submodule.propagateBranches est activé" msgid "--recurse-submodules can only be used to create branches" msgstr "--recurse-submodules ne peut être utilisé que pour créer des branches" @@ -3192,10 +3229,6 @@ msgstr "" msgid "git version:\n" msgstr "version git ::\n" -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "échec de uname() avec l'erreur '%s' (%d)\n" - msgid "compiler info: " msgstr "info compilateur : " @@ -3364,7 +3397,7 @@ msgstr "%s nécessite des arguments" #, c-format msgid "%s takes no arguments" -msgstr "%s n'accepte aucune argument" +msgstr "%s n'accepte aucun argument" msgid "only one batch option may be specified" msgstr "une seule option de traitement ne peut être spécifiée à la fois" @@ -3569,9 +3602,14 @@ msgstr "git check-mailmap [<options>] <contact>..." msgid "also read contacts from stdin" msgstr "lire aussi les contacts depuis l'entrée standard" -#, c-format -msgid "unable to parse contact: %s" -msgstr "impossible d'analyser le contact : %s" +msgid "read additional mailmap entries from file" +msgstr "lire des entrées supplémentaires de mailmap depuis un fichier" + +msgid "blob" +msgstr "blob" + +msgid "read additional mailmap entries from blob" +msgstr "lire des entrées supplémentaires depuis un blob" msgid "no contacts specified" msgstr "aucun contact spécifié" @@ -3928,6 +3966,10 @@ msgstr "impossible d'utiliser des chemins avec un basculement de branches" msgid "'%s' cannot be used with switching branches" msgstr "'%s' ne peut pas être utilisé avec un basculement de branches" +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "'%s' requiert les chemins à extraire" + #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s' ne peut pas être utilisé avec '%s'" @@ -3971,9 +4013,8 @@ msgstr "nouvelle branche non née" msgid "update ignored files (default)" msgstr "mettre à jour les fichiers ignorés (par défaut)" -msgid "do not check if another worktree is holding the given ref" -msgstr "" -"ne pas vérifier si une autre copie de travail contient le référence fournie" +msgid "do not check if another worktree is using this branch" +msgstr "ne pas vérifier si une autre copie-de-travail utilise cette branche" msgid "checkout our version for unmerged files" msgstr "extraire notre version pour les fichiers non fusionnés" @@ -4210,8 +4251,93 @@ msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "" "clean.requireForce positionné est true et -f non fourni ; refus de nettoyer" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<options>] [--] <dépôt> [<répertoire>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info : impossible d'ajouter une alternative pour '%s' : %s\n" + +#, c-format +msgid "failed to stat '%s'" +msgstr "échec du stat de '%s'" + +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s existe et n'est pas un répertoire" + +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "'%s' est un lien symbolique, refus de cloner avec --local" + +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "échec du démarrage un itérateur sur '%s'" + +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "le lien symbolique '%s' existe, refus de cloner avec --local" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "échec pour délier '%s'" + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "le lien dur ne peut pas être vérifié à '%s'" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "le lien dur est différent de la source à '%s'" + +#, c-format +msgid "failed to create link '%s'" +msgstr "échec de la création du lien '%s'" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "échec de la copie vers '%s'" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "échec de l'itération sur '%s'" + +#, c-format +msgid "done.\n" +msgstr "fait.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Le clone a réussi, mais l'extraction a échoué.\n" +"Vous pouvez inspecter ce qui a été extrait avec 'git status'\n" +"et réessayer avec 'git restore --source=HEAD :/'\n" + +msgid "remote did not send all necessary objects" +msgstr "le serveur distant n'a pas envoyé tous les objets nécessaires" + +#, c-format +msgid "unable to update %s" +msgstr "impossible de mettre à jour %s" + +msgid "failed to initialize sparse-checkout" +msgstr "échec lors de l'initialisation l'extraction clairsemée" + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "" +"la HEAD distante réfère à une référence non existante, impossible de " +"l'extraire" + +msgid "unable to checkout working tree" +msgstr "impossible d'extraire la copie de travail" + +msgid "unable to write parameters to config file" +msgstr "impossible d'écrire les paramètres dans le fichier de configuration" + +msgid "cannot repack to clean up" +msgstr "impossible de remballer pour nettoyer" + +msgid "cannot unlink temporary alternates file" +msgstr "impossible de délier le fichier temporaire alternates" msgid "don't clone shallow repository" msgstr "ne pas cloner un dépôt superficiel" @@ -4264,6 +4390,9 @@ msgstr "utiliser <nom> au lieu de 'origin' pour suivre la branche amont" msgid "checkout <branch> instead of the remote's HEAD" msgstr "extraire <branche> au lieu de la HEAD du répertoire distant" +msgid "clone single revision <rev> and check out" +msgstr "cloner la révision unique <rév> et l'extraire" + msgid "path to git-upload-pack on the remote" msgstr "chemin vers git-upload-pack sur le serveur distant" @@ -4276,20 +4405,18 @@ msgstr "créer un clone superficiel de cette profondeur" msgid "create a shallow clone since a specific time" msgstr "créer un clone superficiel depuis une date spécifique" -msgid "revision" -msgstr "révision" +msgid "ref" +msgstr "ref" -msgid "deepen history of shallow clone, excluding rev" -msgstr "" -"approfondir l'historique d'un clone superficiel en excluant une révision" +msgid "deepen history of shallow clone, excluding ref" +msgstr "approfondit l'historique d'un clone superficiel en excluant une ref" msgid "clone only one branch, HEAD or --branch" msgstr "cloner seulement une branche, HEAD ou --branch" -msgid "don't clone any tags, and make later fetches not to follow them" +msgid "clone tags, and make later fetches not to follow them" msgstr "" -"ne pas cloner les tags et indiquer aux récupérations futures de ne pas le " -"faire" +"cloner les tags et indiquer aux récupérations futures de ne pas le faire" msgid "any cloned submodules will be shallow" msgstr "tous les sous-modules clonés seront superficiels" @@ -4335,97 +4462,8 @@ msgstr "" "un URI pour télécharger des paquets avant de récupérer depuis le distant " "d'origine" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info : impossible d'ajouter une alternative pour '%s' : %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "échec du stat de '%s'" - -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s existe et n'est pas un répertoire" - -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "'%s' est un lien symbolique, refus de cloner avec --local" - -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "échec du démarrage un itérateur sur '%s'" - -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "le lien symbolique '%s' existe, refus de cloner avec --local" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "échec pour délier '%s'" - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "le lien dur ne peut pas être vérifier à '%s'" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "le lien dur est différent de la source à '%s'" - -#, c-format -msgid "failed to create link '%s'" -msgstr "échec de la création du lien '%s'" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "échec de la copie vers '%s'" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "échec de l'itération sur '%s'" - -#, c-format -msgid "done.\n" -msgstr "fait.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Le clone a réussi, mais l'extraction a échoué.\n" -"Vous pouvez inspecter ce qui a été extrait avec 'git status'\n" -"et réessayer avec 'git restore --source=HEAD :/'\n" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Impossible de trouver la branche distante '%s' à cloner." - -msgid "remote did not send all necessary objects" -msgstr "le serveur distant n'a pas envoyé tous les objets nécessaires" - -#, c-format -msgid "unable to update %s" -msgstr "impossible de mettre à jour %s" - -msgid "failed to initialize sparse-checkout" -msgstr "échec lors de l'initialisation l'extraction clairsemée" - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "" -"la HEAD distante réfère à une référence non existante, impossible de " -"l'extraire" - -msgid "unable to checkout working tree" -msgstr "impossible d'extraire la copie de travail" - -msgid "unable to write parameters to config file" -msgstr "impossible d'écrire les paramètres dans le fichier de configuration" - -msgid "cannot repack to clean up" -msgstr "impossible de remballer pour nettoyer" - -msgid "cannot unlink temporary alternates file" -msgstr "impossible de délier le fichier temporaire alternates" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<options>] [--] <dépôt> [<répertoire>]" msgid "Too many arguments." msgstr "Trop d'arguments." @@ -4531,6 +4569,10 @@ msgstr "le transport distant a retourné une erreur" msgid "Remote branch %s not found in upstream %s" msgstr "La branche distante %s n'a pas été trouvée dans le dépôt amont %s" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "La révision distante %s n'a pas été trouvée dans le dépôt amont %s" + msgid "You appear to have cloned an empty repository." msgstr "Vous semblez avoir cloné un dépôt vide." @@ -4705,9 +4747,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree : échec de la lecture" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4715,14 +4757,14 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" -" [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" +"reword):]<commit>]\n" +" [-F <fichier> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<auteur>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" " [-i | -o] [--pathspec-from-file=<fichier> [--pathspec-file-nul]]\n" -" [(--trailer <symbole>[(=|:)<valeur>])...] [-S[<id-clé>]]\n" +" [(--trailer <jeton>[(=|:)<valeur>])...] [-S[<id-clé>]]\n" " [--] [<spéc-de-chemin>...]" msgid "git status [<options>] [--] [<pathspec>...]" @@ -5222,12 +5264,11 @@ msgstr "" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" "git config get [<option-de-fichier>] [<option-d-affichage>] [--includes] [--" -"all] [--regexp=<regexp>] [--value=<valeur>] [--fixed-value] [--" -"default=<défaut>] <name>" +"all] [--regexp] [--value=<valeur>] [--fixed-value] [--default=<défaut>] " +"<name>" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5238,10 +5279,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" "git config unset [<option-de-fichier>] [--all] [--value=<valeur>] [--fixed-" -"value] <nom> <valeur>" +"value] <nom>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "" @@ -5257,6 +5298,15 @@ msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "" "git config [<option-de-fichier>] --get-colorbool <nom> [<stdout-est-tty>]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<option-de-fichier>] [<option-d-affichage>] [--includes] [--" +"all] [--regexp=<regexp>] [--value=<valeur>] [--fixed-value] [--" +"default=<défaut>] <name>" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5460,7 +5510,7 @@ msgid "value" msgstr "valeur" msgid "use default value when missing entry" -msgstr "utiliser le valeur par défaut quand l'entrée n'existe pas" +msgstr "utiliser la valeur par défaut quand l'entrée n'existe pas" msgid "--fixed-value only applies with 'value-pattern'" msgstr "--fixed-value ne s'applique qu'à 'motif-de-valeur'" @@ -5497,7 +5547,7 @@ msgid "" " Use a regexp, --add or --replace-all to change %s." msgstr "" "impossible de surcharger des valeurs multiples avec une seule valeur\n" -" Utilisez une regexp, --add ou --replace-all pour modifier %s." +" Utilisez une regex, --add ou --replace-all pour modifier %s." #, c-format msgid "no such section: %s" @@ -5523,7 +5573,7 @@ msgid "get all values: key [<value-pattern>]" msgstr "obtenir toutes les valeurs : clé [<motif-de-valeur>]" msgid "get values for regexp: name-regex [<value-pattern>]" -msgstr "obtenir les valeur pour la regexp : name-regex [<motif-de-valeur>]" +msgstr "obtenir les valeurs pour la regex : name-regex [<motif-de-valeur>]" msgid "get value specific for the URL: section[.var] URL" msgstr "obtenir la valeur spécifique pour l'URL : section[.var] URL" @@ -5560,7 +5610,7 @@ msgid "find the color setting: slot [<stdout-is-tty>]" msgstr "trouver le réglage de la couleur : slot [<stdout-est-tty>]" msgid "with --get, use default value when missing entry" -msgstr "avec --get, utiliser le valeur par défaut quand l'entrée n'existe pas" +msgstr "avec --get, utiliser la valeur par défaut quand l'entrée n'existe pas" msgid "--get-color and variable type are incoherent" msgstr "--get-color et le type de la variable sont incohérents" @@ -5597,7 +5647,7 @@ msgstr "" "Les permissions de votre répertoire de socket sont trop permissives ;\n" "les autres utilisateurs pourraient lire vos identifiants secrets. Lancez :\n" "\n" -" chmod 0700 %s" +"\tchmod 0700 %s" msgid "print debugging messages to stderr" msgstr "afficher les messages de debug sur stderr" @@ -5678,13 +5728,8 @@ msgid "traversed %lu commits\n" msgstr "%lu commits parcourus\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"plus de %i étiquettes ont été trouvées; seules les %i plus récentes sont " -"affichées\n" -"abandon de la recherche à %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "%i étiquettes trouvées ; recherche abandonnée à %s\n" #, c-format msgid "describe %s\n" @@ -6077,8 +6122,8 @@ msgstr "" "'git config fetch.showForcedUpdates false' pour éviter cette vérification\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s n'a pas envoyé tous les objets nécessaires\n" +msgid "%s did not send all necessary objects" +msgstr "%s n'a pas envoyé tous les objets nécessaires" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -6117,8 +6162,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "la valeur \"%2$s\" de l'option \"%1$s\" est invalide pour %3$s" #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "l'option \"%s\" est ignorée pour %s\n" +msgid "option \"%s\" is ignored for %s" +msgstr "l'option \"%s\" est ignorée pour %s" #, c-format msgid "%s is not a valid object" @@ -6128,6 +6173,21 @@ msgstr "%s n'est pas un objet valide" msgid "the object %s does not exist" msgstr "l'objet %s n'existe pas" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Lancez 'git remote set-head %s %s' pour suivre la modification, ou\n" +"réglez l'option de configuration 'remote.%s.followRemoteHEAD' à une\n" +"valeur différente si vous ne souhaitez pas voir ce message. Lancer\n" +"spécifiquement 'git config set remote.%s.followRemoteHEAD warn-if-not-branch-" +"%s'\n" +"va désactiver l'alerte jusqu'à ce que le distant change HEAD." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "branches multiples détectées, imcompatible avec --set-upstream" @@ -6268,6 +6328,9 @@ msgstr "correspondance de référence" msgid "specify fetch refmap" msgstr "spécifier une correspondance de référence pour la récupération" +msgid "revision" +msgstr "révision" + msgid "report that we have only objects reachable from this object" msgstr "rapporte que nous n'avons que des objets joignables depuis cet objet" @@ -6325,8 +6388,8 @@ msgid "protocol does not support --negotiate-only, exiting" msgstr "Le protocole ne prend pas en charge --negotiate-only, abandon" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" "--filter ne peut être utilisé qu'avec le dépôt distant configuré dans " "extensions.partialclone" @@ -6424,7 +6487,7 @@ msgid "config key storing a list of repository paths" msgstr "clé de config qui stocke la liste des chemins de dépôts" msgid "keep going even if command fails in a repository" -msgstr "continuer mêm si la commande échoue dans un dépôt" +msgstr "continuer même si la commande échoue dans un dépôt" msgid "missing --config=<config>" msgstr "--config=<config> manquant" @@ -6639,7 +6702,7 @@ msgid "check only connectivity" msgstr "ne vérifier que la connectivité" msgid "enable more strict checking" -msgstr "activer une vérification plus strict" +msgstr "activer une vérification plus stricte" msgid "write dangling objects in .git/lost-found" msgstr "écrire les objets en suspens dans .git/lost-found" @@ -6797,6 +6860,9 @@ msgstr "être plus consciencieux (durée de traitement allongée)" msgid "enable auto-gc mode" msgstr "activer le mode auto-gc" +msgid "perform garbage collection in the background" +msgstr "réaliser le glanage de cellules en arrière plan" + msgid "force running gc even if there may be another gc running" msgstr "" "forcer le lancement du ramasse-miettes même si un autre ramasse-miettes " @@ -6805,6 +6871,9 @@ msgstr "" msgid "repack all other packs except the largest pack" msgstr "recompacter tous les autres paquets excepté le plus gros paquet" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "préfixe de paquet pour stocker un paquet contenant les objets élagués" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "impossible d'analyser gc.logExpiry %s" @@ -6837,7 +6906,7 @@ msgstr "" msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" -"Il y a trop d'objets seuls inaccessibles ; lancez 'git prune' pour les " +"Il y a trop d'objets esseulés inaccessibles ; lancez 'git prune' pour les " "supprimer." msgid "" @@ -6897,6 +6966,9 @@ msgstr "la tâche '%s' ne peut pas être sélectionnée plusieurs fois" msgid "run tasks based on the state of the repository" msgstr "lancer les tâches selon l'état du dépôt" +msgid "perform maintenance in the background" +msgstr "réaliser la maintenance en arrière-plan" + msgid "frequency" msgstr "fréquence" @@ -6995,9 +7067,27 @@ msgstr "ni les minuteurs systemd ni crontab ne sont disponibles" msgid "%s scheduler is not available" msgstr "le planificateur %s n'est pas disponible" -msgid "another process is scheduling background maintenance" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"impossible de créer '%s.lock' : %s.\n" +"\n" +"Il semble qu'un processus git-maintenance(1) programmé est déjà lancé dans\n" +"ce dépôt. Veuillez vous assurer qu'aucun processus de maintenance n'est " +"lancé\n" +"et réessayez. Si l'échec persiste, un processus git-maintenance(1) peut " +"avoir\n" +"planté dans ce dépôt : supprimez le fichier manuellement pour poursuivre." + +msgid "cannot acquire lock for scheduled background maintenance" msgstr "" -"un autre processus est en train de programmer une maintenance en tâche de " +"impossible d'acquérir le verrou pour une maintenance programmée en tâche de " "fond" msgid "git maintenance start [--scheduler=<scheduler>]" @@ -7578,9 +7668,29 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "longueur chaînée = %d : %lu objet" msgstr[1] "longueur chaînée = %d : %lu objets" +msgid "could not start pack-objects to repack local links" +msgstr "" +"impossible de démarrer pack-objects pour ré-empaqueter les liens locaux" + +msgid "failed to feed local object to pack-objects" +msgstr "échéc de la fourniture les objets locaux à pack-objects" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack : attente de lignes d'Id d'objets en hexa complet seulement " +"depuis les objects de paquet." + +msgid "could not finish pack-objects to repack local links" +msgstr "" +"impossible de terminer pack-objects pour ré-empaqueter les objets locaux" + msgid "Cannot come back to cwd" msgstr "Impossible de revenir au répertoire de travail courant" +#, c-format +msgid "bad --pack_header: %s" +msgstr "mauvais --pack_header : %s" + #, c-format msgid "bad %s" msgstr "mauvais %s" @@ -7589,6 +7699,9 @@ msgstr "mauvais %s" msgid "unknown hash algorithm '%s'" msgstr "algorithme d'empreinte inconnu '%s'" +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor ne peut pas être utilisé avec un nom de paquet" + msgid "--stdin requires a git repository" msgstr "--stdin requiert un dépôt git" @@ -7776,9 +7889,6 @@ msgstr "" msgid "Final output: %d %s\n" msgstr "Sortie finale : %d %s\n" -msgid "unable to create temporary object directory" -msgstr "impossible de créer un répertoire d'objets temporaire" - #, c-format msgid "git show %s: bad file" msgstr "git show %s : fichier incorrect" @@ -7861,7 +7971,7 @@ msgid "base commit shouldn't be in revision list" msgstr "le commit de base ne devrait pas faire partie de la liste de révisions" msgid "cannot get patch id" -msgstr "impossible d'obtenir l'id du patch" +msgstr "impossible d'obtenir l'id de la rustine" msgid "failed to infer range-diff origin of current series" msgstr "" @@ -7874,13 +7984,13 @@ msgstr "" "utilisation de '%s' comme une différence d'intervalle pour la série actuelle" msgid "use [PATCH n/m] even with a single patch" -msgstr "utiliser [PATCH n/m] même avec un patch unique" +msgstr "utiliser [PATCH n/m] même avec une rustine unique" msgid "use [PATCH] even with multiple patches" -msgstr "utiliser [PATCH] même avec des patchs multiples" +msgstr "utiliser [PATCH] même avec des rustines multiples" msgid "print patches to standard out" -msgstr "afficher les patchs sur la sortie standard" +msgstr "afficher les rustines sur la sortie standard" msgid "generate a cover letter" msgstr "générer une lettre de motivation" @@ -7896,7 +8006,7 @@ msgid "use <sfx> instead of '.patch'" msgstr "utiliser <sfx> au lieu de '.patch'" msgid "start numbering patches at <n> instead of 1" -msgstr "démarrer la numérotation des patchs à <n> au lieu de 1" +msgstr "démarrer la numérotation des rustines à <n> au lieu de 1" msgid "reroll-count" msgstr "reroll-count" @@ -7940,10 +8050,10 @@ msgid "output all-zero hash in From header" msgstr "écrire une empreinte à zéro dans l'entête From" msgid "don't include a patch matching a commit upstream" -msgstr "ne pas inclure un patch correspondant à un commit amont" +msgstr "ne pas inclure de rustine correspondant à un commit amont" msgid "show patch format instead of default (patch + stat)" -msgstr "afficher le format du patch au lieu du défaut (patch + stat)" +msgstr "afficher le format de la rustine au lieu du défaut (rustine + stat)" msgid "Messaging" msgstr "Communication" @@ -7980,10 +8090,10 @@ msgid "boundary" msgstr "limite" msgid "attach the patch" -msgstr "attacher le patch" +msgstr "attacher la rustine" msgid "inline the patch" -msgstr "patch à l'intérieur" +msgstr "incorporer la rustine à l'intérieur" msgid "enable message threading, styles: shallow, deep" msgstr "" @@ -7999,17 +8109,17 @@ msgid "base-commit" msgstr "commit-de-base" msgid "add prerequisite tree info to the patch series" -msgstr "ajouter un arbre prérequis à la série de patchs" +msgstr "ajouter un arbre prérequis à la série de rustines" msgid "add a signature from a file" msgstr "ajouter une signature depuis un fichier" msgid "don't print the patch filenames" -msgstr "ne pas afficher les noms de fichiers des patchs" +msgstr "ne pas afficher les noms de fichiers des rustines" msgid "show progress while generating patches" msgstr "" -"afficher la barre de progression durant la phase de génération des patchs" +"afficher la barre de progression durant la phase de génération des rustines" msgid "show changes against <rev> in cover letter or single patch" msgstr "" @@ -8074,7 +8184,7 @@ msgid "unable to read signature file '%s'" msgstr "lecture du fichier de signature '%s' impossible" msgid "Generating patches" -msgstr "Génération des patchs" +msgstr "Génération des rustines" msgid "failed to create output files" msgstr "échec de création des fichiers en sortie" @@ -8192,7 +8302,7 @@ msgid "" " [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n" " [--symref] [<repository> [<patterns>...]]" msgstr "" -"git ls-remote [--brances] [--tags] [--refs] [--upload-pack=<exec>]\n" +"git ls-remote [--branches] [--tags] [--refs] [--upload-pack=<exec>]\n" " [-q | --quiet] [--exit-code] [--get-url] [--sort=<clé>]\n" " [--symref] [<dépôt> [<motif>...]]" @@ -8365,15 +8475,6 @@ msgstr "utiliser une fusion basée sur diff3" msgid "use a zealous diff3 based merge" msgstr "utiliser une fusion basée sur un diff3 zélée" -msgid "for conflicts, use our version" -msgstr "pour les conflits, utiliser notre version (our)" - -msgid "for conflicts, use their version" -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>" @@ -8478,10 +8579,6 @@ msgstr "option de stratégie inconnue : -X%s" msgid "malformed input line: '%s'." msgstr "ligne en entrée malformée : '%s'." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "la fusion ne peut pas continuer ; résultat non propre retourné %d" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<options>] [<commit>...]" @@ -8848,6 +8945,9 @@ msgstr "paquet à réutiliser lors du calcul de bitmap de multi-paquet" msgid "write multi-pack bitmap" msgstr "écriture du bitmap de multi-paquet" +msgid "write a new incremental MIDX" +msgstr "écrire un nouveau MIDX incrémental" + msgid "write multi-pack index containing only given indexes" msgstr "écrire l'index multi-paquet ne contenant que les index fournis" @@ -8984,11 +9084,11 @@ msgstr "git notes [--ref <références-notes>] [list [<object>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <référence-notes>] add [-f] [--allow-empty] [--" "[no-]separator|--separator=<coupure-paragraphe>] [--[no-]stripspace] [-m " -"<message> | -F <fichier> | (-c | -C) <objet>] [<objet>]" +"<message> | -F <fichier> | (-c | -C) <objet>] [<objet>] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" @@ -8997,11 +9097,11 @@ msgstr "" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <références-notes>] append [--allow-empty] [--" "[no-]separator|--separator=<coupure-paragraphe>] [--[no-]stripspace]-m " -"<message> | -F <fichier> | (-c | -C) <objet>] [<objet>]" +"<message> | -F <fichier> | (-c | -C) <objet>] [<objet>] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref <références-notes>] edit [--allow-empty] [<objet>]" @@ -9120,6 +9220,9 @@ msgstr "contenu de la note dans un fichier" msgid "reuse and edit specified note object" msgstr "réutiliser et éditer l'objet de note spécifié" +msgid "edit note message in editor" +msgstr "éditer le message de node dans un éditeur" + msgid "reuse specified note object" msgstr "réutiliser l'objet de note spécifié" @@ -9308,6 +9411,13 @@ msgstr "" "git pack-objects [<options>] <nom-de-base> [< <liste-références> | < <liste-" "objets>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "option --name-hash-version invalide : %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "actuellement, --write-bitmap-index nécessite --name-hash-version=1" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9629,6 +9739,9 @@ msgstr "gestion des objets manquants" msgid "do not pack objects in promisor packfiles" msgstr "ne pas empaqueter les objets dans les fichiers paquets prometteurs" +msgid "implies --missing=allow-any" +msgstr "implique --missing=allow-any" + msgid "respect islands during delta compression" msgstr "respecter les îlots pendant la compression des deltas" @@ -9638,6 +9751,11 @@ msgstr "protocole" msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "exclure tout uploadpack.blobpackfileuri configuré avec ce protocole" +msgid "use the specified name-hash function to group similar objects" +msgstr "" +"utiliser la fonction d'empreinte de nom spécifiée pour grouper les objets " +"similaires" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "la profondeur %d de chaîne de delta est trop grande, forcée à %d" @@ -10041,8 +10159,8 @@ msgstr "" msgid "" "You didn't specify any refspecs to push, and push.default is \"nothing\"." msgstr "" -"Vous n'avez pas spécifié de spécifications de référence à pousser, et push." -"default est \"nothing\"." +"Vous n'avez pas spécifié de spécifications de référence à pousser, et " +"push.default est \"nothing\"." #, c-format msgid "" @@ -10525,7 +10643,7 @@ msgid "continue" msgstr "continuer" msgid "skip current patch and continue" -msgstr "sauter le patch courant et continuer" +msgstr "sauter la rustine courante et continuer" msgid "abort and check out the original branch" msgstr "abandonner et extraire la branche d'origine" @@ -10537,7 +10655,7 @@ msgid "edit the todo list during an interactive rebase" msgstr "éditer la liste à faire lors d'un rebasage interactif" msgid "show the patch file being applied or merged" -msgstr "afficher le patch en cours d'application ou de fusion" +msgstr "afficher la rustine en cours d'application ou de fusion" msgid "use apply strategies to rebase" msgstr "utiliser des stratégies d'application pour rebaser" @@ -10900,8 +11018,11 @@ msgstr "pas de journal de références à supprimer spécifié" msgid "invalid ref format: %s" msgstr "format de référence invalide : %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<format> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "spécifier le format de réference vers lequel convertir" @@ -10909,6 +11030,9 @@ msgstr "spécifier le format de réference vers lequel convertir" msgid "perform a non-destructive dry-run" msgstr "faire l'action en mode simulé non destructif" +msgid "drop reflogs entirely during the migration" +msgstr "abandonner complètement le reflog pendant la migration" + msgid "missing --ref-format=<format>" msgstr "--ref-format=<format> manquant" @@ -10916,6 +11040,12 @@ msgstr "--ref-format=<format> manquant" msgid "repository already uses '%s' format" msgstr "le dépôt utilise déjà le format '%s'" +msgid "enable strict checking" +msgstr "activer une vérification plus stricte" + +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' n'accepte aucun argument" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -11250,10 +11380,34 @@ msgid " Local refs will be mirrored by 'git push'" msgstr " Les références locales seront reflétées par 'git push'" #, c-format -msgid " Local ref configured for 'git push'%s:" -msgid_plural " Local refs configured for 'git push'%s:" -msgstr[0] " Référence locale configurée pour 'git push'%s :" -msgstr[1] " Références locales configurées pour 'git push'%s :" +msgid " Local ref configured for 'git push'%s:" +msgid_plural " Local refs configured for 'git push'%s:" +msgstr[0] " Référence locale configurée pour 'git push'%s :" +msgstr[1] " Références locales configurées pour 'git push'%s :" + +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "'%s/HEAD' est inchangé et pointe sur '%s'\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' a changé depuis '%s' et pointe à présent sur '%s'\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "'%s/HEAD' a été créé et pointe sur '%s'\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' est détaché de '%s' et pointe à présent sur '%s'\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"'%s/HEAD' pointait sur '%s' (qui n'est pas une branche distante), mais " +"pointe à présent sur '%s'\n" msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "définir refs/remotes/<nom>/HEAD selon la distante" @@ -11278,7 +11432,7 @@ msgid "Not a valid ref: %s" msgstr "Référence non valide : %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "Impossible de paramétrer %s" #, c-format @@ -11350,8 +11504,14 @@ msgstr "Pas de suppression de toutes les URLs non-push" msgid "be verbose; must be placed before a subcommand" msgstr "être verbeux : doit être placé avant une sous-commande" -msgid "git repack [<options>]" -msgstr "git repack [<options>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<nom-de-paquet>]\n" +"[--write-midx] [--name-hash-version=<n>]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11432,6 +11592,12 @@ msgstr "passer --no-reuse-delta à git-pack-objects" msgid "pass --no-reuse-object to git-pack-objects" msgstr "passer --no-reuse-object à git-pack-objects" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"spécifier la verison d'empreinte de nom à utiliser pour grouper les objets " +"similaires par chemin" + msgid "do not run git-update-server-info" msgstr "ne pas lancer git-update-server-info" @@ -11481,9 +11647,6 @@ msgstr "trouver une progression géométrique avec un facteur <N>" msgid "write a multi-pack index of the resulting packs" 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" @@ -11700,9 +11863,6 @@ 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" @@ -12370,13 +12530,11 @@ 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 branches)" -msgstr "" -"afficher seulement les étiquettes (peut être combiné avec les branches)" +msgid "only show tags (can be combined with --branches)" +msgstr "afficher seulement les étiquettes (peut être combiné avec --branches)" -msgid "only show branches (can be combined with tags)" -msgstr "" -"afficher seulement les branches (peut être combiné avec les étiquettes)" +msgid "only show branches (can be combined with --tags)" +msgstr "afficher seulement les branches (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" @@ -12424,7 +12582,7 @@ msgid "" "directory '%s' contains untracked files, but is not in the sparse-checkout " "cone" msgstr "" -"le dossier '%s' contient des fichiers non-suivis, mais n'est pas dans le " +"le répertoire '%s' contient des fichiers non-suivis, mais n'est pas dans le " "cone d'extraction clairsemée" #, c-format @@ -12435,6 +12593,10 @@ msgid "failed to create directory for sparse-checkout file" msgstr "" "échec de la création du répertoire pour le fichier d'extraction clairsemée" +#, c-format +msgid "unable to fdopen %s" +msgstr "impossible d'ouvrir %s avec fdopen" + msgid "failed to initialize worktree config" msgstr "échec lors de l'initialisation de la configuration d'arbre de travail" @@ -12904,8 +13066,8 @@ msgid "couldn't hash object from '%s'" msgstr "impossible de calculer l'empreinte de l'objet depuis '%s'" #, c-format -msgid "unexpected mode %o\n" -msgstr "mode %o inattendu\n" +msgid "unexpected mode %o" +msgstr "mode %o inattendu" msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "" @@ -13157,7 +13319,7 @@ msgid "" "the superproject is not on any branch" msgstr "" "La branche du sous-module %s est configurée pour hériter de la branche du " -"superprojet, mais le superprojet n'est sur aucune branche" +"super-projet, mais le super-projet n'est sur aucune branche" #, c-format msgid "Unable to find current revision in submodule path '%s'" @@ -14063,6 +14225,9 @@ msgstr "régler le mode de suivi (voir git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "essayer de nommer la nouvelle branche comme la branche amont" +msgid "use relative paths for worktrees" +msgstr "utiliser des chemins relatifs pour les arbres-de-travail" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "les options '%s', '%s' et '%s' ne peuvent pas être utilisées ensemble" @@ -14345,6 +14510,26 @@ msgstr "impossible de créer '%s'" msgid "index-pack died" msgstr "l'index de groupe a disparu" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "Le répertoire '%s' est présent dans l'index et pourtant pas clairsemé" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "l'arbre de cache corrompu a des entrées non présentes dans l'index" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s avec les drapeaux 0x%x ne devrait pas être dans l'arbre de cache" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "mauvais sous-arbre '%.*s'" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "" +"l'arbre de cache pour le chemin %.*s ne correspond pas. %s attendu, %s obtenu" + msgid "terminating chunk id appears earlier than expected" msgstr "l'identifiant de terminaison de tronçon apparaît plus tôt qu'attendu" @@ -14375,13 +14560,13 @@ msgid "Add file contents to the index" msgstr "Ajouter le contenu de fichiers dans l'index" msgid "Apply a series of patches from a mailbox" -msgstr "Appliquer une série de patchs depuis une boîte mail" +msgstr "Appliquer une série de rustines depuis une boîte mail" msgid "Annotate file lines with commit information" msgstr "Annoter les lignes du fichier avec l'information de commit" msgid "Apply a patch to files and/or to the index" -msgstr "Appliquer une patch à des fichiers ou à l'index" +msgstr "Appliquer une rustine à des fichiers ou à l'index" msgid "Import a GNU Arch repository into Git" msgstr "Importer dans Git un dépôt GNU Arch" @@ -14389,6 +14574,9 @@ msgstr "Importer dans Git un dépôt GNU Arch" msgid "Create an archive of files from a named tree" msgstr "Créer une archive des fichiers depuis un arbre nommé" +msgid "Download missing objects in a partial clone" +msgstr "Télécharger les objets manquants dans un clone partiel" + msgid "Use binary search to find the commit that introduced a bug" msgstr "Trouver par recherche binaire la modification qui a introduit un bogue" @@ -14533,7 +14721,7 @@ msgid "Run a Git command on a list of repositories" msgstr "Lance une commande Git sur une liste de dépôts" msgid "Prepare patches for e-mail submission" -msgstr "Préparer les patchs pour soumission par courriel" +msgstr "Préparer les rustines pour soumission par courriel" msgid "Verifies the connectivity and validity of the objects in the database" msgstr "" @@ -14603,7 +14791,7 @@ msgstr "Afficher le contenu d'un objet arbre" msgid "Extracts patch and authorship from a single e-mail message" msgstr "" -"Extraire le patch et l'information de d'auteur depuis un simple message de " +"Extraire la rustine et l'information de l'auteur depuis un simple message de " "courriel" msgid "Simple UNIX mbox splitter program" @@ -14666,7 +14854,7 @@ msgid "Pack heads and tags for efficient repository access" msgstr "Empaqueter les têtes et les étiquettes pour un accès efficace au dépôt" msgid "Compute unique ID for a patch" -msgstr "Calculer l'ID unique d'un patch" +msgstr "Calculer l'ID unique d'une rustine" msgid "Prune all unreachable objects from the object database" msgstr "Élaguer les objets inatteignables depuis la base de données des objets" @@ -14741,7 +14929,7 @@ msgid "Remove files from the working tree and from the index" msgstr "Supprimer des fichiers de la copie de travail et de l'index" msgid "Send a collection of patches as emails" -msgstr "Envoyer un ensemble de patchs comme courriels" +msgstr "Envoyer un ensemble de rustines comme courriels" msgid "Push objects over Git protocol to another repository" msgstr "Pousser les objets sur un autre dépôt via le protocole Git" @@ -15026,7 +15214,7 @@ msgid "" "disabling Bloom filters for commit-graph layer '%s' due to incompatible " "settings" msgstr "" -"désactivation des filtres de Bloom opur la couche de graphe de commits '%s' " +"désactivation des filtres de Bloom pour la couche de graphe de commits '%s' " "à cause de réglages incompatibles" msgid "commit-graph has no base graphs chunk" @@ -15168,8 +15356,8 @@ msgid "" "attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " "(%d) is not supported" msgstr "" -"essai d'écriture de graphe de commits, mais 'commitGraph." -"changedPathsVersion' (%d) n'est pas pris en charge" +"essai d'écriture de graphe de commits, mais " +"'commitGraph.changedPathsVersion' (%d) n'est pas pris en charge" msgid "too many commits to write graph" msgstr "trop de commits pour écrire un graphe" @@ -15258,13 +15446,13 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "Le support de <GIT_DIR>/info/grafts est déconseillé\n" "et sera supprimé dans une version future de Git.\n" "\n" "Veuillez utiliser \"git replace --convert-graft-file\"\n" -"pour convertir les grafts en référence de remplacement.\n" +"pour convertir les grafts en références de remplacement.\n" "\n" "Supprimez ce message en lançant\n" "\"git config advice.graftFileDeprecated false\"" @@ -16105,6 +16293,18 @@ msgstr "l'url n'a pas de schéma : %s" msgid "credential url cannot be parsed: %s" msgstr "impossible d'analyser l'url d'identification : %s" +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "délai d'attente invalide '%s', entier positif ou nul attendu" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "délai d'attente d'init invalide '%s', entier positif ou nul attendu" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "max-connections invalide '%s', entier attendu" + msgid "in the future" msgstr "dans le futur" @@ -16177,8 +16377,8 @@ msgstr "impossible de charger la regex île pour '%s' : %s" #, c-format msgid "island regex from config has too many capture groups (max=%d)" msgstr "" -"l'expression rationnelle depuis la configuration a trop de groupes de " -"capture (max=%d)" +"l'expression régulière depuis la configuration a trop de groupes de capture " +"(max=%d)" #, c-format msgid "Marked %d islands, done.\n" @@ -16369,6 +16569,12 @@ msgstr "argument invalide pour %s" msgid "invalid regex given to -I: '%s'" msgstr "regex invalide fournie à -I : '%s'" +msgid "-G requires a non-empty argument" +msgstr "-G exige un argument non vide" + +msgid "-S requires a non-empty argument" +msgstr "-S exige un argument non vide" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "échec de l'analyse du paramètre de l'option --submodule : '%s'" @@ -16701,8 +16907,7 @@ msgstr "" "ou -G" msgid "treat <string> in -S as extended POSIX regular expression" -msgstr "" -"traiter <chaîne> dans -S comme une expression rationnelle POSIX étendue" +msgstr "traiter <chaîne> dans -S comme une expression régulière POSIX étendue" msgid "control the order in which files appear in the output" msgstr "contrôler l'ordre dans lequel les fichiers apparaissent dans la sortie" @@ -16846,6 +17051,20 @@ msgstr "espaces de nom de Git \"%s\"" msgid "too many args to run %s" msgstr "trop d'arguments pour lancer %s" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Vous tentez de récupérer %s, qui est dans le graphe de commit mais pas dans " +"la base de données des objets.\n" +"C'est probablement du à une corruption de dépôt.\n" +"Si vous essayez de réparer cette corruption de dépôt en re-récupérer l'objet " +"manquant, utilisez 'git fetch --refetch' sur les objets manquants." + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack : liste superficielle attendue" @@ -17435,11 +17654,11 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" "Le crochet '%s' a été ignoré parce qu'il n'est pas marqué comme exécutable.\n" -"Vous pouvez désactiver cet avertissement avec `git config advice.ignoredHook " -"false`." +"Vous pouvez désactiver cet avertissement avec `git config set " +"advice.ignoredHook false`." msgid "not a git repository" msgstr "pas un dépôt git" @@ -17456,15 +17675,9 @@ msgstr "" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "La délégation de commande n'est pas supporté avec cuRL < 7.22.0" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "L'épinglage de clé publique n'est pas supporté avec cuRL < 7.39.0" - msgid "Unknown value for http.proactiveauth" msgstr "valeur inconnue pour http.proactiveauth" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE n'est pas supporté avec cuRL < 7.44.0" - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "Dorsale SSL '%s' non supportée. Dorsales SSL supportées :" @@ -17628,13 +17841,16 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "Impossible de créer '%s.lock' : %s" +msgid "unable to create temporary object directory" +msgstr "impossible de créer un répertoire d'objets temporaire" + #, c-format msgid "could not write loose object index %s" msgstr "impossible d'écrire l'objet esseulé %s" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "Échec de l'écriture de l'index d'objet esseulé %s\n" +msgid "failed to write loose object index %s" +msgstr "Échec de l'écriture de l'index d'objet esseulé %s" #, c-format msgid "unexpected line: '%s'" @@ -17650,6 +17866,10 @@ msgstr "CRLF citées détectées" msgid "unable to format message: %s" msgstr "impossible de formater le message : %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "taille de marqueur invalide '%s', entier attendu" + #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Échec de la fusion du sous-module %s (non extrait)" @@ -18190,6 +18410,17 @@ msgstr "impossible de charger le paquet" msgid "could not open index for %s" msgstr "impossible d'ouvrir l'index pour %s" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "impossible de lier '%s' à '%s'" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "échec du nettoyage de l'index de multi-paquet à %s" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "impossible d'écrire un MIDX incrémental avec des bitmap" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "" "index multi-paquet existant ignoré ; non-concordance de la somme de contrôle" @@ -18219,18 +18450,34 @@ msgstr "aucun fichier paquet à l'index." msgid "refusing to write multi-pack .bitmap without any objects" msgstr "refus d'écrire le .bitmap multi-paquet sans aucun objet" +msgid "unable to create temporary MIDX layer" +msgstr "impossible de créer une couche MIDX temporaire" + msgid "could not write multi-pack bitmap" msgstr "impossible d'écrire le bitmap multi-paquet" +msgid "unable to open multi-pack-index chain file" +msgstr "impossible d'ouvrir le fichier d'index multi-paquet" + +msgid "unable to rename new multi-pack-index layer" +msgstr "impossible d'écrire la nouvelle couche de l'index multi-paquet" + msgid "could not write multi-pack-index" msgstr "échec de l'écriture de l'index de multi-paquet" +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "" +"impossible d'expirer les paquets depuis un index multi-paquet incrémental" + msgid "Counting referenced objects" msgstr "Comptage des objets référencés" msgid "Finding and deleting unreferenced packfiles" msgstr "Recherche et effacement des fichiers paquets non-référencés" +msgid "cannot repack an incremental multi-pack-index" +msgstr "impossible de ré-empaqueter un index multi-paquet incrémental" + msgid "could not start pack-objects" msgstr "impossible de démarrer le groupement d'objets" @@ -18303,6 +18550,28 @@ msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "" "index multi-paquet les noms de paquets sont en désordre : '%s' avant '%s'" +msgid "multi-pack-index chain file too small" +msgstr "le fichier de chaîne d'index multi-paquet est trop petit" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "nombre de paquets dans la base MIDX trop haut : %<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "nombre d'objets dans la base MIDX trop haut : %<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "" +"chaîne d'index multi-paquet invalide : la ligne '%s' n'est pas une empreinte" + +msgid "unable to find all multi-pack index files" +msgstr "impossible de trouver tous les fichiers d'index multi-paquet" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "position d'objet MIDX invalide. MIDX est vraisemblablement corrompu" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "mauvais pack-int-id : %u (%u paquets au total)" @@ -18321,10 +18590,6 @@ msgstr "" 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 clear multi-pack-index at %s" -msgstr "échec du nettoyage de l'index de multi-paquet à %s" - msgid "multi-pack-index file exists, but failed to parse" msgstr "le fichier d'index multi-paquet existe mais n'a pu être analysé" @@ -18533,10 +18798,22 @@ msgstr "l'objet empaqueté %s (stocké dans %s) est corrompu" msgid "missing mapping of %s to %s" msgstr "correspondance manquante entre %s et %s" +#, c-format +msgid "unable to open %s" +msgstr "impossible d'ouvrir %s" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "les fichiers '%s' et '%s' diffèrent par leur contenu" + #, c-format msgid "unable to write file %s" msgstr "impossible d'écrire le fichier %s" +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "impossible d'écrire le fichier %s qui disparaît répétitivement" + #, c-format msgid "unable to set permission to '%s'" msgstr "impossible de régler les droits de '%s'" @@ -18618,10 +18895,6 @@ msgstr "%s : type de fichier non supporté" msgid "%s is not a valid '%s' object" msgstr "%s n'est pas un objet '%s' valide" -#, c-format -msgid "unable to open %s" -msgstr "impossible d'ouvrir %s" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "incohérence de hachage pour %s (%s attendu)" @@ -18723,7 +18996,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Git ne crée normalement jamais de référence qui se termine par 40\n" "caractères hexa car elle serait ignorée si vous spécifiez juste\n" @@ -18735,7 +19008,7 @@ msgstr "" "est créée.\n" "Veuillez examiner ces références et peut-être les supprimer. Désactivez ce " "message\n" -"en lançant \"git config advice.objectNameWarning false\"" +"en lançant \"git config set advice.objectNameWarning false\"" #, c-format msgid "log for '%.*s' only goes back to %s" @@ -18900,13 +19173,6 @@ 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" - msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "" "table de recherche en bitmap corrompue : position de triplet hors d'index" @@ -19120,6 +19386,52 @@ msgstr "bascule inconnue « %c »" msgid "unknown non-ascii option in string: `%s'" msgstr "option non-ascii inconnue dans la chaîne : '%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " <%s>" + msgid "..." msgstr "..." @@ -19184,7 +19496,7 @@ msgid "use <n> digits to display object names" msgstr "utiliser <n> chiffres pour afficher les noms des objets" msgid "prefixed path to initial superproject" -msgstr "chemin préfixé vers le superprojet initial" +msgstr "chemin préfixé vers le super-projet initial" msgid "how to strip spaces and #comments from message" msgstr "comment éliminer les espaces et les commentaires # du message" @@ -19206,6 +19518,21 @@ msgstr "valeur booléenne d'environnement invalide '%s' pour '%s'" msgid "failed to parse %s" msgstr "échec de l'analyse de %s" +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "échec de parcours des enfants de l'arbre %s : non trouvé" + +#, c-format +msgid "failed to find object %s" +msgstr "échec de la recherche de l'objet %s" + +#, c-format +msgid "failed to find tag %s" +msgstr "impossible de trouver l'étiquette %s" + +msgid "failed to setup revision walk" +msgstr "impossible définir un parcours de révisions" + #, c-format msgid "Could not make %s writable by group" msgstr "Impossible de rendre %s inscriptible pour le groupe" @@ -19363,6 +19690,22 @@ msgstr "un nom de prometteur distant ne peut pas commencer par '/' : %s" msgid "could not fetch %s from promisor remote" msgstr "impossible de récupérer %s depuis le distant de prometteur" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "distant connu nommé '%s' mais avec l'url '%s' au lieu de '%s'" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "valeur inconnue '%s' pour l'option de config '%s'" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "élément inconnu '%s' pour l'info de distant" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "distant accpté de prometteur '%s' non trouvé" + msgid "object-info: expected flush after arguments" msgstr "object-info : vidage attendu après les arguments" @@ -19398,7 +19741,7 @@ msgstr "" msgid "" "pseudo-merge regex from config has too many capture groups (max=%<PRIuMAX>)" msgstr "" -"l'expression rationnelle de pseudo-fusion a trop de groupes de capture " +"l'expression régulière de pseudo-fusion a trop de groupes de capture " "(max=%<PRIuMAX>)" #, c-format @@ -19865,6 +20208,10 @@ msgstr "valeur positive attendue avec l'atome %%(align)" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "format attendu : %%(ahead-behind:<commit-esque>)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "format attendu : %%(is-base:<commit-esque>)" + #, c-format msgid "malformed field name: %.*s" msgstr "nom de champ malformé %.*s" @@ -20038,17 +20385,25 @@ msgstr "le journal pour la réf %s s'arrête de manière inattendue sur %s" msgid "log for %s is empty" msgstr "le journal pour la réf %s est vide" -msgid "refusing to force and skip creation of reflog" -msgstr "refus de forcer et sauter la création du reflog" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "refus de mettre à jour une réf avec un nom cassé '%s'" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "refus de mettre à jour le réflog pour la pseudo-réf '%s'" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "refus de mettre à jour la pseudo-réf '%s'" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "refus de mettre à jour le réflog avec un nom cassé '%s'" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "refus de mettre à jour une réf avec un nom cassé '%s'" + +msgid "refusing to force and skip creation of reflog" +msgstr "refus de forcer et sauter la création du reflog" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "échec de update_ref pour la réf '%s' : %s" @@ -20099,6 +20454,17 @@ msgstr "" "impossible de vérrouiller '%s' : symref attendu avec la cible '%s', mais réf " "normale trouvée" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "impossible de lire le fichier de référence '%s'" + +#, c-format +msgid "cannot open directory %s" +msgstr "impossible d'ouvrir le répertoire %s" + +msgid "Checking references consistency" +msgstr "Vérification de la cohérence des références" + #, c-format msgid "refname is dangerous: %s" msgstr "le nom de réference est dangereux : %s" @@ -20176,6 +20542,14 @@ msgstr "" msgid "invalid refspec '%s'" msgstr "spécificateur de réference invalide : '%s'" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "la valeur '%s' du motif n'a pas de '*'" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "le remplacement '%s' n'a pas de '*'" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "citation invalide dans la valeur push-option : '%s'" @@ -20224,8 +20598,8 @@ msgstr "le serveur distant a envoyé un paquet de fin de réponse inattendu" msgid "unable to rewind rpc post data - try increasing http.postBuffer" msgstr "" -"impossible de rembobiner le données post rpc - essayer d'augmenter http." -"postBuffer" +"impossible de rembobiner le données post rpc - essayer d'augmenter " +"http.postBuffer" #, c-format msgid "remote-curl: bad line length character: %.4s" @@ -20297,6 +20671,28 @@ msgstr "remote-curl : récupération tentée sans dépôt local" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl : commande inconnue '%s' depuis git" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"lecture depuis \"%s/%s\", dont la suppression est programmée.\n" +"\n" +"Si vous utilisez encore le répertoire \"remotes\", il est recommandé de\n" +"migrer vers une gestion à base de configuration :\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"S'il vous est impossible de migrer, veuillez nous avertir par\n" +"un courriel à <git@vger.kernel.org>." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "" @@ -20308,6 +20704,10 @@ msgstr "plus d'un receivepack fournis, utilisation du premier" msgid "more than one uploadpack given, using the first" msgstr "plus d'un uploadpack fournis, utilisation du premier" +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "valeur '%s' de followRemoteHEAD non reconnue et ignorée " + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "valeur non reconnue transfer.credentialsInUrl : '%s'" @@ -20328,14 +20728,6 @@ msgstr "%s suit habituellement %s, pas %s" msgid "%s tracks both %s and %s" msgstr "%s suit à la fois %s et %s" -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "la clé '%s' du modèle n'a pas de '*'" - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "la valeur '%s' du modèle n'a pas de '*'" - #, c-format msgid "src refspec %s does not match any" msgstr "" @@ -20750,13 +21142,17 @@ msgstr "ne télécharger les méta-données que pour la branche qui sera extrait msgid "create repository within 'src' directory" msgstr "Créer un dépôt dans le repertoire 'src'" +msgid "specify if tags should be fetched during clone" +msgstr "" +"spécifier si les étiquettes devraient être récupérées pendant le clonage" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <branche-principale>] [--full-" "clone]\n" -"\t[--[no-]src] <url> [<enrôlement>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enrôlement>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20774,6 +21170,10 @@ msgstr "échec d'obtention de la branche par défaut pour '%s'" msgid "could not configure remote in '%s'" msgstr "impossible de paramétrer le distant dans '%s'" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "impossible de désactiver les étiquettes dans '%s'" + #, c-format msgid "could not configure '%s'" msgstr "impossible de configurer '%s'" @@ -21254,7 +21654,7 @@ msgstr "impossible d'appliquer %s... %s" #, c-format msgid "dropping %s %s -- patch contents already upstream\n" -msgstr "abandon de %s %s -- le contenu de la rustine déjà en amont\n" +msgstr "abandon de %s %s -- le contenu de la rustine est déjà en amont\n" #, c-format msgid "git %s: failed to read the index" @@ -21845,6 +22245,10 @@ msgstr "impossible de revenir au répertoire de travail courant" msgid "failed to stat '%*s%s%s'" msgstr "échec du stat de '%*s%s%s'" +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' n'est pas absolu" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -22248,6 +22652,27 @@ 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 "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <options> -- <options-de-révision>" + +msgid "toggle inclusion of blob objects" +msgstr "activer l'inclusion des objets blob" + +msgid "toggle inclusion of commit objects" +msgstr "activer l'inclusion des objets commit" + +msgid "toggle inclusion of tag objects" +msgstr "activer l'inclusion des objets étiquette" + +msgid "toggle inclusion of tree objects" +msgstr "activer l'inclusion des objets arbre" + +msgid "toggle pruning of uninteresting paths" +msgstr "activer l'élagage des chemins inintéressants" + +msgid "read a pattern list over stdin" +msgstr "lire les motifs depuis stdin" + #, c-format msgid "commit %s is not marked reachable" msgstr "le commit %s n'est pas marqué joignable" @@ -22255,6 +22680,9 @@ msgstr "le commit %s n'est pas marqué joignable" msgid "too many commits marked reachable" msgstr "trop de commits marqués joignables" +msgid "could not determine MIDX preferred pack" +msgstr "impossible de déterminer le paquet préféré de MIDX" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<options>]" @@ -22320,6 +22748,25 @@ msgstr "jeton" msgid "command token to send to the server" msgstr "jeton de commande à envoyer au serveur" +msgid "unit-test [<options>]" +msgstr "unit-test [<options>]" + +msgid "immediately exit upon the first failed test" +msgstr "sortir immédiatement sur le premier échec" + +msgid "suite[::test]" +msgstr "suite[::test]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "" +"lancer seulement la suite de test ou le test individuel <suite[::test]>" + +msgid "suite" +msgstr "suite" + +msgid "exclude test suite <suite>" +msgstr "exclure la suite de tests <suite>" + #, c-format msgid "running trailer command '%s' failed" msgstr "échec de la commande trailer '%s'" @@ -22872,6 +23319,10 @@ msgstr "erreur : " msgid "warning: " msgstr "avertissement : " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "échec de uname() avec l'erreur '%s' (%d)\n" + msgid "Fetching objects" msgstr "Récupération des objets" @@ -22906,6 +23357,10 @@ msgstr "fichier .git cassé" msgid ".git file incorrect" msgstr "fichier .git incorrect" +msgid ".git file absolute/relative path mismatch" +msgstr "" +"non-correspondance entre les chemin absolu entre relatif du fichier .git" + msgid "not a valid path" msgstr "pas un chemin valide" @@ -22922,6 +23377,9 @@ msgstr "impossible de localiser le dépôt ; fichier .git cassé" msgid "gitdir unreadable" msgstr "gitdir non lisible" +msgid "gitdir absolute/relative path mismatch" +msgstr "non-correspondance de chemin absolu/relatif de gitdir" + msgid "gitdir incorrect" msgstr "gitdir incorrect" @@ -22957,6 +23415,14 @@ msgstr "impossible de désinitialiser %s dans '%s'" msgid "failed to set extensions.worktreeConfig setting" msgstr "échec de paramétrage extensions.worktreeConfig" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"impossible de mettre à jour le format de dépôt pour prendre en charge les " +"arbres-de-travail relatifs" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "échec de modification du paramètre extensions.relativeWorktrees" + #, c-format msgid "could not setenv '%s'" msgstr "impossible de configurer l'environnement '%s'" @@ -23138,13 +23604,13 @@ msgid "You are in the middle of an am session." msgstr "Vous êtes au milieu d'une session am." msgid "The current patch is empty." -msgstr "Le patch actuel est vide." +msgstr "La rustine actuelle est vide." msgid " (fix conflicts and then run \"git am --continue\")" msgstr " (réglez les conflits puis lancez \"git am --continue\")" msgid " (use \"git am --skip\" to skip this patch)" -msgstr " (utilisez \"git am --skip\" pour sauter ce patch)" +msgstr " (utilisez \"git am --skip\" pour sauter cette rustine)" msgid "" " (use \"git am --allow-empty\" to record this patch as an empty commit)" @@ -23194,7 +23660,7 @@ msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr " (réglez les conflits puis lancez \"git rebase --continue\")" msgid " (use \"git rebase --skip\" to skip this patch)" -msgstr " (utilisez \"git rebase --skip\" pour sauter ce patch)" +msgstr " (utilisez \"git rebase --skip\" pour sauter cette rustine)" msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr " (utilisez \"git rebase --abort\" pour extraire la branche d'origine)" @@ -23254,7 +23720,7 @@ msgstr "" " (tous les conflits sont réglés : lancez \"git cherry-pick --continue\")" msgid " (use \"git cherry-pick --skip\" to skip this patch)" -msgstr " (utilisez \"git cherry-pick --skip\" pour sauter ce patch)" +msgstr " (utilisez \"git cherry-pick --skip\" pour sauter cette rustine)" msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" msgstr " (utilisez \"git cherry-pick --abort\" pour annuler le picorage)" @@ -23276,7 +23742,7 @@ msgid " (all conflicts fixed: run \"git revert --continue\")" msgstr " (tous les conflits sont réglés : lancez \"git revert --continue\")" msgid " (use \"git revert --skip\" to skip this patch)" -msgstr " (utilisez \"git revert --skip\" pour sauter ce patch)" +msgstr " (utilisez \"git revert --skip\" pour sauter cette rustine)" msgid " (use \"git revert --abort\" to cancel the revert operation)" msgstr " (utilisez \"git revert --abort\" pour annuler le rétablissement)" @@ -23526,6 +23992,9 @@ msgstr "'%s.final' contient le courriel composé.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases est incompatible avec d'autres options\n" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases et --translate-aliases sont mutuellement exclusifs.\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -23597,7 +24066,7 @@ msgid "" "\n" msgstr "" "\n" -"Aucun fichier patch spécifié !\n" +"Aucun fichier de rustine spécifié !\n" "\n" #, perl-format @@ -23617,7 +24086,7 @@ msgid "" msgstr "" "Les lignes commençant par \"GIT:\" seront supprimées.\n" "Envisagez d'inclure un diffstat global ou une table des matières\n" -"pour le patch que vous êtes en train d'écrire.\n" +"pour la rustine que vous êtes en train d'écrire.\n" "\n" "Effacez le corps si vous ne souhaitez pas envoyer un résumé.\n" @@ -23654,7 +24123,7 @@ msgid "" "has the template subject '*** SUBJECT HERE ***'. Pass --force if you really " "want to send.\n" msgstr "" -"Envoi refusé parce que le patch\n" +"Envoi refusé parce que la rustine\n" "\t%s\n" "a un sujet modèle '*** SUBJECT HERE ***'. Passez --force is vous souhaitez " "vraiment envoyer.\n" @@ -23807,7 +24276,7 @@ msgid "" msgstr "" "fatal : %s : rejeté par le crochet %s\n" "%s\n" -"attention : aucun patch envoyé\n" +"attention : aucune rustine envoyée\n" #, perl-format msgid "unable to open %s: %s\n" @@ -23819,7 +24288,7 @@ msgid "" "warning: no patches were sent\n" msgstr "" "fatal : %s : %d est plus long que 998 caractères \n" -"attention : aucun patch envoyé\n" +"attention : aucune rustine envoyée\n" #, perl-format msgid "Skipping %s with backup suffix '%s'.\n" @@ -23831,225 +24300,23 @@ msgid "Do you really want to send %s? [y|N]: " msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : " #, c-format -#~ msgid "truncating .rej filename to %.*s.rej" -#~ msgstr "troncature du nom de fichier .rej en %.*s.rej" - -#~ msgid "" -#~ "the add.interactive.useBuiltin setting has been removed!\n" -#~ "See its entry in 'git help config' for details." -#~ msgstr "" -#~ "le réglage add.interactive.useBuiltin a été supprimé !\n" -#~ "Référez-vous à cette entrée dans 'git help config' pour plus de détails." - -#~ msgid "git archive: Remote with no URL" -#~ msgstr "git archive : Dépôt distant sans URL" - -#~ msgid "only one action at a time" -#~ msgstr "une seule action à la fois" - -#~ msgid "use [RFC PATCH] instead of [PATCH]" -#~ msgstr "utiliser [RFC PATCH] au lieu de [PATCH]" - -#, c-format -#~ msgid "no URLs configured for remote '%s'" -#~ msgstr "aucune URL configurée pour le dépôt distant '%s'" - -#, c-format -#~ msgid "unable to copy '%s' to '%s'" -#~ msgstr "impossible de copier '%s' vers '%s'" - -#, c-format -#~ msgid "remote '%s' has no configured URL" -#~ msgstr "le distant '%s' n'a pas d'URL configuré" - -#~ msgid "" -#~ "Use -f if you really want to add them.\n" -#~ "Turn this message off by running\n" -#~ "\"git config advice.addIgnoredFile false\"" -#~ msgstr "" -#~ "Utilisez -f si vous voulez vraiment les ajouter.\n" -#~ "Éliminez ce message en lançant\n" -#~ "\"git config advice.addIgnoredFile false\"" - -#~ msgid "" -#~ "Maybe you wanted to say 'git add .'?\n" -#~ "Turn this message off by running\n" -#~ "\"git config advice.addEmptyPathspec false\"" -#~ msgstr "" -#~ "Peut-être avez-vous voulu dire 'git add .' ?\n" -#~ "Éliminez ce message en lançant\n" -#~ "\"git config advice.addEmptyPathspec false\"" - -#~ msgid "" -#~ "clean.requireForce defaults to true and neither -i, -n, nor -f given; " -#~ "refusing to clean" -#~ msgstr "" -#~ "clean.requireForce à true par défaut et ni -i, -n ou -f fourni ; refus de " -#~ "nettoyer" - -#, c-format -#~ msgid "bad ls-files format: element '%s' does not start with '('" -#~ msgstr "mauvais format ls-files : l'élément '%s' ne commence pas par '('" - -#, c-format -#~ msgid "bad ls-files format: element '%s' does not end in ')'" -#~ msgstr "mauvais format ls-files : l'élément '%s' ne se termine pas par ')'" - -#, c-format -#~ msgid "bad ls-files format: %%%.*s" -#~ msgstr "mauvais format ls-files : %%%.*s" - -#~ msgid "keep redundant, empty commits" -#~ msgstr "garder les validations redondantes, vides" - -#~ msgid "core.commentChar should only be one ASCII character" -#~ msgstr "core.commentChar ne devrait être qu'un unique caractère ASCII" - -#~ 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" +#~ msgid "Could not find remote branch %s to clone." +#~ msgstr "Impossible de trouver la branche distante '%s' à cloner." #, 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 "merging cannot continue; got unclean result of %d" +#~ msgstr "la fusion ne peut pas continuer ; résultat non propre retourné %d" -#~ msgid "<commit-ish>" -#~ msgstr "<commit-esque>" +#~ msgid "git repack [<options>]" +#~ msgstr "git repack [<options>]" -#, c-format -#~ msgid "%s is incompatible with %s" -#~ msgstr "%s est incompatible avec %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'" +#~ msgid "--onto and --advance are incompatible" +#~ msgstr "--onto et --advance sont incompatibles" #, 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." - -#~ msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" -#~ msgstr "" -#~ "ne pas passer l'option --keep-cr à git-mailsplit indépendamment de 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 "" -#~ "Les mises à jour ont été rejetées, car la pointe de la branche\n" -#~ "de suivi a été mise à jour depuis la dernière extraction. Intégrez\n" -#~ "ces changements localement (par exemple 'git pull ...') avant de\n" -#~ "forcer à nouveau une mise à jour.\n" - -#~ msgid "or do not fetch any tag at all (--no-tags)" -#~ msgstr "ou ne rapatrier aucune étiquette (--no-tags)" - -#~ msgid "current working directory is untracked" -#~ msgstr "l'arbre de travail actuel est non-suivi" - -#~ msgid "cannot use --contents with final commit object name" -#~ msgstr "on ne peut pas utiliser --contents avec un nom d'objet commit final" - -#~ msgid "please commit or stash them." -#~ msgstr "veuillez les valider ou les remiser." +#~ msgid "key '%s' of pattern had no '*'" +#~ msgstr "la clé '%s' du modèle n'a pas de '*'" #, c-format -#~ msgid "Unknown mode: %s" -#~ msgstr "Mode inconnu : %s" - -#~ msgid "could not lock HEAD" -#~ msgstr "impossible de verrouiller HEAD" +#~ msgid "preferred pack (%s) is invalid" +#~ msgstr "le paquet préféré (%s) est invalide" diff --git a/po/id.po b/po/id.po index 7131a49e855ef3..7d32c51ac77f04 100644 --- a/po/id.po +++ b/po/id.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-19 14:03+0700\n" -"PO-Revision-Date: 2024-07-19 14:25+0700\n" +"POT-Creation-Date: 2025-03-05 22:57+0000\n" +"PO-Revision-Date: 2025-03-09 17:44+0700\n" "Last-Translator: Bagas Sanjaya <bagasdotme@gmail.com>\n" "Language-Team: Indonesian\n" "Language: id\n" @@ -651,18 +651,20 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" -"j - biarkan bingkah ini, lihat bingkah berikutnya yang belum diputuskan\n" -"J - biarkan bingkah ini, lihat bingkah berikutnya\n" -"k - biarkan bingkah ini, lihat bingkah sebelumnya yang belum diputuskan\n" -"K - biarkan bingkah ini, lihat bingkah sebelumnya\n" +"j - biarkan bingkah ini tak diputuskan, lihat bingkah berikutnya yang belum " +"diputuskan\n" +"J - biarkan bingkah ini tak diputuskan, lihat bingkah berikutnya\n" +"k - biarkan bingkah ini tak diputuskan, lihat bingkah sebelumnya yang belum " +"diputuskan\n" +"K - biarkan bingkah ini tak diputuskan, lihat bingkah sebelumnya\n" "g - pilih satu bingkah untuk dikunjungi\n" "/ - cari satu bingkah yang cocok dengan regex yang diberikan\n" "s - belah bingkah saat ini ke dalam bingkah yang lebih kecil\n" "e - sunting bingkah saat ini secara manual\n" -"p - lihat bingkah saat ini\n" +"p - lihat bingkah saat ini, 'P' untuk menggunakan pager\n" "? - lihat bantuan\n" #: add-patch.c @@ -753,10 +755,10 @@ msgstr "Hanya berkas biner yang berubah." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Nonaktifkan pesan ini dengan \"git config advice.%s false\"" +"Nonaktifkan pesan ini dengan \"git config set advice.%s false\"" #: advice.c #, c-format @@ -1502,6 +1504,18 @@ msgstr "juga terapkan tambalan (gunakan dengan --stat/--summary/--check)" msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "coba penggabungan tiga arah, mundur ke penambalan normal jika gagal" +#: apply.c builtin/merge-file.c +msgid "for conflicts, use our version" +msgstr "untuk konflik, gunakan versi kami" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use their version" +msgstr "untuk konflik, gunakan versi mereka" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use a union version" +msgstr "untuk konflik, gunakan versi bersatu" + #: apply.c msgid "build a temporary index based on embedded index information" msgstr "bangun sebuah indeks sementara berdasarkan informasi indeks tertanam" @@ -1563,6 +1577,10 @@ msgstr "tambahkan <akar> di depan semua nama berkas" msgid "don't return error for empty patches" msgstr "jangan kembalikan kesalahan untuk tambalan kosong" +#: apply.c +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs, dan --union memerlukan --3way" + #: archive-tar.c archive-zip.c #, c-format msgid "cannot stream blob %s" @@ -1652,6 +1670,11 @@ msgstr "bukan nama objek valid: %s" msgid "not a tree object: %s" msgstr "bukan objek pohon: %s" +#: archive.c +#, c-format +msgid "failed to unpack tree object %s" +msgstr "gagal membuka objek pohon %s" + #: archive.c #, c-format msgid "File not found: %s" @@ -1768,7 +1791,7 @@ msgstr "opsi `%s' butuh '%s'" msgid "Unexpected option --output" msgstr "Opsi --output tak diharapkan" -#: archive.c +#: archive.c t/unit-tests/unit-test.c #, c-format msgid "extra command line parameter '%s'" msgstr "parameter konfigurasi tambahan: '%s'" @@ -1840,7 +1863,7 @@ 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 +#: builtin/pack-objects.c combine-diff.c object-file.c rerere.c #, c-format msgid "unable to read %s" msgstr "tidak dapat membaca %s" @@ -1978,7 +2001,7 @@ msgid "--reverse and --first-parent together require specified latest commit" msgstr "" "--reverse dan --first-parent bersama-sama butuh komit terbaru yang disebutkan" -#: blame.c builtin/commit.c builtin/log.c builtin/merge.c +#: blame.c builtin/bisect.c builtin/commit.c builtin/log.c builtin/merge.c #: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c #: remote.c sequencer.c submodule.c msgid "revision walk setup failed" @@ -2239,7 +2262,7 @@ msgstr "latihan" #: builtin/add.c builtin/check-ignore.c builtin/commit.c #: builtin/count-objects.c builtin/fsck.c builtin/log.c builtin/mv.c -#: builtin/read-tree.c +#: builtin/read-tree.c builtin/refs.c msgid "be verbose" msgstr "jadi berkata-kata" @@ -2738,7 +2761,7 @@ msgstr "n" #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c #: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c #: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c -#: builtin/tag.c builtin/verify-tag.c +#: builtin/submodule--helper.c builtin/tag.c builtin/verify-tag.c msgid "format" msgstr "format" @@ -2867,6 +2890,22 @@ msgstr "git archive: kesalahan protokol" msgid "git archive: expected a flush" msgstr "git archive: sebuah bilasan diharapkan" +#: builtin/backfill.c +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +#: builtin/backfill.c +msgid "problem loading sparse-checkout" +msgstr "galat memuat sparse-checkout" + +#: builtin/backfill.c +msgid "Minimum number of objects to request at a time" +msgstr "Jumlah objek minum yang diminta pada suatu waktu" + +#: builtin/backfill.c +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Batasi objek yang hilang ke sparse-checkout saat ini" + #: builtin/bisect.c msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" @@ -3036,10 +3075,6 @@ msgstr "" "argumen %s tidak valid untuk 'git bisect terms'.\n" "Opsi yang didukung adalah: --term-good|--term-old dan --term-bad|--term-new." -#: builtin/bisect.c -msgid "revision walk setup failed\n" -msgstr "setup jalan revisi gagal\n" - #: builtin/bisect.c #, c-format msgid "could not open '%s' for appending" @@ -3293,7 +3328,7 @@ msgstr "perlihatkan email pengarang daripada nama (asali: off)" msgid "ignore whitespace differences" msgstr "abaikan perbedaan spasi putih" -#: builtin/blame.c builtin/log.c +#: builtin/blame.c builtin/clone.c builtin/log.c msgid "rev" msgstr "revisi" @@ -3716,11 +3751,11 @@ msgstr "HEAD tidak ditemukan di bawah refs/heads!" #: builtin/branch.c msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" -"cabang dengan --recurse-submodules hanya dapat digunakan jika submodule." -"propagateBranches diaktifkan" +"cabang dengan --recurse-submodules hanya dapat digunakan jika " +"submodule.propagateBranches diaktifkan" #: builtin/branch.c msgid "--recurse-submodules can only be used to create branches" @@ -3809,11 +3844,6 @@ msgstr "" msgid "git version:\n" msgstr "versi git:\n" -#: builtin/bugreport.c -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() gagal dengan kesalahan '%s' (%d)\n" - #: builtin/bugreport.c msgid "compiler info: " msgstr "info pengompilasi: " @@ -4282,9 +4312,16 @@ msgid "also read contacts from stdin" msgstr "juga baca kontak dari masukan standar" #: builtin/check-mailmap.c -#, c-format -msgid "unable to parse contact: %s" -msgstr "tidak dapat menguraikan kontak: %s" +msgid "read additional mailmap entries from file" +msgstr "baca entri mailmap tambahan dari berkas" + +#: builtin/check-mailmap.c +msgid "blob" +msgstr "blob" + +#: builtin/check-mailmap.c +msgid "read additional mailmap entries from blob" +msgstr "baca entri mailmap tambahan dari blob" #: builtin/check-mailmap.c msgid "no contacts specified" @@ -4709,6 +4746,11 @@ msgstr "jalur tidak dapat digunakan dengan mengganti cabang" msgid "'%s' cannot be used with switching branches" msgstr "'%s' tidak dapat digunakan dengan mengganti cabang" +#: builtin/checkout.c +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "'%s' butuh jalur untuk di-checkout" + #: builtin/checkout.c #, c-format msgid "'%s' cannot be used with '%s'" @@ -4737,7 +4779,7 @@ msgstr "gaya konflik '%s' tidak dikenal" msgid "perform a 3-way merge with the new branch" msgstr "lakukan penggabungan 3 arah dengan cabang baru" -#: builtin/checkout.c builtin/log.c parse-options.h +#: builtin/checkout.c builtin/log.c builtin/range-diff.c parse-options.h msgid "style" msgstr "gaya" @@ -4766,9 +4808,8 @@ msgid "update ignored files (default)" msgstr "perbarui berkas yang diabaikan (default)" #: builtin/checkout.c -msgid "do not check if another worktree is holding the given ref" -msgstr "" -"jangan periksa jika pohon kerja yang lain mempunyai referensi yang diberikan" +msgid "do not check if another worktree is using this branch" +msgstr "jangan periksa jika pohon kerja yang lain menggunakan cabang ini" #: builtin/checkout.c msgid "checkout our version for unmerged files" @@ -5060,8 +5101,112 @@ msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "clean.requireForce 'true' dan -f tidak diberikan: menolak membersihkan" #: builtin/clone.c -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<opsi>] [--] <repo> [<direktori>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info: Tidak dapat menambahkan alternatif untuk '%s': %s\n" + +#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c +#, c-format +msgid "failed to stat '%s'" +msgstr "gagal men-stat '%s'" + +#: builtin/clone.c +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s ada dan bukan direktori" + +#: builtin/clone.c +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "'%s' tautan simbolik, menolak mengkloning dengan --local" + +#: builtin/clone.c +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "gagal memulai iterator pada '%s'" + +#: builtin/clone.c +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "tautan simbolik '%s' ada, menolak mengkloning dengan --local" + +#: builtin/clone.c compat/precompose_utf8.c +#, c-format +msgid "failed to unlink '%s'" +msgstr "gagal menghapus tautan '%s'" + +#: builtin/clone.c +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "tautan keras tidak dapat diperiksa pada '%s'" + +#: builtin/clone.c +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "tautan keras berbeda dari sumber pada '%s'" + +#: builtin/clone.c +#, c-format +msgid "failed to create link '%s'" +msgstr "gagal membuat tautan '%s'" + +#: builtin/clone.c +#, c-format +msgid "failed to copy file to '%s'" +msgstr "gagal menyalin berkas ke '%s'" + +#: builtin/clone.c refs/files-backend.c +#, c-format +msgid "failed to iterate over '%s'" +msgstr "gagal iterasi pada '%s'" + +#: builtin/clone.c +#, c-format +msgid "done.\n" +msgstr "selesai.\n" + +#: builtin/clone.c +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Klon sukses, tapi checkout gagal.\n" +"Anda dapat periksa apa yang dicheckout dengan 'git status'\n" +"dan coba lagi dengan 'git restore --source=HEAD :/'\n" + +#: builtin/clone.c fetch-pack.c +msgid "remote did not send all necessary objects" +msgstr "remote tidak mengirim semua objek yang dibutuhkan" + +#: builtin/clone.c +#, c-format +msgid "unable to update %s" +msgstr "tidak dapat memperbarui %s" + +#: builtin/clone.c +msgid "failed to initialize sparse-checkout" +msgstr "gagal menginisalisasi checkout tipis" + +#: builtin/clone.c +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "HEAD remote merujuk pada ref yang tidak ada, tidak dapat men-checkout" + +#: builtin/clone.c +msgid "unable to checkout working tree" +msgstr "tidak dapat men-checkout pohon kerja" + +#: builtin/clone.c +msgid "unable to write parameters to config file" +msgstr "tidak dapat menulis parameter ke berkas konfigurasi" + +#: builtin/clone.c +msgid "cannot repack to clean up" +msgstr "tidak dapat memaket ulang untuk pembersihan" + +#: builtin/clone.c +msgid "cannot unlink temporary alternates file" +msgstr "tidak dapat batal-taut berkas alternatif sementara" #: builtin/clone.c msgid "don't clone shallow repository" @@ -5133,6 +5278,10 @@ msgstr "gunakan <nama> daripada 'origin' untuk lacak hulu" msgid "checkout <branch> instead of the remote's HEAD" msgstr "checkout <cabang> daripada HEAD remote" +#: builtin/clone.c +msgid "clone single revision <rev> and check out" +msgstr "klon satu revisi <revisi> dan check out" + #: builtin/clone.c msgid "path to git-upload-pack on the remote" msgstr "jalur ke git-upload-pack pada remote" @@ -5149,22 +5298,21 @@ msgstr "buat klon dangkal sedalam kedalaman tersebut" 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" +#: builtin/clone.c builtin/fetch.c builtin/pull.c +msgid "ref" +msgstr "referensi" #: builtin/clone.c builtin/fetch.c builtin/pull.c -msgid "deepen history of shallow clone, excluding rev" -msgstr "perdalam riwayat klon dangkal, tidak termasuk rev" +msgid "deepen history of shallow clone, excluding ref" +msgstr "perdalam riwayat klon dangkal, kecualikan referensi" #: builtin/clone.c builtin/submodule--helper.c msgid "clone only one branch, HEAD or --branch" msgstr "klon hanya satu cabang, HEAD atau --branch" #: builtin/clone.c -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "jangan klon tag apapun, dan buat pengambilan nanti tidak mengikutinya" +msgid "clone tags, and make later fetches not to follow them" +msgstr "klon tag dan jangan ikuti mereka pada pengambilan berikutnya" #: builtin/clone.c msgid "any cloned submodules will be shallow" @@ -5178,7 +5326,7 @@ msgstr "direktori git" msgid "separate git dir from working tree" msgstr "pisahkan direktori git dari pohon kerja" -#: builtin/clone.c builtin/init-db.c +#: builtin/clone.c builtin/init-db.c builtin/submodule--helper.c msgid "specify the reference format to use" msgstr "sebutkan format referensi untuk digunakan" @@ -5222,117 +5370,8 @@ msgid "a URI for downloading bundles before fetching from origin remote" msgstr "sebuah URI untuk mengunduh bundel sebelum mengambil dari remote asal" #: builtin/clone.c -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: Tidak dapat menambahkan alternatif untuk '%s': %s\n" - -#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c -#, c-format -msgid "failed to stat '%s'" -msgstr "gagal men-stat '%s'" - -#: builtin/clone.c -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s ada dan bukan direktori" - -#: builtin/clone.c -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "'%s' tautan simbolik, menolak mengkloning dengan --local" - -#: builtin/clone.c -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "gagal memulai iterator pada '%s'" - -#: builtin/clone.c -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "tautan simbolik '%s' ada, menolak mengkloning dengan --local" - -#: builtin/clone.c compat/precompose_utf8.c -#, c-format -msgid "failed to unlink '%s'" -msgstr "gagal menghapus tautan '%s'" - -#: builtin/clone.c -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "tautan keras tidak dapat diperiksa pada '%s'" - -#: builtin/clone.c -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "tautan keras berbeda dari sumber pada '%s'" - -#: builtin/clone.c -#, c-format -msgid "failed to create link '%s'" -msgstr "gagal membuat tautan '%s'" - -#: builtin/clone.c -#, c-format -msgid "failed to copy file to '%s'" -msgstr "gagal menyalin berkas ke '%s'" - -#: builtin/clone.c -#, c-format -msgid "failed to iterate over '%s'" -msgstr "gagal iterasi pada '%s'" - -#: builtin/clone.c -#, c-format -msgid "done.\n" -msgstr "selesai.\n" - -#: builtin/clone.c -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Klon sukses, tapi checkout gagal.\n" -"Anda dapat periksa apa yang dicheckout dengan 'git status'\n" -"dan coba lagi dengan 'git restore --source=HEAD :/'\n" - -#: builtin/clone.c -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Tidak dapat menemukan cabang remote %s untuk diklon." - -#: builtin/clone.c fetch-pack.c -msgid "remote did not send all necessary objects" -msgstr "remote tidak mengirim semua objek yang dibutuhkan" - -#: builtin/clone.c -#, c-format -msgid "unable to update %s" -msgstr "tidak dapat memperbarui %s" - -#: builtin/clone.c -msgid "failed to initialize sparse-checkout" -msgstr "gagal menginisalisasi checkout tipis" - -#: builtin/clone.c -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "HEAD remote merujuk pada ref yang tidak ada, tidak dapat men-checkout" - -#: builtin/clone.c -msgid "unable to checkout working tree" -msgstr "tidak dapat men-checkout pohon kerja" - -#: builtin/clone.c -msgid "unable to write parameters to config file" -msgstr "tidak dapat menulis parameter ke berkas konfigurasi" - -#: builtin/clone.c -msgid "cannot repack to clean up" -msgstr "tidak dapat memaket ulang untuk pembersihan" - -#: builtin/clone.c -msgid "cannot unlink temporary alternates file" -msgstr "tidak dapat batal-taut berkas alternatif sementara" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<opsi>] [--] <repo> [<direktori>]" #: builtin/clone.c msgid "Too many arguments." @@ -5342,7 +5381,8 @@ msgstr "Terlalu banyak argumen." msgid "You must specify a repository to clone." msgstr "Anda harus sebutkan repositori untuk diklon." -#: builtin/clone.c builtin/init-db.c builtin/refs.c setup.c +#: builtin/clone.c builtin/init-db.c builtin/refs.c builtin/submodule--helper.c +#: setup.c #, c-format msgid "unknown ref storage format '%s'" msgstr "format penyimpanan referensi tidak dikenal '%s'" @@ -5461,6 +5501,11 @@ msgstr "transportasi remote melaporkan kesalahan" msgid "Remote branch %s not found in upstream %s" msgstr "Cabang remote %s tidak ditemukan di hulu %s" +#: builtin/clone.c +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "Revisi remote %s tidak ditemukan di hulu %s" + #: builtin/clone.c msgid "You appear to have cloned an empty repository." msgstr "Anda tampaknya mengklon repositori kosong." @@ -5525,7 +5570,8 @@ msgstr "" "[no-]progress]\n" " <opsi pemisahan>" -#: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c +#: builtin/commit-graph.c builtin/fetch.c builtin/gc.c builtin/log.c +#: builtin/repack.c msgid "dir" msgstr "direktori" @@ -5685,9 +5731,9 @@ msgstr "git commit-tree: gagal membaca" #: builtin/commit.c msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -5695,9 +5741,9 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <komit> | --fixup [(amend|" -"reword):]<komit>)]\n" +"reword):]<komit>]\n" " [-F <berkas> | -m <pesan>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--" "author=<pengarang>]\n" @@ -6304,12 +6350,10 @@ msgstr "git config list [<opsi berkas>] [<opsi tampilan>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" -"git config get [<opsi berkas>] [<opsi tampilan] [--includes] [--all] [--" -"regexp=<regexp> [--value=<nilai>] [--fixed-value] [--default=<default>] " -"<nama>" +"git config get [<opsi berkas>] [<opsi tampilan>] [--includes] [--all] [--" +"regexp] [--value=<nilai>] [--fixed-value] [--default=<default>] <nama>" #: builtin/config.c msgid "" @@ -6322,10 +6366,10 @@ msgstr "" #: builtin/config.c msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" -"git config unset [<opsi berkas] [--all] [--value=<nilai>] [--fixed-value] " -"<nama> <nilai>" +"git config unset [<opsi berkas>] [--all] [--value=<nilai>] [--fixed-value] " +"<nama>" #: builtin/config.c msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -6343,6 +6387,16 @@ msgstr "git config edit [<opsi berkas>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "git config [<opsi berkas>] --get-colorbool <nama> [<stdout-is-tty>]" +#: builtin/config.c +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<opsi berkas>] [<opsi tampilan] [--includes] [--all] [--" +"regexp=<regexp> [--value=<nilai>] [--fixed-value] [--default=<default>] " +"<nama>" + #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " @@ -6872,12 +6926,8 @@ msgstr "%lu komit dilintasi\n" #: builtin/describe.c #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"lebih dari %i tag ditemukan; %i terbaru didaftarkan\n" -"menyerah mencari pada %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "dapat %i tag; menyerah mencari pada %s\n" #: builtin/describe.c #, c-format @@ -7354,8 +7404,8 @@ msgstr "" "fetch secara normal mengindikasikan cabang mana ada pembaruan terpaksa,\n" "tapi pemeriksaan tersebut sudah dinonaktifkan. Untuk aktifkan kembali, " "gunakan\n" -"bendera '--show-forced-updates' atau jalankan 'git config fetch." -"showForcedUpdates true'." +"bendera '--show-forced-updates' atau jalankan 'git config " +"fetch.showForcedUpdates true'." #: builtin/fetch.c #, c-format @@ -7372,8 +7422,8 @@ msgstr "" #: builtin/fetch.c #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s tidak mengirim semua objek yang diperlukan\n" +msgid "%s did not send all necessary objects" +msgstr "%s tidak mengirim semua objek yang diperlukan" #: builtin/fetch.c #, c-format @@ -7419,8 +7469,8 @@ msgstr "opsi \"%s\" nilai \"%s\" tidak valid untuk %s" #: builtin/fetch.c #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "opsi \"%s\" diabaikan untuk %s\n" +msgid "option \"%s\" is ignored for %s" +msgstr "opsi \"%s\" diabaikan untuk %s" #: builtin/fetch.c object-file.c #, c-format @@ -7432,6 +7482,21 @@ msgstr "%s bukan sebuah objek valid" msgid "the object %s does not exist" msgstr "objek '%s' tidak ada" +#: builtin/fetch.c +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Jalankan 'git remote set-head %s %s' untuk mengikuti perubahan, atau setel\n" +"opsi konfigurasi 'remote.%s.followRemoteHEAD' ke nilai yang berbeda jika\n" +"Anda tidak ingin melihat pesan ini lagi. Secara rinci menjalankan\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s' akan\n" +"mematikan peringatan ini sampai remote mengubah HEAD ke yang lain." + #: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "banyak cabang terdeteksi, tidak kompatibel dengan --set-upstream" @@ -7606,6 +7671,10 @@ msgstr "peta referensi" msgid "specify fetch refmap" msgstr "sebutkan ambil peta referensi" +#: builtin/fetch.c builtin/pull.c builtin/rebase.c builtin/replay.c +msgid "revision" +msgstr "revisi" + #: builtin/fetch.c builtin/pull.c msgid "report that we have only objects reachable from this object" msgstr "" @@ -7676,8 +7745,8 @@ msgstr "protokol tidak mendukung --negotiate-only, keluar." #: builtin/fetch.c msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" "--filter hanya dapat digunakan dengan remote yang terkonfigurasi di " "extensions.partialclone" @@ -8276,6 +8345,10 @@ msgstr "jadi lebih cermat (waktu yang dijalankan bertambah)" msgid "enable auto-gc mode" msgstr "aktifkan mode gc otomatis" +#: builtin/gc.c +msgid "perform garbage collection in the background" +msgstr "lakukan pengumpulan sampah di latar belakang" + #: builtin/gc.c msgid "force running gc even if there may be another gc running" msgstr "paksa jalankan gc bahkan jika mungkin ada gc lain yang berjalan" @@ -8284,6 +8357,10 @@ msgstr "paksa jalankan gc bahkan jika mungkin ada gc lain yang berjalan" msgid "repack all other packs except the largest pack" msgstr "pak ulang semua pak yang lain kecuali pak terbesar" +#: builtin/gc.c builtin/repack.c +msgid "pack prefix to store a pack containing pruned objects" +msgstr "awalan pak untuk menyimpan pak berisi objek terpangkas" + #: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" @@ -8396,6 +8473,10 @@ msgstr "tugas '%s' tidak dapat dipilih berulang kali" msgid "run tasks based on the state of the repository" msgstr "jalankan tugas berdasarkan keadaan repositori" +#: builtin/gc.c +msgid "perform maintenance in the background" +msgstr "lakukan pemeliharaan di latar belakang" + #: builtin/gc.c msgid "frequency" msgstr "frekuensi" @@ -8522,8 +8603,25 @@ msgid "%s scheduler is not available" msgstr "penjadwal %s tidak tersedia" #: builtin/gc.c -msgid "another process is scheduling background maintenance" -msgstr "proses lainnya sedang menjadwalkan peme" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"Tidak dapat membuat '%s.lock': %s.\n" +"\n" +"Sepertinya proses git-maintenance(1) lainnya berjalan pada repositori ini.\n" +"Pastikan tidak ada proses pemeliharaan lainnya yang berjalan dan coba lagi.\n" +"Jika masih gagal, suatu proses git-maintenance(1) bisa jadi hancur pada\n" +"repositori ini sebelumnya: hapus berkas secara manual untuk melanjutkan." + +#: builtin/gc.c +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "tidak dapat memperoleh kunci untuk pemeliharran balik layar terjadwal" #: builtin/gc.c msgid "git maintenance start [--scheduler=<scheduler>]" @@ -9254,10 +9352,32 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "panjang rantai = %d: %lu objek" msgstr[1] "panjang rantai = %d: %lu objek" +#: builtin/index-pack.c +msgid "could not start pack-objects to repack local links" +msgstr "tidak dapat memulai pack-objects untuk mempak ulang tautan lokal" + +#: builtin/index-pack.c +msgid "failed to feed local object to pack-objects" +msgstr "tidak dapat memasukkan objek ke pada pack-objects" + +#: builtin/index-pack.c +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: Mengharapkan hanya baris hex ID objek penuh daripack-objects." + +#: builtin/index-pack.c +msgid "could not finish pack-objects to repack local links" +msgstr "tidak dapat menyelesaikan pack-objects untuk mempak ulang tautan lokal" + #: builtin/index-pack.c msgid "Cannot come back to cwd" msgstr "tidak dapat kembali ke direktori kerja saat ini" +#: builtin/index-pack.c builtin/unpack-objects.c +#, c-format +msgid "bad --pack_header: %s" +msgstr "--pack_header jelek: %s" + #: builtin/index-pack.c #, c-format msgid "bad %s" @@ -9268,6 +9388,10 @@ msgstr "%s jelek" msgid "unknown hash algorithm '%s'" msgstr "algoritma hash tak dikenal '%s'" +#: builtin/index-pack.c +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor tidak dapat digunakan dengan nama pak" + #: builtin/index-pack.c msgid "--stdin requires a git repository" msgstr "--stdin memerlukan repositori git" @@ -9502,10 +9626,6 @@ msgstr "-L<rentang>:<berkas> tidak dapat digunakan dengan spek jalur" msgid "Final output: %d %s\n" msgstr "Keluaran terakhir: %d %s\n" -#: builtin/log.c -msgid "unable to create temporary object directory" -msgstr "tidak dapat membuat direktori objek sementara" - #: builtin/log.c #, c-format msgid "git show %s: bad file" @@ -10246,18 +10366,6 @@ msgstr "gunakan penggabungan berdasarkan diff3" msgid "use a zealous diff3 based merge" msgstr "gunakan penggabungan berdasarkan diff3 yang bersemangat" -#: builtin/merge-file.c -msgid "for conflicts, use our version" -msgstr "untuk konflik, gunakan versi kami" - -#: builtin/merge-file.c -msgid "for conflicts, use their version" -msgstr "untuk konflik, gunakan versi mereka" - -#: builtin/merge-file.c -msgid "for conflicts, use a union version" -msgstr "untuk konflik, gunakan versi bersatu" - #: builtin/merge-file.c diff.c msgid "<algorithm>" msgstr "<algoritma>" @@ -10393,11 +10501,6 @@ msgstr "opsi strategi tidak dikenal: -X%s" msgid "malformed input line: '%s'." msgstr "baris masukan jelek: '%s'." -#: builtin/merge-tree.c -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "penggabungan tidak dapat berlanjut; dapat hasil kotor dari %d" - #: builtin/merge.c msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<opsi>] [<komit>...]" @@ -10553,7 +10656,7 @@ msgstr "Tidak dapat menulis indeks." msgid "Not handling anything other than two heads merge." msgstr "Tak tangani apapun selain penggabungan dua kepala." -#: builtin/merge.c +#: builtin/merge.c builtin/sparse-checkout.c #, c-format msgid "unable to write %s" msgstr "tidak dapat menulis %s" @@ -10852,6 +10955,10 @@ msgstr "pak untuk digunakan ulang saat menghitung bitmap multipak" msgid "write multi-pack bitmap" msgstr "tulis bitmap multipak" +#: builtin/multi-pack-index.c +msgid "write a new incremental MIDX" +msgstr "tulis MIDX tambahan baru" + #: builtin/multi-pack-index.c msgid "write multi-pack index containing only given indexes" msgstr "tulis indeks multipak yang hanya berisi indeks yang diberikan" @@ -11024,11 +11131,11 @@ msgstr "git notes [--ref <referensi catan>] [list [<objek>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <referensi catatan>] add [-f] [--allow-empty] [--" "[no-]separator|--separator=<pemisah paragraf>] [--[no-]stripspace] [-m " -"<pesan | -F <berkas> | (-c | -C) <objek>] [<objek>]" +"<pesan> | -F <berkas> | (-c | -C) <objek>] [<objek>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" @@ -11039,11 +11146,11 @@ msgstr "" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <referensi catatan>] append [--alow-empty] [--" "[no]separator|--separator=<pemisah paragraf>] [--[no-]stripspace] [-m " -"<pesan> | -F <berkas> | (-c | -C) <objek>] [<objek>]" +"<pesan> | -F <berkas> | (-c | -C) <objek>] [<objek>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" @@ -11196,6 +11303,10 @@ msgstr "isi catatan di dalam berkas" msgid "reuse and edit specified note object" msgstr "gunakan ulang dan sunting objek catatan yang disebutkan" +#: builtin/notes.c +msgid "edit note message in editor" +msgstr "sunting pesan catatan dalam penyunting" + #: builtin/notes.c msgid "reuse specified note object" msgstr "gunakan ulang objek catatan yang disebutkan" @@ -11431,6 +11542,15 @@ msgstr "" "git pack-objects [<opsi>...] <nama dasar> [< <daftar referensi> | < <daftar-" "objek>]" +#: builtin/pack-objects.c +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "opsi --name-hash-version tidak valid: %d" + +#: builtin/pack-objects.c +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "saat ini, --write-bitmap-index memerlukan --name-hash-version=1" + #: builtin/pack-objects.c #, c-format msgid "" @@ -11825,6 +11945,10 @@ msgstr "penanganan untuk objek yang hilang" msgid "do not pack objects in promisor packfiles" msgstr "jangan pak objek di dalam pak penjanji" +#: builtin/pack-objects.c +msgid "implies --missing=allow-any" +msgstr "mengimplikasikan --missing=allow-any" + #: builtin/pack-objects.c msgid "respect islands during delta compression" msgstr "patuhi pulau selama pemampatan delta" @@ -11839,6 +11963,12 @@ msgstr "" "abaikan uploadpack.blobpackfileuri apapun yang dikonfigurasikan dengan " "protokol ini" +#: builtin/pack-objects.c +msgid "use the specified name-hash function to group similar objects" +msgstr "" +"gunakan fungsi nama-hash yang dirincikan untuk mengelompokan objek yang " +"serupa" + #: builtin/pack-objects.c #, c-format msgid "delta chain depth %d is too deep, forcing %d" @@ -12238,8 +12368,8 @@ msgid "" msgstr "" "\n" "Untuk menghindari konfigurasi cabang hulu otomatis ketika namanya\n" -"tidak akan cocok dengan cabang lokal, lihat opsi 'simple' dari branch." -"autoSetupMerge\n" +"tidak akan cocok dengan cabang lokal, lihat opsi 'simple' dari " +"branch.autoSetupMerge\n" "di 'git help config'.\n" #: builtin/push.c @@ -13333,8 +13463,12 @@ msgid "invalid ref format: %s" msgstr "format referensi tidak valid: %s" #: builtin/refs.c -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<format> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" + +#: builtin/refs.c +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [---verbose]" #: builtin/refs.c msgid "specify the reference format to convert to" @@ -13344,6 +13478,10 @@ msgstr "sebutkan format referensi untuk dikonversi" msgid "perform a non-destructive dry-run" msgstr "lakukan uji coba non desktruktif" +#: builtin/refs.c +msgid "drop reflogs entirely during the migration" +msgstr "buang keseluruhan log referensi selama migrasi" + #: builtin/refs.c msgid "missing --ref-format=<format>" msgstr "--ref-format=<format> hilang" @@ -13353,6 +13491,14 @@ msgstr "--ref-format=<format> hilang" msgid "repository already uses '%s' format" msgstr "repositori telah menggunakan format '%s'" +#: builtin/refs.c +msgid "enable strict checking" +msgstr "aktifkan pemeriksaan lebih ketat" + +#: builtin/refs.c +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' tidak mengambil argumen" + #: builtin/remote.c msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" @@ -13767,6 +13913,35 @@ msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Referensi lokal dikonfigurasi untuk 'git push'%s:" msgstr[1] " Referensi lokal dikonfigurasi untuk 'git push'%s:" +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "'%s/HEAD' tak berubah dan menunjuk pada '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' berubah dari '%s' dan sekarang menunjuk pada '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "'%s/HEAD' sekarang dibuat dan menunjuk pada '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "%s/HEAD' terlepas pada '%s' dan sekarang menunjuk pada '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"'%s/HEAD' dulunya menunjuk pada '%s' (yang bukan cabang remote), tetapi " +"sekarang menunjuk pada '%s'\n" + #: builtin/remote.c msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "setel refs/remotes/<nama>/HEAD tergantung remote" @@ -13795,8 +13970,8 @@ msgstr "Bukan referensi valid: %s" #: builtin/remote.c #, c-format -msgid "Could not setup %s" -msgstr "Tidak dapat mengatur %s" +msgid "Could not set up %s" +msgstr "Tidak dapat menyiapkan %s" #: builtin/remote.c #, c-format @@ -13888,8 +14063,14 @@ msgid "be verbose; must be placed before a subcommand" msgstr "jadi lebih bertele-tele; harus ditempatkan sebelum subperintah" #: builtin/repack.c -msgid "git repack [<options>]" -msgstr "git repack [<opsi>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<nama pak>]\n" +"[--write-midx] [--name-hash-version=<n>]" #: builtin/repack.c msgid "" @@ -13982,6 +14163,13 @@ msgstr "lewatkan --no-reuse-delta ke git-pack-objects" msgid "pass --no-reuse-object to git-pack-objects" msgstr "lewatkan --no-reuse-object ke git-pack-objects" +#: builtin/repack.c +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"tentukan versi nama hash yang digunakan untuk mengelompokan objek yang " +"serupa berdasarkan jalur" + #: builtin/repack.c msgid "do not run git-update-server-info" msgstr "jangan jalankan git-update-server-info" @@ -14048,10 +14236,6 @@ msgstr "temukan deret geometri dengan faktor <N>" msgid "write a multi-pack index of the resulting packs" msgstr "tulis indeks multipak dari pak yang dihasilkan" -#: builtin/repack.c -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" @@ -14326,10 +14510,6 @@ msgstr "hanya satu pola yang dapat diberikan dengan -l" 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" @@ -15156,12 +15336,12 @@ msgid "failed to look up reference" msgstr "gagal mencari referensi" #: builtin/show-ref.c -msgid "only show tags (can be combined with branches)" -msgstr "hanya perlihatkan tag (bisa dikombinasikan dengan cabang)" +msgid "only show tags (can be combined with --branches)" +msgstr "hanya perlihatkan tag (bisa dikombinasikan dengan --branches)" #: builtin/show-ref.c -msgid "only show branches (can be combined with tags)" -msgstr "hanya perlihatkan cabang (bisa dikombinasikan dengan tag)" +msgid "only show branches (can be combined with --tags)" +msgstr "hanya perlihatkan cabang (bisa dikombinasikan dengan --tags)" #: builtin/show-ref.c msgid "check for reference existence without resolving" @@ -15227,6 +15407,11 @@ msgstr "gagal menghapus direktori '%s'" msgid "failed to create directory for sparse-checkout file" msgstr "gagal membuat direktori untuk berkas sparse-checkout" +#: builtin/sparse-checkout.c +#, c-format +msgid "unable to fdopen %s" +msgstr "tidak dapat membuka (fdopen) %s" + #: builtin/sparse-checkout.c msgid "failed to initialize worktree config" msgstr "gagal menginisialisasi konfigurasi pohon kerja" @@ -15797,8 +15982,8 @@ msgstr "tidak dapat hash objek dari '%s'" #: builtin/submodule--helper.c #, c-format -msgid "unexpected mode %o\n" -msgstr "mode tidak diharapkan %o\n" +msgid "unexpected mode %o" +msgstr "mode tidak diharapkan %o" #: builtin/submodule--helper.c msgid "use the commit stored in the index instead of the submodule HEAD" @@ -17199,6 +17384,10 @@ msgstr "pasang mode pelacakan (lihat git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "coba cocokkan nama cabang baru dengan sebuah cabang pelacakan remote" +#: builtin/worktree.c +msgid "use relative paths for worktrees" +msgstr "gunakan jalur relatif untuk pohon kerja" + #: builtin/worktree.c diff.c parse-options.c #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" @@ -17540,6 +17729,31 @@ msgstr "tidak dapat membuat '%s'" msgid "index-pack died" msgstr "index-pack mati" +#: cache-tree.c +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "direktori '%s' ada pada indeks, tapi bukan tipis" + +#: cache-tree.c unpack-trees.c +msgid "corrupted cache-tree has entries not present in index" +msgstr "pohon tembolok rusak mempunyai entri yang tidak ada pada indeks" + +#: cache-tree.c +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s dengan bendera 0x%x tidak boleh ada di pohon tembolok" + +#: cache-tree.c +#, c-format +msgid "bad subtree '%.*s'" +msgstr "subpohon jelek '%.*s'" + +#: cache-tree.c +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "" +"pohon tembolok untuk jalur %.*s tidak cocok. %s diharapkan tapi dapat %s" + #: chunk-format.c msgid "terminating chunk id appears earlier than expected" msgstr "id bingkah pengakhiran muncul lebih awal dari yang diharapkan" @@ -17597,6 +17811,10 @@ msgstr "Impor repositori GNU Arch ke dalam Git" msgid "Create an archive of files from a named tree" msgstr "Buat arsip berkas dari pohon bernama" +#: command-list.h +msgid "Download missing objects in a partial clone" +msgstr "Unduh objek yang hilang dalam klon parsial" + #: command-list.h msgid "Use binary search to find the commit that introduced a bug" msgstr "Gunakan pencarian biner untuk mencari komit yang memasukkan bug" @@ -18519,7 +18737,7 @@ msgstr "gagal menulis jumlah id grafik dasar yang benar" msgid "unable to create temporary graph layer" msgstr "tidak dapat membuat lapisan grafik dasar" -#: commit-graph.c +#: commit-graph.c midx-write.c #, c-format msgid "unable to adjust shared permissions for '%s'" msgstr "tidak dapat menyesuaikan perizinan berbagi untuk '%s'" @@ -18666,16 +18884,16 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "Dukungan untuk <GIT_DIR>/info/grafts usang dan akan dihapus\n" -"pada versi Git di masa yang akan datang.\n" +"pada versi Git mendatang.\n" "\n" "Mohon gunakan \"git replace --convert-graft-file\"\n" "untuk mengkonversi cangkuk ke referensi penggantian.\n" "\n" "Matikan pesan ini dengan menjalankan\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" #: commit.c #, c-format @@ -19691,6 +19909,21 @@ msgstr "url tidak punya skema: %s" msgid "credential url cannot be parsed: %s" msgstr "url kredensial tidak dapat diuraikan: %s" +#: daemon.c +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "timeout '%s' tidak valid, bilangan bulat non-negatif diharapkan" + +#: daemon.c +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "init-timeout '%s' tidak valid, bilangan bulat non-negatif diharapkan" + +#: daemon.c +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "max-connections '%s' tidak valid, bilangan bulat diharapkan" + #: date.c msgid "in the future" msgstr "di masa depan" @@ -19894,7 +20127,7 @@ msgstr "" msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Nilai tidak dikenal untuk variabel konfigurasi 'diff.submodule': '%s'" -#: diff.c transport.c +#: diff.c merge-recursive.c transport.c #, c-format msgid "unknown value for config '%s': %s" msgstr "nilai tidak dikenal untuk konfigurasi '%s': %s" @@ -20005,6 +20238,14 @@ msgstr "argumen tidak valid ke %s" msgid "invalid regex given to -I: '%s'" msgstr "regex tidak valid diberikan ke -I: '%s'" +#: diff.c +msgid "-G requires a non-empty argument" +msgstr "-G butuh sebuah argumen bukan kosong" + +#: diff.c +msgid "-S requires a non-empty argument" +msgstr "-S butuh sebuah argumen bukan kosong" + #: diff.c #, c-format msgid "failed to parse --submodule option parameter: '%s'" @@ -20583,6 +20824,21 @@ msgstr "jalur ruang nama git jelek \"%s\"" msgid "too many args to run %s" msgstr "terlalu banyak argumen untuk menjalankan %s" +#: fetch-pack.c +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Anda mencoba mengambil %s, yang ada di dalam berkas grafik komit tapi bukan " +"di dalam basis data objek.\n" +"Bisa jadi ini dikarenakan kerusakan repositori.\n" +"Apabila Anda mencoba memperbaiki keruskanan repositori ini dengan mengambil " +"ulang objek yang hilang, gunakan 'git fetch --refetch' dengan objek tersebut." + #: fetch-pack.c msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: daftar dangkal diharapkan" @@ -21303,11 +21559,11 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" -"Kait '%s' diabaikan karena tidak disetel sebagai dapat dieksekusi.\n" -"Anda dapat menonaktifkan peringatan ini dengan `git config advice." -"ignoredHook false`." +"Kait '%s' diabaikan karena tidak disetel sebagai berkas yang dapat\n" +"dieksekusi. Anda dapat menonaktifkan peringatan ini dengan\n" +"`git config set advice.ignoredHook false`." #: http-fetch.c msgid "not a git repository" @@ -21327,18 +21583,10 @@ msgstr "nilai negatif untuk http.postBuffer; asalkan ke %d" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Kontrol delegasi tidak didukung oleh cURL < 7.22.0" -#: http.c -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "Penyematan kunci publik tidak didukung oleh cURL < 7.39.0" - #: http.c msgid "Unknown value for http.proactiveauth" msgstr "nilai tidak dikenal untuk http.proactiveauth" -#: http.c -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE tidak didukung dengan cURL < 7.44.0" - #: http.c #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" @@ -21529,6 +21777,10 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "Tidak dapat membuat '%s.lock': %s" +#: log-tree.c +msgid "unable to create temporary object directory" +msgstr "tidak dapat membuat direktori objek sementara" + #: loose.c #, c-format msgid "could not write loose object index %s" @@ -21536,8 +21788,8 @@ msgstr "tidak dapat menulis indeks objek longgar %s" #: loose.c #, c-format -msgid "failed to write loose object index %s\n" -msgstr "gagal menulis indeks objek longgar %s\n" +msgid "failed to write loose object index %s" +msgstr "gagal menulis indeks objek longgar %s" #: ls-refs.c #, c-format @@ -21557,6 +21809,11 @@ msgstr "CRLF terkutip terdeteksi" msgid "unable to format message: %s" msgstr "tidak dapat memformat pesan: %s" +#: merge-ll.c +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "marker-size '%s' tidak valid, bilangan bulat diharapkan" + #: merge-ort.c merge-recursive.c #, c-format msgid "Failed to merge submodule %s (not checked out)" @@ -22200,6 +22457,20 @@ msgstr "tidak dapat memuat pak" msgid "could not open index for %s" msgstr "tidak dapat membuka indeks untuk %s" +#: midx-write.c +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "tidak dapat mentautkan '%s' ke '%s'" + +#: midx-write.c midx.c +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "gagal membersihkan indeks multipak pada %s" + +#: midx-write.c +msgid "cannot write incremental MIDX with bitmap" +msgstr "tidak dapat menulis MIDX tambahan dengan bitmap" + #: midx-write.c msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "abaikan indeks multipak yang sudah ada; checksum tidak cocok" @@ -22236,14 +22507,30 @@ msgstr "tidak ada berkas pak untuk diindeks." msgid "refusing to write multi-pack .bitmap without any objects" msgstr "menolak menulis .bitmap multipak tanpa objek apapun" +#: midx-write.c +msgid "unable to create temporary MIDX layer" +msgstr "tidak dapat membuat lapisan MIDX sementara" + #: midx-write.c msgid "could not write multi-pack bitmap" msgstr "tidak dapat menulis bitmap multipak" +#: midx-write.c +msgid "unable to open multi-pack-index chain file" +msgstr "tidak dapat membuka berkas rantai indeks multipak" + +#: midx-write.c +msgid "unable to rename new multi-pack-index layer" +msgstr "tidak dapat menamai ulang lapisan indeks multipak baru" + #: midx-write.c msgid "could not write multi-pack-index" msgstr "gagal menulis indeks multipak" +#: midx-write.c +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "tidak dapat mengkadaluarsakan pak dari indeks multipak tambahan" + #: midx-write.c msgid "Counting referenced objects" msgstr "Menghitung objek tereferensi" @@ -22252,6 +22539,10 @@ msgstr "Menghitung objek tereferensi" msgid "Finding and deleting unreferenced packfiles" msgstr "Mencari dan menghapus berkas pak tak tereferensi" +#: midx-write.c +msgid "cannot repack an incremental multi-pack-index" +msgstr "tidak dapat mempak ulang indeks multipak tambahan" + #: midx-write.c msgid "could not start pack-objects" msgstr "tidak dapat memulai pack-objects" @@ -22328,6 +22619,33 @@ msgstr "bingkah nama pak indeks multipak terlalu kecil" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "nama pak indeks multipak tidak berurutan: '%s' sebelum '%s'" +#: midx.c +msgid "multi-pack-index chain file too small" +msgstr "berkas rantai indeks multipak terlalu kecil" + +#: midx.c +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "jumlah pak pada MIDX dasarterlalu tinggi: %<PRIuMAX>" + +#: midx.c +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "jumlah object pada MIDX dasar terlalu tinggi: %<PRIuMAX>" + +#: midx.c +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "rantai indeks multipak tidak valid: baris '%s' bukan suatu hash" + +#: midx.c +msgid "unable to find all multi-pack index files" +msgstr "tidak dapat menemukan semua berkas indeks multipak" + +#: midx.c +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "posisi objek MIDX tidak valid, MIDX mungkin rusak" + #: midx.c #, c-format msgid "bad pack-int-id: %u (%u total packs)" @@ -22350,11 +22668,6 @@ msgstr "indeks multipak simpan offset 64-bit, tapi off_t terlalu kecil" msgid "multi-pack-index large offset out of bounds" msgstr "offset indeks multipak besar di luar jangkauan" -#: midx.c -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "gagal membersihkan indeks multipak pada %s" - #: midx.c msgid "multi-pack-index file exists, but failed to parse" msgstr "berkas indeks multipak ada, tetapi gagal diurai" @@ -22614,11 +22927,26 @@ msgstr "objek terpak %s (disimpan di %s) rusak" msgid "missing mapping of %s to %s" msgstr "pemetaan %s ke %s hilang" +#: object-file.c +#, c-format +msgid "unable to open %s" +msgstr "tidak dapat membuka %s" + +#: object-file.c +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "berkas '%s' dan '%s' berbeda konteks" + #: object-file.c #, c-format msgid "unable to write file %s" msgstr "tidak dapat menulis berkas %s" +#: object-file.c +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "tidak dapat menulis berkas yang menghilang %s terus-menerus" + #: object-file.c #, c-format msgid "unable to set permission to '%s'" @@ -22722,11 +23050,6 @@ msgstr "%s: tipe berkas tidak didukung" msgid "%s is not a valid '%s' object" msgstr "%s bukan sebuah objek '%s' valid" -#: object-file.c -#, c-format -msgid "unable to open %s" -msgstr "tidak dapat membuka %s" - #: object-file.c #, c-format msgid "hash mismatch for %s (expected %s)" @@ -22842,19 +23165,17 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Biasanya Git tidak pernah membuat sebuah referensi yang diakhiri dengan\n" -"40 karakter hex, karena akan diabaikan ketika Anda hanya menyebutkan 40-" -"hex.\n" +"40 karakter hex, karena akan diabaikan ketika Anda hanya merincikan 40-hex.\n" "Referensi tersebut bisa tidak sengaja dibuat. Misalnya,\n" "\n" " git switch -c $br $(git rev-parse ...)\n" "\n" "dimana \"$br\" entah bagaimana kosong dan referensi 40-hex dibuat.\n" -"Mohon periksa referensi tersebut dan mungkin hapus. Matikan pesan ini " -"dengan\n" -"menjalankan \"git config advice.objectNameWarning false\"" +"Mohon periksa referensi tersebut dan mungkin hapus. Matikan pesan ini\n" +"dengan menjalankan \"git config set advice.objectNameWarning false\"" #: object-name.c #, c-format @@ -23053,15 +23374,6 @@ 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" -msgstr "pak yang disukai '%s' kadaluarsa" - #: pack-bitmap.c msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "tabel pencarian bitmap rusak: posisi kembar tiga di luar indeks" @@ -23328,6 +23640,55 @@ msgstr "sakelar tidak dikenal `%c'" msgid "unknown non-ascii option in string: `%s'" msgstr "opsi non-ascii di dalam untai tidak dikenal: `%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid " <%s>" +msgstr " <%s>" + #: parse-options.c msgid "..." msgstr "..." @@ -23431,6 +23792,25 @@ msgstr "nilai lingkungan boolean '%s' jelek untuk '%s'" msgid "failed to parse %s" msgstr "gagal menguraikan %s" +#: path-walk.c +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "gagal berjalan anak pohon %s: tidak ditemukan" + +#: path-walk.c +#, c-format +msgid "failed to find object %s" +msgstr "gagal menemukan objek %s" + +#: path-walk.c +#, c-format +msgid "failed to find tag %s" +msgstr "gagal menemukan tag %s" + +#: path-walk.c +msgid "failed to setup revision walk" +msgstr "gagal men-setup jalan revisi" + #: path.c #, c-format msgid "Could not make %s writable by group" @@ -23617,6 +23997,26 @@ msgstr "nama remote penjanji tidak dapat diawali dengan '/': %s" msgid "could not fetch %s from promisor remote" msgstr "tidak dapat mengambil %s dari remote penjanji" +#: promisor-remote.c +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "remote yang terkenal bernama '%s' tapi dengan url '%s' daripada '%s'" + +#: promisor-remote.c +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "nilai '%s' tidak dikenal untuk opsi konfigurasi '%s'" + +#: promisor-remote.c +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "elemen '%s' dari info remote tidak dikenal" + +#: promisor-remote.c +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "remote penjanji yang diterima '%s' tidak ditemukan" + #: protocol-caps.c msgid "object-info: expected flush after arguments" msgstr "object-info: bilasan diharapkan setelah argumen" @@ -24213,6 +24613,11 @@ msgstr "lebar positif diharapkan dengan atom %%(align)" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "format yang diharapkan: %%(ahead-behind:<mirip komit>)" +#: ref-filter.c +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "format yang diharapkan: %%(is-base:<mirip komit>)" + #: ref-filter.c #, c-format msgid "malformed field name: %.*s" @@ -24428,8 +24833,19 @@ msgid "log for %s is empty" msgstr "log untuk %s kosong" #: refs.c -msgid "refusing to force and skip creation of reflog" -msgstr "menolak memaksa dan melewatkan pembuatan reflog" +#, c-format +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "menolak memperbarui reflog untuk referensi semu '%s'" + +#: refs.c +#, c-format +msgid "refusing to update pseudoref '%s'" +msgstr "menolak memperbarui referensi semu '%s'" + +#: refs.c +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "menolak memperbarui reflog dengan nama jelek '%s'" #: refs.c #, c-format @@ -24437,9 +24853,8 @@ msgid "refusing to update ref with bad name '%s'" msgstr "menolak memperbarui referensi dengan nama jelek '%s'" #: refs.c -#, c-format -msgid "refusing to update pseudoref '%s'" -msgstr "menolak memperbarui referensi semu '%s'" +msgid "refusing to force and skip creation of reflog" +msgstr "menolak memaksa dan melewatkan pembuatan reflog" #: refs.c #, c-format @@ -24502,6 +24917,20 @@ msgstr "" "tidak dapat mengunci referensi '%s': diharapkan referensi simbolik dengan " "target '%s': tetapi bukan referensi reguler" +#: refs/files-backend.c +#, c-format +msgid "cannot read ref file '%s'" +msgstr "tidak dapat membaca berkas referensi '%s'" + +#: refs/files-backend.c +#, c-format +msgid "cannot open directory %s" +msgstr "tidak dapat membuka direktori %s" + +#: refs/files-backend.c +msgid "Checking references consistency" +msgstr "Memeriksa konsistensi referensi" + #: refs/reftable-backend.c #, c-format msgid "refname is dangerous: %s" @@ -24590,6 +25019,16 @@ msgstr "nama referensi %s simbolik, menyalinnya tidak didukung" msgid "invalid refspec '%s'" msgstr "spek referensi tidak valid '%s'" +#: refspec.c +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "pola '%s' tidak mempunyai '*'" + +#: refspec.c +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "pengganti '%s' tidak mempunyai '*'" + #: remote-curl.c #, c-format msgid "invalid quoting in push-option value: '%s'" @@ -24743,6 +25182,28 @@ msgstr "remote-curl: pengambilan dicoba tanpa repositori lokal" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: perintah tidak dikenal '%s' dari git" +#: remote.c +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"membaca remote dari \"%s/%s\", yang dinominasikan untuk dihapus.\n" +"\n" +"Jika Anda masih menggunakan direktori \"remotes/\" disarankan untuk\n" +"migrasi ke remote berdasarkan konfigurasi:\n" +"\n" +"\tgit remote rename %s %s\n" +"Jika tidak, mohon beri tahu kami mengapa Anda masih menggunakannya dengan\n" +"mengirimkan surel ke <git@vger.kernel.org>." + #: remote.c #, c-format msgid "config remote shorthand cannot begin with '/': %s" @@ -24756,6 +25217,11 @@ msgstr "lebih dari satu paket terima diberikan, gunakan yang pertama" msgid "more than one uploadpack given, using the first" msgstr "lebih dari satu paket unggah diberikan, gunakan yang pertama" +#: remote.c +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "nilai followRemoteHEAD yang tak dikenal '%s' diabaikan" + #: remote.c #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" @@ -24781,16 +25247,6 @@ msgstr "%s biasanya melacak %s, bukan %s" msgid "%s tracks both %s and %s" msgstr "%s melacak baik %s dan %s" -#: remote.c -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "kunci '%s' dari pola tidak ada '*'" - -#: remote.c -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "nilai '%s' dari pola tidak ada '*'" - #: remote.c #, c-format msgid "src refspec %s does not match any" @@ -25289,13 +25745,17 @@ msgstr "hanya unduh metadata untuk cabang yang akan dicheckout" msgid "create repository within 'src' directory" msgstr "salin repositori di dalam direktori 'src'" +#: scalar.c +msgid "specify if tags should be fetched during clone" +msgstr "rincikan jikan tag hendak diambil selama kloning" + #: scalar.c msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <cabang utama>] [--full-clone]\n" -"\t[--[-no-]src] <url> [<pendaftaran>]" +"\t[--[-no-]src] [--[no-]tags] <url> [<pendaftaran>]" #: scalar.c #, c-format @@ -25317,6 +25777,11 @@ msgstr "gagal mendapatkan cabang asali untuk '%s'" msgid "could not configure remote in '%s'" msgstr "tidak dapat menyetel remote di '%s'" +#: scalar.c +#, c-format +msgid "could not disable tags in '%s'" +msgstr "tidak dapat menonaktifkan tag di '%s'" + #: scalar.c #, c-format msgid "could not configure '%s'" @@ -26606,6 +27071,11 @@ msgstr "tidak dapat kembali ke cwd" msgid "failed to stat '%*s%s%s'" msgstr "gagal men-stat '%*s%s%s'" +#: setup.c +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' bukan mutlak" + #: setup.c #, c-format msgid "" @@ -27090,6 +27560,34 @@ 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-path-walk.c +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <opsi> -- <opsi revisi>" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of blob objects" +msgstr "sertakan objek blob" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of commit objects" +msgstr "sertakan objek komit" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tag objects" +msgstr "sertakan objek tag" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tree objects" +msgstr "sertakan objek pohon" + +#: t/helper/test-path-walk.c +msgid "toggle pruning of uninteresting paths" +msgstr "pangkas jalur yang tidak menarik" + +#: t/helper/test-path-walk.c +msgid "read a pattern list over stdin" +msgstr "baca daftar pola dari masukan standar" + #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -27099,6 +27597,10 @@ msgstr "komit %s tidak ditandai sebagai dapat dicapai" msgid "too many commits marked reachable" msgstr "terlalu banyak komit yang ditandai sebagai dapat dicapai" +#: t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "tidak dapat menentukan pak MIDX terpilih" + #: t/helper/test-serve-v2.c msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<opsi>]" @@ -27181,6 +27683,30 @@ msgstr "token" msgid "command token to send to the server" msgstr "token perintah untuk dikirim ke peladen" +#: t/unit-tests/unit-test.c +msgid "unit-test [<options>]" +msgstr "unit-test [<opsi>]" + +#: t/unit-tests/unit-test.c +msgid "immediately exit upon the first failed test" +msgstr "langsung keluar pada saat kegagalan tes pertama" + +#: t/unit-tests/unit-test.c +msgid "suite[::test]" +msgstr "suite[::test]" + +#: t/unit-tests/unit-test.c +msgid "run only test suite or individual test <suite[::test]>" +msgstr "hanya jalankan rangkaian tes atau tes individu <suite[::test]>" + +#: t/unit-tests/unit-test.c +msgid "suite" +msgstr "rangkaian" + +#: t/unit-tests/unit-test.c +msgid "exclude test suite <suite>" +msgstr "kecualikan rangkaian tes <rangkaian>" + #: trailer.c #, c-format msgid "running trailer command '%s' failed" @@ -27821,6 +28347,11 @@ msgstr "kesalahan: " msgid "warning: " msgstr "peringatan: " +#: version.c +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() gagal dengan kesalahan '%s' (%d)\n" + #: walker.c msgid "Fetching objects" msgstr "Mengambil objek" @@ -27861,6 +28392,10 @@ msgstr "berkas .git rusak" msgid ".git file incorrect" msgstr "berkas .git salah" +#: worktree.c +msgid ".git file absolute/relative path mismatch" +msgstr "jalur absolut/relative berkas .git tidak cocok" + #: worktree.c msgid "not a valid path" msgstr "bukan jalur valid" @@ -27882,6 +28417,10 @@ msgstr "tidak dapat menempatkan repositori; berkas .git rusak" msgid "gitdir unreadable" msgstr "gitdir tidak dapat dibaca" +#: worktree.c +msgid "gitdir absolute/relative path mismatch" +msgstr "jalur absolut/relatif gitdir tidak cocok" + #: worktree.c msgid "gitdir incorrect" msgstr "gitdir salah" @@ -27926,6 +28465,16 @@ msgstr "tidak dapat menyetel balik %s di '%s'" msgid "failed to set extensions.worktreeConfig setting" msgstr "gagal menyetel setelan extensions.worktreeConfig" +#: worktree.c +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"tidak dapat meningkatkan format repositori untuk mendukung pohon kerja " +"relatif" + +#: worktree.c +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "gagal menyetel setelan extensions.relativeWorktrees" + #: wrapper.c #, c-format msgid "could not setenv '%s'" @@ -28629,6 +29178,10 @@ msgstr "'%s.final' berisi email yang dibuat.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases tidak kompatibel dengan opsi yang lain\n" +#: git-send-email.perl +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases dan --translate-aliases saling eksklusif\n" + #: git-send-email.perl msgid "" "fatal: found configuration options for 'sendmail'\n" diff --git a/po/it.po b/po/it.po index c31560834d8f2b..20fd8bb28d8589 100644 --- a/po/it.po +++ b/po/it.po @@ -17602,7 +17602,7 @@ msgstr "Controllo la ridenominazione di '%s' in '%s'\n" #: builtin/mv.c:185 msgid "bad source" -msgstr "sourgente errata" +msgstr "sorgente errata" #: builtin/mv.c:188 msgid "can not move directory into itself" diff --git a/po/ko.po b/po/ko.po index 5d190e52380864..7a6847f0236711 100644 --- a/po/ko.po +++ b/po/ko.po @@ -7,6 +7,7 @@ # Changwoo Ryu <cwryu@debian.org>, 2015-2018. # Sihyeon Jang <uneedsihyeon@gmail.com>, 2018. # Gwan-gyeong Mun <elongbug@gmail.com>, 2018. +# Seoyeon Kwon <syeon0204@gmail.com>, 2025. # # - 작업자는 위 Contributors 목록에 추가해 주세요. # - 번역하면서 80컬럼을 넘어가지 않도록 해 주세요. @@ -7666,7 +7667,7 @@ msgid "" " git commit --allow-empty\n" "\n" msgstr "" -"이전 커맷 빼오기가 비어 있습니다. 아마도 충돌 해결 과정에서 그렇게 됐을\n" +"이전 커밋 빼오기가 비어 있습니다. 아마도 충돌 해결 과정에서 그렇게 됐을\n" "것입니다. 그래도 커밋하려면 다음과 같이 하십시오:\n" "\n" " git commit --allow-empty\n" diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 00000000000000..d7154b6395b2bf --- /dev/null +++ b/po/meson.build @@ -0,0 +1,27 @@ +i18n = import('i18n') + +translations = i18n.gettext('git', + languages: [ + 'bg', + 'ca', + 'de', + 'el', + 'es', + 'fr', + 'id', + 'is', + 'it', + 'ko', + 'pl', + 'pt_PT', + 'ru', + 'sv', + 'tr', + 'uk', + 'vi', + 'zh_CN', + 'zh_TW', + ], + install: true, +) +test_dependencies += translations[0] diff --git a/po/sv.po b/po/sv.po index 4e0516818377a3..42c357e54f093e 100644 --- a/po/sv.po +++ b/po/sv.po @@ -1,14 +1,14 @@ # Swedish translations for Git. -# Copyright (C) 2010-2024 Peter Krefting <peter@softwolves.pp.se> +# Copyright (C) 2010-2025 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-2024. +# Peter Krefting <peter@softwolves.pp.se>, 2010-2025. # msgid "" msgstr "" -"Project-Id-Version: git 2.46.0\n" +"Project-Id-Version: git 2.49.0\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-20 21:56+0100\n" -"PO-Revision-Date: 2024-07-21 14:53+0100\n" +"POT-Creation-Date: 2025-03-10 17:45+0100\n" +"PO-Revision-Date: 2025-03-10 17:48+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Svenska <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -542,7 +542,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - lämna stycket obestämt, se nästa obestämda stycke\n" @@ -553,7 +553,7 @@ msgstr "" "/ - sök efter stycke som motsvarar angivet reguljärt uttryck\n" "s - dela aktuellt stycke i mindre styckens\n" "e - redigera aktuellt stycke manuellt\n" -"p - visa aktuellt stycke\n" +"p - visa aktuellt stycke, ”P” för att använda bläddrare\n" "? - visa hjälp\n" #, c-format @@ -624,10 +624,10 @@ msgstr "Endast binära filer ändrade." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Slå av meddelandet med ”git config advice.%s false”" +"Slå av meddelandet med ”git config set advice.%s false”" #, c-format msgid "%shint:%s%.*s%s\n" @@ -664,7 +664,7 @@ msgstr "" "som lämpligt för att ange lösning och checka in." msgid "Exiting because of an unresolved conflict." -msgstr "Avslutar på grund av olöst konflikgt." +msgstr "Avslutar på grund av olöst konflikt." msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Du har inte avslutat sammanslagningen (MERGE_HEAD finns)." @@ -1229,6 +1229,15 @@ msgstr "" "försök en trevägssammanslagning, fall tillbaka på normal patch om det " "misslyckas" +msgid "for conflicts, use our version" +msgstr "för konflikter, använd vår version" + +msgid "for conflicts, use their version" +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 "build a temporary index based on embedded index information" msgstr "bygg ett temporärt index baserat på inbyggd indexinformation" @@ -1274,6 +1283,9 @@ msgstr "lägg till <rot> i alla filnamn" msgid "don't return error for empty patches" msgstr "ge inte någon felkod för tomma patchar" +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs, och --union kräver --3way" + #, c-format msgid "cannot stream blob %s" msgstr "kan inte strömma blob:en %s" @@ -1288,7 +1300,7 @@ msgstr "fel i deflate (%d)" #, c-format msgid "unable to start '%s' filter" -msgstr "kane inte starta filtret ”%s”" +msgstr "kan inte starta filtret ”%s”" msgid "unable to redirect descriptor" msgstr "kan inte omdirigera handtag" @@ -1345,6 +1357,10 @@ msgstr "objektnamnet är inte giltigt: %s" msgid "not a tree object: %s" msgstr "inte ett trädobjekt: %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "misslyckades packa upp trädobjektet %s" + #, c-format msgid "File not found: %s" msgstr "Hittar inte filen: %s" @@ -1461,7 +1477,7 @@ msgid "" "Use '\\!' for literal leading exclamation." msgstr "" "Negativa mönster ignoreras i git-attribut\n" -"Använd '\\!' för att inleda med ett utropstecken." +"Använd ”\\!” för att inleda med ett utropstecken." #, c-format msgid "cannot fstat gitattributes file '%s'" @@ -2044,7 +2060,7 @@ msgid "" "It does not apply to blobs recorded in its index." msgstr "" "Har du handredigerat din patch?\n" -"Den kan inte tillämpas på blobbar som antecknats i dess index." +"Den kan inte tillämpas på blob:ar som antecknats i dess index." msgid "Falling back to patching base and 3-way merge..." msgstr "" @@ -2300,6 +2316,18 @@ msgstr "git archive: protokollfel" msgid "git archive: expected a flush" msgstr "git archive: förväntade en tömning (flush)" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "problem med att läsa filen sparse-checkout" + +msgid "Minimum number of objects to request at a time" +msgstr "Minsta antal objekt att be om varje gång" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Begränsa saknade objekt till befintlig ”sparse-checkout”" + msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2440,9 +2468,6 @@ msgstr "" "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" -msgstr "misslyckades starta revisionstraversering\n" - #, c-format msgid "could not open '%s' for appending" msgstr "kunde inte öppna ”%s” för tillägg" @@ -2799,7 +2824,7 @@ msgstr "kunde inte slå upp HEAD" #, c-format msgid "HEAD (%s) points outside of refs/heads/" -msgstr "HEAD (%s) pekar utenför refs/heads/" +msgstr "HEAD (%s) pekar utanför refs/heads/" #, c-format msgid "branch %s is being rebased at %s" @@ -2815,7 +2840,7 @@ msgstr "HEAD i arbetskatalogen %s har inte uppdaterats" #, c-format msgid "invalid branch name: '%s'" -msgstr "gelaktigt namn på gren: ”%s”" +msgstr "felaktigt namn på gren: ”%s”" #, c-format msgid "no commit on branch '%s' yet" @@ -2908,7 +2933,7 @@ msgid "delete branch (even if not merged)" msgstr "ta bort gren (även om inte helt sammanslagen)" msgid "move/rename a branch and its reflog" -msgstr "flytta/ta bort en gren och dess reflogg" +msgstr "flytta/ta bort en gren och dess referenslogg" msgid "move/rename a branch, even if target exists" msgstr "flytta/ta bort en gren, även om målet finns" @@ -2917,7 +2942,7 @@ msgid "do not output a newline after empty formatted refs" msgstr "skriv inte ut ett nyradstecken efter tomma formaterade referenser" msgid "copy a branch and its reflog" -msgstr "kopiera en gren och dess reflogg" +msgstr "kopiera en gren och dess referenslogg" msgid "copy a branch, even if target exists" msgstr "kopiera en gren, även om målet finns" @@ -2929,7 +2954,7 @@ msgid "show current branch name" msgstr "visa namn på aktuell gren" msgid "create the branch's reflog" -msgstr "skapa grenens reflogg" +msgstr "skapa grenens referenslogg" msgid "edit the description for the branch" msgstr "redigera beskrivning för grenen" @@ -3042,10 +3067,6 @@ msgstr "" 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" - msgid "compiler info: " msgstr "kompilatorinfo:" @@ -3082,7 +3103,7 @@ msgid "" "You can delete any lines you don't wish to share.\n" msgstr "" "Tack för att du skriver en buggraport för Git!\n" -"Om du svarar på följande frågor är det lättare för oss att första " +"Om du svarar på följande frågor är det lättare för oss att förstå " "problemet.\n" "Skriv gärna på engelska\n" "\n" @@ -3288,7 +3309,7 @@ msgid "read commands from stdin" msgstr "läs kommandon från standard in" msgid "with --batch[-check]: ignores stdin, batches all known objects" -msgstr "med --batch[-check]: ignorear standard in, buntar alla kända objekt" +msgstr "med --batch[-check]: ignorerar standard in, buntar alla kända objekt" msgid "Change or optimize batch output" msgstr "Ändra eller optimera buntutdata" @@ -3319,11 +3340,11 @@ msgid "blob|tree" msgstr "blob|träd" msgid "use a <path> for (--textconv | --filters); Not with 'batch'" -msgstr "använd en <sökväg> för (--textconv | --filters): Inte med 'batch'" +msgstr "använd en <sökväg> för (--textconv | --filters): Inte med ”batch”" #, c-format msgid "'%s=<%s>' needs '%s' or '%s'" -msgstr "'%s=<%s>' behöver '%s' eller '%s'" +msgstr "”%s=<%s>” behöver ”%s” eller ”%s”" msgid "path|tree-ish" msgstr "sökväg|träd-igt" @@ -3355,13 +3376,13 @@ msgid "" "git check-attr [--source <tree-ish>] [-a | --all | <attr>...] [--] " "<pathname>..." msgstr "" -"git check-attr [--source <träd:igt>] [-a | --all | <attr>...] [--] " +"git check-attr [--source <träd-igt>] [-a | --all | <attr>...] [--] " "<sökväg>..." msgid "" "git check-attr --stdin [-z] [--source <tree-ish>] [-a | --all | <attr>...]" msgstr "" -"git check-attr --stdin [-z] [--source <träd:igt>] [-a | --all | <attr>...]" +"git check-attr --stdin [-z] [--source <träd-igt>] [-a | --all | <attr>...]" msgid "report all attributes set on file" msgstr "visa alla attribut som satts på filen" @@ -3414,9 +3435,14 @@ msgstr "git check-mailmap [<flaggor>] <kontakt>..." msgid "also read contacts from stdin" msgstr "läs även kontakter från standard in" -#, c-format -msgid "unable to parse contact: %s" -msgstr "kan inte tolka kontakt: %s" +msgid "read additional mailmap entries from file" +msgstr "läs ytterligare mailmap-poster från fil" + +msgid "blob" +msgstr "blob" + +msgid "read additional mailmap entries from blob" +msgstr "läs ytterligare mailmap-poster från blob" msgid "no contacts specified" msgstr "inga kontakter angavs" @@ -3669,13 +3695,13 @@ 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 @@ -3764,6 +3790,10 @@ msgstr "sökvägar kan inte användas vid byte av gren" msgid "'%s' cannot be used with switching branches" msgstr "”%s” kan inte användas vid byte av gren" +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "”%s” behöver sökvägar att checka ut" + #, c-format msgid "'%s' cannot be used with '%s'" msgstr "”%s” kan inte användas med ”%s”" @@ -3777,7 +3807,7 @@ msgid "Cannot switch branch to a non-commit '%s'" msgstr "Kan inte växla gren till icke-incheckningen ”%s”" msgid "missing branch or commit argument" -msgstr "saknar gren- eller incheckingsargument" +msgstr "saknar gren- eller incheckningsargument" #, c-format msgid "unknown conflict style '%s'" @@ -3807,9 +3837,8 @@ msgstr "ny ofödd gren" msgid "update ignored files (default)" msgstr "uppdatera ignorerade filer (standard)" -msgid "do not check if another worktree is holding the given ref" -msgstr "" -"kontrollera inte om en annan arbetskatalog håller den angivna referensen" +msgid "do not check if another worktree is using this branch" +msgstr "kontrollera inte om en annan arbetskatalog använder grenen" msgid "checkout our version for unmerged files" msgstr "checka ut vår version för ej sammanslagna filer" @@ -3866,7 +3895,7 @@ msgid "create/reset and checkout a branch" msgstr "skapa/nollställ och checka ut en gren" msgid "create reflog for new branch" -msgstr "skapa reflogg för ny gren" +msgstr "skapa referenslogg för ny gren" msgid "second guess 'git checkout <no-such-branch>' (default)" msgstr "förutspå ”git checkout <gren-saknas>” (förval)" @@ -4041,8 +4070,91 @@ msgstr "ta endast bort ignorerade filer" msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "clean.requireForce är true och -f angavs inte: vägrar städa" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<flaggor>] [--] <arkiv> [<kat>]" +#, c-format +msgid "info: Could not add alternate for '%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”" + +#, c-format +msgid "%s exists and is not a directory" +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" + +#, c-format +msgid "failed to start iterator over '%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" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "misslyckades ta bort länken ”%s”" + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "hård länk kan inte kontrolleras vid ”%s”" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "hård länk skiljer sig från källan vid ”%s”" + +#, c-format +msgid "failed to create link '%s'" +msgstr "misslyckades skapa länken ”%s”" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "misslyckades kopiera filen till ”%s”" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "misslyckades iterera över ”%s”" + +#, c-format +msgid "done.\n" +msgstr "klart.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"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" + +msgid "remote did not send all necessary objects" +msgstr "fjärren sände inte alla nödvändiga objekt" + +#, c-format +msgid "unable to update %s" +msgstr "kan inte uppdatera %s" + +msgid "failed to initialize sparse-checkout" +msgstr "misslyckades initiera sparse-checkout" + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut" + +msgid "unable to checkout working tree" +msgstr "kan inte checka ut arbetskatalogen" + +msgid "unable to write parameters to config file" +msgstr "kan inte skriva parametrar till konfigurationsfilen" + +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" msgid "don't clone shallow repository" msgstr "klona inte grunt arkiv" @@ -4095,6 +4207,9 @@ 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" +msgid "clone single revision <rev> and check out" +msgstr "klona ensam revision <rev> och checka ut" + msgid "path to git-upload-pack on the remote" msgstr "sökväg till git-upload-pack på fjärren" @@ -4107,17 +4222,17 @@ msgstr "skapa en grund klon på detta djup" msgid "create a shallow clone since a specific time" msgstr "skapa en grund klon från en angiven tidpunkt" -msgid "revision" -msgstr "revision" +msgid "ref" +msgstr "ref" -msgid "deepen history of shallow clone, excluding rev" -msgstr "fördjupa historik för grund klon, exkludera revisionen" +msgid "deepen history of shallow clone, excluding ref" +msgstr "fördjupa historik för grund klon, exkludera ref" msgid "clone only one branch, HEAD or --branch" msgstr "klona endast en gren, HEAD eller --branch" -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "klona inga taggar och gör att senare hämtningar inte följer dem" +msgid "clone tags, and make later fetches not to follow them" +msgstr "klona taggar och gör att senare hämtningar inte följer dem" msgid "any cloned submodules will be shallow" msgstr "klonade undermoduler kommer vara grunda" @@ -4158,95 +4273,8 @@ msgstr "uri" msgid "a URI for downloading bundles before fetching from origin remote" msgstr "en URI för att hämta buntar innan de hämtas från ursprungsfjärr" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: Kan inte skapa suppleant för ”%s”: %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "misslyckades ta status på ”%s”" - -#, c-format -msgid "%s exists and is not a directory" -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" - -#, c-format -msgid "failed to start iterator over '%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" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "misslyckades ta bort länken ”%s”" - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "hård länk kan inte kontrolleras vid ”%s”" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "hård länk skiljer sig från källan vid ”%s”" - -#, c-format -msgid "failed to create link '%s'" -msgstr "misslyckades skapa länken ”%s”" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "misslyckades kopiera filen till ”%s”" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "misslyckades iterera över ”%s”" - -#, c-format -msgid "done.\n" -msgstr "klart.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"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" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Kunde inte hitta fjärrgrenen %s för att klona." - -msgid "remote did not send all necessary objects" -msgstr "fjärren sände inte alla nödvändiga objekt" - -#, c-format -msgid "unable to update %s" -msgstr "kan inte uppdatera %s" - -msgid "failed to initialize sparse-checkout" -msgstr "misslyckades initiera sparse-checkout" - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut" - -msgid "unable to checkout working tree" -msgstr "kan inte checka ut arbetskatalogen" - -msgid "unable to write parameters to config file" -msgstr "kan inte skriva parametrar till konfigurationsfilen" - -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" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<flaggor>] [--] <arkiv> [<kat>]" msgid "Too many arguments." msgstr "För många argument." @@ -4346,6 +4374,10 @@ msgstr "fjärrtransport rapporterade fel" msgid "Remote branch %s not found in upstream %s" msgstr "Fjärrgrenen %s hittades inte i uppströmsarkivet %s" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "Fjärr-revisionen %s hittades inte i uppströmsarkivet %s" + msgid "You appear to have cloned an empty repository." msgstr "Du verkar ha klonat ett tomt arkiv." @@ -4404,7 +4436,7 @@ msgid "the object directory to store the graph" msgstr "objektkatalogen där grafen ska lagras" msgid "if the commit-graph is split, only verify the tip file" -msgstr "om inchecknignsgrafen är delad, kontrollera bara spetsfilen" +msgstr "om incheckningsgrafen är delad, kontrollera bara spetsfilen" #, c-format msgid "Could not open commit-graph '%s'" @@ -4450,7 +4482,7 @@ msgstr "tillåt skriva en inkrementell incheckningsgraffil" msgid "maximum number of commits in a non-base split commit-graph" msgstr "" -"maximalt antal incheckningar i en delad incheckingsgraf som inte är bad" +"maximalt antal incheckningar i en delad incheckningsgraf som inte är bad" msgid "maximum ratio between two levels of a split commit-graph" msgstr "maximalt förhållande mellan två nivåer av en delad incheckningsgraf" @@ -4459,7 +4491,7 @@ msgid "only expire files older than a given date-time" msgstr "låt tid endast gå ut för filer äldre än givet datum och tid" msgid "maximum number of changed-path Bloom filters to compute" -msgstr "maximalt antal Bloom-filer med ändrad sökväg att beräkna" +msgstr "maximalt antal Bloom-filter med ändrad sökväg att beräkna" msgid "use at most one of --reachable, --stdin-commits, or --stdin-packs" msgstr "använd som mest en av --reachable, --stdin-commits och --stdin-packs" @@ -4519,9 +4551,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree: misslyckades läsa" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4529,9 +4561,9 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<läge>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<läge>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <incheckning> | --fixup [(amend|" -"reword):]<incheckning>)]\n" +"reword):]<incheckning>]\n" " [-F <fil> | -m <medd>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--" "author=<författare>]\n" @@ -4770,7 +4802,7 @@ msgstr "Ange meddelandet en av flaggorna -m eller -F.\n" #, c-format msgid "--author '%s' is not 'Name <email>' and matches no existing author" msgstr "" -"--author '%s' är inte 'Namn <epost>' och motsvarar ingen befintlig författare" +"--author ”%s” är inte ”Namn <epost>” och motsvarar ingen befintlig författare" #, c-format msgid "Invalid ignored mode '%s'" @@ -5022,12 +5054,10 @@ msgstr "git config list [<filflagga>] [<visningsflagga>] [--includes]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" "git config get [<filflagga>] [<visningsflagga>] [--includes] [--all] [--" -"regexp=<reguttr>] [--value=<värde>] [--fixed-value] [--default=<förval>] " -"<namn>" +"regexp] [--value=<värde>] [--fixed-value] [--default=<förval>] <namn>" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5038,10 +5068,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" "git config unset [<filflagga>] [--all] [--value=<värde>] [--fixed-value] " -"<namn> <värde>" +"<namn>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [<filflagga>] <gammalt-namn> <nytt-namn>" @@ -5055,6 +5085,15 @@ msgstr "git config edit [<filflagga>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "git config [<filflagga>] --get-colorbool <namn> [<stdout-är-tty>]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<filflagga>] [<visningsflagga>] [--includes] [--all] [--" +"regexp=<reguttr>] [--value=<värde>] [--fixed-value] [--default=<förval>] " +"<namn>" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5174,7 +5213,7 @@ msgid "writing to stdin is not supported" msgstr "skriva till standard in stöds inte" msgid "writing config blobs is not supported" -msgstr "skriva konfigurations-blobbar stöds inte" +msgstr "skriva konfigurations-blob:ar stöds inte" #, c-format msgid "" @@ -5211,7 +5250,7 @@ msgid "" "section in \"git help worktree\" for details" msgstr "" "--worktree kan inte användas med flera arbetskataloger om inte\n" -"konfigurationsutöknignen worktreeConfig har aktiverats. Läsa stycket\n" +"konfigurationsutökningen worktreeConfig har aktiverats. Läsa stycket\n" "”KONFIGURATIONSFIL” i ”git help worktree” för detaljer" msgid "Other" @@ -5297,7 +5336,7 @@ msgid "editing stdin is not supported" msgstr "redigering av standard in stöds ej" msgid "editing blobs is not supported" -msgstr "redigering av blobbar stöds ej" +msgstr "redigering av blob:ar stöds ej" #, c-format msgid "cannot create configuration file %s" @@ -5398,7 +5437,7 @@ 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" -msgstr "kan inte erhålla låset för lagring av inlogginsuppgifter på %d ms" +msgstr "kan inte erhålla låset för lagring av inloggningsuppgifter på %d ms" msgid "" "git describe [--all] [--tags] [--contains] [--abbrev=<n>] [<commit-ish>...]" @@ -5465,12 +5504,8 @@ msgid "traversed %lu commits\n" msgstr "traverserade %lu incheckningar\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"mer än %i taggar hittades; listar de %i senaste\n" -"gav upp sökningen vid %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "hittade %i taggar; gav upp sökning vid %s\n" #, c-format msgid "describe %s\n" @@ -5577,7 +5612,7 @@ 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å blob:ar angavs: ”%s”" #, c-format msgid "unhandled object '%s' given." @@ -5736,7 +5771,7 @@ msgid "reference parents which are not in fast-export stream by object id" msgstr "referera föräldrar som inte finns i fast-export-ström med objekt-id" msgid "show original object ids of blobs/commits" -msgstr "visa ursprungliga objekt-id för blobbar/incheckningar" +msgstr "visa ursprungliga objekt-id för blob:ar/incheckningar" msgid "label tags with mark ids" msgstr "märk taggar med märke-id" @@ -5758,7 +5793,7 @@ msgid "Expected 'to' command, got %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" +msgstr "Förväntade formatet namn:filnamn för undermodul-omskrivningsflaggan" #, c-format msgid "feature '%s' forbidden in input without --allow-unsafe-features" @@ -5853,8 +5888,8 @@ msgstr "" "false” för att undvika testet\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s sände inte alla nödvändiga objekt\n" +msgid "%s did not send all necessary objects" +msgstr "%s sände inte alla nödvändiga objekt" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -5891,8 +5926,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %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" +msgid "option \"%s\" is ignored for %s" +msgstr "flaggan ”%s” ignoreras för %s" #, c-format msgid "%s is not a valid object" @@ -5902,6 +5937,20 @@ msgstr "%s är inte ett giltigt objekt" msgid "the object %s does not exist" msgstr "objektet %s finns inte" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Kör ”git remote set-head %s %s” för att följa ändringen, eller sätt\n" +"konfigurationsflaggan ”remote %s.followRemoteHEAD” till ett annat värde\n" +"om du inte vill se det här meddelandet. Du kan specifikt inaktivera\n" +"varningen till fjärren ändrar HEAD till något annat genom att köra\n" +"”git config set remote %s.followRemoteHEAD warn-if-not-branch-%s”." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "flera grenar upptäcktes, inkompatibelt med --set-upstream" @@ -6039,6 +6088,9 @@ msgstr "referenskarta" msgid "specify fetch refmap" msgstr "ange referenskarta för ”fetch”" +msgid "revision" +msgstr "revision" + msgid "report that we have only objects reachable from this object" msgstr "rapportera att vi bara har objekt nåbara från detta objektet" @@ -6052,7 +6104,7 @@ msgid "check for forced-updates on all updated branches" msgstr "se efter tvingade uppdateringar i alla uppdaterade grenar" msgid "write the commit-graph after fetching" -msgstr "skriv incheckingsgrafen efter hämtning" +msgstr "skriv incheckningsgrafen efter hämtning" msgid "accept refspecs from stdin" msgstr "ta emot referenser från standard in" @@ -6100,7 +6152,7 @@ msgid "--atomic can only be used when fetching from one remote" msgstr "--atomic kan bara användas vid hämtning från en fjärr" msgid "--stdin can only be used when fetching from one remote" -msgstr "--stdin kan bara användas vid hämtning fårn en fjärr" +msgstr "--stdin kan bara användas vid hämtning från en fjärr" msgid "" "git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]" @@ -6287,11 +6339,11 @@ msgstr "%s: objekt trasigt eller saknas" #, c-format msgid "%s: invalid reflog entry %s" -msgstr "%s: ogiltig reflog-post %s" +msgstr "%s: ogiltig referensloggpost %s" #, c-format msgid "Checking reflog %s->%s" -msgstr "Kontrollerar reflog %s→%s" +msgstr "Kontrollerar referenslogg %s→%s" #, c-format msgid "%s: invalid sha1 pointer %s" @@ -6397,10 +6449,10 @@ msgid "report root nodes" msgstr "rapportera rotnoder" msgid "make index objects head nodes" -msgstr "gör indexojekt till huvudnoder" +msgstr "gör indexobjekt till huvudnoder" msgid "make reflogs head nodes (default)" -msgstr "gör refloggar till huvudnoder (standard)" +msgstr "gör referensloggar till huvudnoder (standard)" msgid "also consider packs and alternate objects" msgstr "ta även hänsyn till paket och supplerande objekt" @@ -6461,11 +6513,11 @@ msgstr "kunde inte skapa fsmonitor-kaka ”%s”" #, c-format msgid "fsmonitor: cookie_result '%d' != SEEN" -msgstr "fsmonitor: cookie_result '%d' != SEEN" +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ådpool på ”%s”" msgid "could not start fsmonitor listener thread" msgstr "kunde inte starta fsmonitor-lyssnartråd" @@ -6568,12 +6620,18 @@ msgstr "var mer grundlig (ökar körtiden)" msgid "enable auto-gc mode" msgstr "aktivera auto-gc-läge" +msgid "perform garbage collection in the background" +msgstr "utför skräpsamling i bakgrunden" + msgid "force running gc even if there may be another gc running" msgstr "tvinga gc-körning även om en annan gc kanske körs" msgid "repack all other packs except the largest pack" msgstr "packa om alla paket förutom det största paketet" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "paketprefix att lagra ett paket som innehåller bortrensade objekt" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "misslyckades tolka värdet %s för gc.logExpiry" @@ -6664,6 +6722,9 @@ 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" +msgid "perform maintenance in the background" +msgstr "utför underhåll i bakgrunden" + msgid "frequency" msgstr "frekvens" @@ -6758,8 +6819,25 @@ msgstr "varken systemd-timer eller crontab är tillgänglig" msgid "%s scheduler is not available" msgstr "%s-schemaläggare är inte tillgänglig" -msgid "another process is scheduling background maintenance" -msgstr "en annan process schemalägger bakgrundsunderhåll" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"Kunde inte skapa ”%s.lock”: %s.\n" +"\n" +"Det verkar som en annan schemalagd git-maintenance(1)-process kör i det\n" +"här arkivet. Se till att inga andra underhållsprocesser körs och försök\n" +"sedan igen. Om det fortfarande misslyckas kanske en git-maintenance(1)-\n" +"process har kraschat i det här arkivet tidigare: ta bort filen manuellt\n" +"för att fortsätta." + +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "kan inte erhålla låset för schemalagt bakgrundsunderhåll" msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=<schemaläggare>]" @@ -7112,7 +7190,7 @@ 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" @@ -7289,7 +7367,7 @@ 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 skriva %s-fil ”%s”" #, c-format msgid "cannot close written %s file '%s'" @@ -7326,9 +7404,26 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "kedjelängd = %d: %lu objekt" msgstr[1] "kedjelängd = %d: %lu objekt" +msgid "could not start pack-objects to repack local links" +msgstr "kunde inte starta pack-objects för att packa om lokala länkar" + +msgid "failed to feed local object to pack-objects" +msgstr "misslyckades sända lokala objekt till pack-objects" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: Förväntar kompletta hex-objekt-ID-rader endast från pack-objects." + +msgid "could not finish pack-objects to repack local links" +msgstr "kunde inte avsluta pack-objects för att packa om lokala länkar" + msgid "Cannot come back to cwd" msgstr "Kan inte gå tillbaka till arbetskatalogen (cwd)" +#, c-format +msgid "bad --pack_header: %s" +msgstr "felaktig --pack_header: %s" + #, c-format msgid "bad %s" msgstr "felaktig %s" @@ -7337,6 +7432,9 @@ msgstr "felaktig %s" msgid "unknown hash algorithm '%s'" msgstr "okänd hashningsalgoritm ”%s”" +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor kan inte användas med ett paketnamn" + msgid "--stdin requires a git repository" msgstr "--stdin kräver ett git-arkiv" @@ -7521,9 +7619,6 @@ msgstr "-L<intervall>:<fil> kan inte användas med sökvägsspecifikation" msgid "Final output: %d %s\n" msgstr "Slututdata: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "kan inte skapa temporär objektkatalog" - #, c-format msgid "git show %s: bad file" msgstr "git show %s: felaktig fil" @@ -7655,7 +7750,7 @@ msgid "cover-from-description-mode" 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" +msgstr "skapa delar av omslagsbrevet baserat på grenbeskrivningen" msgid "use branch description from file" msgstr "använd grenbeskrivningar från fil" @@ -7897,10 +7992,10 @@ msgid "show debugging data" msgstr "visa felsökningsutdata" msgid "suppress duplicate entries" -msgstr "undertyck dublettposter" +msgstr "undertryck dublettposter" msgid "show sparse directories in the presence of a sparse index" -msgstr "visa glesa kataloger när et glest index existerar" +msgstr "visa glesa kataloger när ett glest index existerar" msgid "" "--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, " @@ -7989,7 +8084,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 hakparenteser som inte är ”patch” i ärenderaden" msgid "copy Message-ID to the end of commit message" msgstr "kopiera Message-ID till slutet av incheckningsmeddelandet" @@ -8080,15 +8175,6 @@ msgstr "använd diff3-baserad sammanslagning" msgid "use a zealous diff3 based merge" msgstr "använd nitisk diff3-baserad sammanslagning" -msgid "for conflicts, use our version" -msgstr "för konflikter, använd vår version" - -msgid "for conflicts, use their version" -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>" @@ -8153,7 +8239,7 @@ msgid "git merge-tree [--write-tree] [<options>] <branch1> <branch2>" msgstr "git merge-tree [--write-tree] [<flaggor>] <gren1> <gren2>" msgid "git merge-tree [--trivial-merge] <base-tree> <branch1> <branch2>" -msgstr "git merge-tree [--trivial-merge] <baseträd> <gren1> <gren2>" +msgstr "git merge-tree [--trivial-merge] <basträd> <gren1> <gren2>" msgid "do a real merge instead of a trivial merge" msgstr "gör en riktig sammanslagning istället för en enkel sammanslagning" @@ -8193,10 +8279,6 @@ msgstr "okänd strategiflagga: -X%s" msgid "malformed input line: '%s'." msgstr "felaktig indatarad: ”%s”." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "sammanslagning kan inte fortsätta; fick inte rent resultat från %d" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<flaggor>] [<incheckning>...]" @@ -8553,6 +8635,9 @@ msgstr "paket att återanvända vid beräkning av multipaketsbitkarta" msgid "write multi-pack bitmap" msgstr "skriv flerpaketsbitkarta" +msgid "write a new incremental MIDX" +msgstr "skriv en ny inkrementell MIDX" + msgid "write multi-pack index containing only given indexes" msgstr "skriv flerpaketsindex som endast innehåller angivna index" @@ -8686,11 +8771,11 @@ msgstr "git notes [--ref <anteckningsref>] [list [<objekt>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <anteckningsref>] add [-f] [--allow-empty] [--" "[no-]separator|--separator=<styckebrytning>] [--[no-]stripspace] [-m <medd> " -"| -F <fil> | (-c | -C) <objekt>] [<objekt>]" +"| -F <fil> | (-c | -C) <objekt>] [<objekt>] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" @@ -8699,11 +8784,11 @@ msgstr "" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <anteckningsref>] append [--allow-empty] [--" "[no-]separator|--separator=<styckebrytning>] [--[no-]stripspace] [-m <medd> " -"| -F <fil> | (-c | -C) <objekt>] [<objekt>]" +"| -F <fil> | (-c | -C) <objekt>] [<objekt>] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref <anteckningsref>] edit [--allow-empty] [<objekt>]" @@ -8822,6 +8907,9 @@ msgstr "anteckningsinnehåll i en fil" msgid "reuse and edit specified note object" msgstr "återanvänd och redigera angivet anteckningsobjekt" +msgid "edit note message in editor" +msgstr "redigera anteckning i textredigeringsprogram" + msgid "reuse specified note object" msgstr "återanvänd angivet anteckningsobjekt" @@ -8895,7 +8983,7 @@ msgid "failed to remove 'git notes merge' worktree" 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" +msgstr "misslyckades läsa referensen NOTES_MERGE_PARTIAL" msgid "could not find commit from NOTES_MERGE_PARTIAL." msgstr "kunde inte hitta incheckning från NOTES_MERGE_PARTIAL." @@ -9006,6 +9094,13 @@ msgid "" msgstr "" "git pack-objects [<flaggor>] <basnamn> [< <reflista> | < <objektlista>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "ogiltig flagga för --name-hash-version: %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "--write-bitmap-index kräver för närvarande, --name-hash-version=1" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9116,14 +9211,14 @@ msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" msgstr "" -"värdet på uploadpack.blobpackfileuri måste vara på formen '<objekt-hash> " -"<paket-hash> <uri>' (fick '%s')" +"värdet på uploadpack.blobpackfileuri måste vara på formen ”<objekt-hash> " +"<paket-hash> <uri>” (fick ”%s”)" #, c-format msgid "" "object already configured in another uploadpack.blobpackfileuri (got '%s')" msgstr "" -"objektet redan konfigurerat i et annat uploadpack.blobpackfileuri (fick '%s)" +"objektet redan konfigurerat i ett annat uploadpack.blobpackfileuri (fick ”%s”" #, c-format msgid "could not get type of object %s in pack %s" @@ -9170,7 +9265,7 @@ msgstr "kan inte öppna paketfilen" #, c-format msgid "loose object at %s could not be examined" -msgstr "lösa objekt på %s kunde inte underökas" +msgstr "lösa objekt på %s kunde inte undersökas" msgid "unable to force loose object" msgstr "kan inte tvinga lösa objekt" @@ -9314,6 +9409,9 @@ msgstr "hantering av saknade objekt" msgid "do not pack objects in promisor packfiles" msgstr "packa inte objekt i kontraktspackfiler" +msgid "implies --missing=allow-any" +msgstr "implicerar --missing=allow-any" + msgid "respect islands during delta compression" msgstr "respektera öar under deltakomprimering" @@ -9324,6 +9422,10 @@ msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "" "uteslut redan konfigurerade uploadpack.blobpackfileuri med detta protokoll" +msgid "use the specified name-hash function to group similar objects" +msgstr "" +"använd den angivna namn-hash-funktionen för att gruppera liknande objekt" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "deltakedjedjupet %d är för djupt, påtvingar %d" @@ -9616,7 +9718,7 @@ msgid "Need to specify how to reconcile divergent branches." msgstr "Måste ange hur avvikande grenar skall förlikas." msgid "cannot rebase with locally recorded submodule modifications" -msgstr "kan inte ombasera med lokalt lagrade ändringar i undermoful" +msgstr "kan inte ombasera med lokalt lagrade ändringar i undermodul" msgid "git push [<options>] [<repository> [<refspec>...]]" msgstr "git push [<flaggor>] [<arkiv> [<refspec>...]]" @@ -10112,7 +10214,7 @@ msgstr "" "Ange vilken gren du vill ombasera mot.\n" "Se git-rebase(1) för detaljer.\n" "\n" -" git rebase '<gren>'\n" +" git rebase ”<gren>”\n" "\n" #, c-format @@ -10134,7 +10236,7 @@ msgid "empty exec command" msgstr "tomt exec-kommando" msgid "rebase onto given branch instead of upstream" -msgstr "ombasera mot given grenen istället för uppström" +msgstr "ombasera mot given gren istället för uppström" msgid "use the merge-base of upstream and branch as the current base" msgstr "använd sammanslagningsbasen mellan uppströms och gren som aktuell bas" @@ -10526,7 +10628,8 @@ msgid "process the reflogs of all references" msgstr "hantera referensloggar för alla referenser" msgid "limits processing to reflogs from the current worktree only" -msgstr "begränsar hantering av referensloggar till endst aktuell arbetskatalog" +msgstr "" +"begränsar hantering av referensloggar till endast aktuell arbetskatalog" #, c-format msgid "Marking reachable objects..." @@ -10543,8 +10646,11 @@ msgstr "ingen referenslogg att ta bort angavs" msgid "invalid ref format: %s" msgstr "felaktigt referensformat: %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<format> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "ange referensformatet att konvertera till" @@ -10552,6 +10658,9 @@ msgstr "ange referensformatet att konvertera till" msgid "perform a non-destructive dry-run" msgstr "utför ett icke-destruktiv testkörning" +msgid "drop reflogs entirely during the migration" +msgstr "kasta referensloggar helt under migreringen" + msgid "missing --ref-format=<format>" msgstr "saknad --ref-format=<format>" @@ -10559,6 +10668,12 @@ msgstr "saknad --ref-format=<format>" msgid "repository already uses '%s' format" msgstr "arkivet använder redan ”%s”-format" +msgid "enable strict checking" +msgstr "aktivera strikt kontroll" + +msgid "'git refs verify' takes no arguments" +msgstr "”git refs verify” tar inget argument" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -10888,6 +11003,30 @@ 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:" +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "”%s/HEAD” är oförändrad och pekar på ”%s”\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "”%s/HEAD” har ändrats från ”%s” och pekar nu på ”%s”\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "”%s/HEAD” har nu skapats och pekar på ”%s”\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "”%s/HEAD” kopplades från vid ”%s” och pekar nu på ”%s”\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"”%s/HEAD” pekade tidigare på ”%s” (som inte är en fjärrgren), men pekar nu " +"på ”%s”\n" + msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "sätt refs/remotes/<namn>/HEAD enligt fjärren" @@ -10909,7 +11048,7 @@ msgid "Not a valid ref: %s" msgstr "Inte en giltig referens: %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "Kunde inte ställa in %s" #, c-format @@ -10981,8 +11120,14 @@ msgstr "Kommer inte ta bort alla icke-sänd-URL:er" msgid "be verbose; must be placed before a subcommand" msgstr "var pratsam; måste skrivas före ett underkommando" -msgid "git repack [<options>]" -msgstr "git repack [<flaggor>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<paket-namn>]\n" +"[--write-midx] [--name-hash-version=<n>]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11056,6 +11201,12 @@ msgstr "sänd --no-reuse-delta till git-pack-objects" msgid "pass --no-reuse-object to git-pack-objects" msgstr "sänd --no-reuse-object till git-pack-objects" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"ange den namnhash-version som ska användas för att gruppera liknande objekt " +"efter sökväg" + msgid "do not run git-update-server-info" msgstr "kör inte git-update-server-info" @@ -11104,9 +11255,6 @@ msgstr "hitta ett geometrisk förlopp med faktor <N>" msgid "write a multi-pack index of the resulting packs" 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" @@ -11323,9 +11471,6 @@ 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" @@ -11756,7 +11901,7 @@ 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" +"köa dina ändringar i .gitmodules eller använd ”stash” för att fortsätta" #, c-format msgid "not removing '%s' recursively without -r" @@ -11830,7 +11975,7 @@ msgid "linewrap output" msgstr "radbryt utdata" msgid "field" -msgstr "föt" +msgstr "fält" msgid "group by field" msgstr "gruppera efter fält" @@ -11910,7 +12055,7 @@ msgid "<n>[,<base>]" msgstr "<n>[,<bas>]" msgid "show <n> most recent ref-log entries starting at base" -msgstr "visa <n> nyaste refloggposter med början på bas" +msgstr "visa <n> nyaste referensloggposter med början på bas" msgid "no branches given, and HEAD is not valid" msgstr "inga grenar angavs, och HEAD är inte giltigt" @@ -11978,11 +12123,11 @@ msgstr "referensen existerar inte" msgid "failed to look up reference" msgstr "misslyckades slå upp referensen" -msgid "only show tags (can be combined with branches)" -msgstr "visa endast taggar (kan kombineras med grenar)" +msgid "only show tags (can be combined with --branches)" +msgstr "visa endast taggar (kan kombineras med --branches)" -msgid "only show branches (can be combined with tags)" -msgstr "visa endast grenar (kan kombineras med taggar)" +msgid "only show branches (can be combined with --tags)" +msgstr "visa endast grenar (kan kombineras med --tags)" msgid "check for reference existence without resolving" msgstr "kontrollerar att referensen existerar utan att slå upp dem" @@ -11991,7 +12136,7 @@ msgid "stricter reference checking, requires exact ref path" msgstr "striktare referenskontroll, kräver exakt referenssökväg" msgid "show the HEAD reference, even if it would be filtered out" -msgstr "visa HEAD-refrens, även när den skulle filtreras ut" +msgstr "visa HEAD-referens, även när den skulle filtreras ut" msgid "dereference tags into object IDs" msgstr "avreferera taggar till objekt-id" @@ -12024,7 +12169,7 @@ 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 " +"katalogen ”%s” innehåller ospårade filer, men är inte i området som anges i " "”sparse-checkout”" #, c-format @@ -12034,6 +12179,10 @@ msgstr "misslyckades ta bort katalogen ”%s”" msgid "failed to create directory for sparse-checkout file" msgstr "misslyckades skapa katalog för ”sparse-checkout”-filen" +#, c-format +msgid "unable to fdopen %s" +msgstr "kan inte utföra fdopen %s" + msgid "failed to initialize worktree config" msgstr "misslyckades initiera arbetskataloginställning" @@ -12044,7 +12193,7 @@ msgid "initialize the sparse-checkout in cone mode" msgstr "initiera sparse-checkout i konläge" msgid "toggle the use of a sparse index" -msgstr "slå på/av använding av glest index" +msgstr "slå på/av användning av glest index" #, c-format msgid "unable to create leading directories of %s" @@ -12215,7 +12364,7 @@ msgstr "Inga ”stash”-poster hittades." #, c-format msgid "%s is not a valid reference" -msgstr "%s är inte en giltigt referens" +msgstr "%s är inte en giltig referens" msgid "git stash clear with arguments is unimplemented" msgstr "”git stash clear” med argument har inte implementerats" @@ -12466,7 +12615,7 @@ msgstr "" "HEAD" msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]" -msgstr "git submodule status [--quitet] [--cached] [--recursive] [<sökväg>...]" +msgstr "git submodule status [--quiet] [--cached] [--recursive] [<sökväg>...]" #, c-format msgid "* %s %s(blob)->%s(submodule)" @@ -12485,11 +12634,11 @@ msgid "couldn't hash object from '%s'" msgstr "kunde inte hasha objekt från ”%s”" #, c-format -msgid "unexpected mode %o\n" -msgstr "okänt läge %o\n" +msgid "unexpected mode %o" +msgstr "okänt läge %o" msgid "use the commit stored in the index instead of the submodule HEAD" -msgstr "använd incechkning lagrad i indexet istället för undermodulens HEAD" +msgstr "använd incheckning lagrad i indexet istället för undermodulens HEAD" msgid "compare the commit in the index with that in the submodule HEAD" msgstr "jämför incheckningen i indexet med den i undermodulens HEAD" @@ -12612,7 +12761,7 @@ msgstr "misslyckades klona ”%s” till undermodulsökvägen ”%s”" #, c-format msgid "could not get submodule directory for '%s'" -msgstr "kunde inte få tag i undermodulkatalog för ”%s”" +msgstr "kunde inte få tag i undermodulskatalog för ”%s”" msgid "alternative anchor for relative paths" msgstr "alternativa ankare för relativa sökvägar" @@ -12716,8 +12865,8 @@ 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ämtning av incheckningen misslyckades." +"Hämtade i undermodulsö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'" @@ -13085,7 +13234,7 @@ msgid "replace the tag if exists" msgstr "ersätt taggen om den finns" msgid "create a reflog" -msgstr "skapa en reflog" +msgstr "skapa en referenslogg" msgid "Tag listing options" msgstr "Alternativ för listning av taggar" @@ -13606,6 +13755,9 @@ msgstr "ställ in spårningsläge (se git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "försök träffa namn på ny gren mot en fjärrspårande gren" +msgid "use relative paths for worktrees" +msgstr "använd relativa sökvägar för arbetskataloger" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "flaggorna ”%s”, ”%s” och ”%s” kan inte användas samtidigt" @@ -13767,7 +13919,7 @@ 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äge från URI:en ”%s”" #, c-format msgid "exceeded bundle URI recursion limit (%d)" @@ -13807,7 +13959,7 @@ msgstr "okänd kapabilitet ”%s”" #, c-format msgid "'%s' does not look like a v2 or v3 bundle file" -msgstr "'%s' ser inte ut som en v2- eller v3-bunt-fil" +msgstr "”%s” ser inte ut som en v2- eller v3-bunt-fil" #, c-format msgid "unrecognized header: %s%s (%d)" @@ -13877,6 +14029,26 @@ msgstr "kan inte skapa ”%s”" msgid "index-pack died" msgstr "index-pack dog" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "katalogen ”%s” finns i indexet, men inte glest" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "trasigt cacheträd innehåller poster som inte finns i indexet" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s med flaggorna 0x%x borde inte finnas i cacheträdet" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "felaktigt underträd ”%.*s”" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "" +"cacheträd för sökvägen %.*s stämmer inte överens. Förväntade %s fick %s" + msgid "terminating chunk id appears earlier than expected" msgstr "avslutande stycke-id förekommer tidigare än förväntat" @@ -13921,6 +14093,9 @@ msgstr "Importera ett GNU Arch-arkiv till Git" msgid "Create an archive of files from a named tree" msgstr "Skapa ett arkiv över filer från ett namngivet träd" +msgid "Download missing objects in a partial clone" +msgstr "Hämta saknade objekt i en delvis kloning" + msgid "Use binary search to find the commit that introduced a bug" msgstr "Använd binärsökning för att hitta ändringen som introducerade ett fel" @@ -14027,7 +14202,7 @@ msgid "Compare a tree to the working tree or index" msgstr "Jämför en träd med arbetskatalogen eller indexet" msgid "Compares the content and mode of blobs found via two tree objects" -msgstr "Visar innehåll och läge för blobbar som hittats via två trädobjekt" +msgstr "Visar innehåll och läge för blob:ar som hittats via två trädobjekt" msgid "Show changes using common diff tools" msgstr "Visa ändringar med vanliga diff-verktyg" @@ -14096,7 +14271,7 @@ msgid "Send a collection of patches from stdin to an IMAP folder" msgstr "Sänd en samling patchar från stdin till en IMAP-mapp" msgid "Build pack index file for an existing packed archive" -msgstr "SKapa pack-indexfiler för ett befintligt packat arkiv" +msgstr "Skapa pack-indexfiler för ett befintligt packat arkiv" msgid "Create an empty Git repository or reinitialize an existing one" msgstr "Skapa tomt Git-arkiv eller ominitiera ett befintligt" @@ -14318,7 +14493,7 @@ msgid "Creates a temporary file with a blob's contents" msgstr "Skapar temporära filer med innehållet från en blob" msgid "Unpack objects from a packed archive" -msgstr "Packa upp objekt från ett pakat arkiv" +msgstr "Packa upp objekt från ett packat arkiv" msgid "Register file contents in the working tree to the index" msgstr "Registrera filinnehållet från arbetskatalogen i indexet" @@ -14375,7 +14550,7 @@ msgid "Git for CVS users" msgstr "Git för CVS-användare" msgid "Tweaking diff output" -msgstr "Justrea diff-utdata" +msgstr "Justera diff-utdata" msgid "A useful minimum set of commands for Everyday Git" msgstr "Ett användbart minsta uppsättning kommandon för vardags-Git" @@ -14483,7 +14658,7 @@ 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" +msgstr "incheckningsgrafens ändrade-sökvägar-indexstycke är för litet" #, c-format msgid "" @@ -14547,10 +14722,10 @@ 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 incheckningsgrafkedja: rad ”%s” är inte ett hash-värde" msgid "unable to find all commit-graph files" -msgstr "kan inte hitta alla incheckingsgraffiler" +msgstr "kan inte hitta alla incheckningsgraffiler" msgid "invalid commit position. commit-graph is likely corrupt" msgstr "ogiltig incheckningsposition. incheckningsgrafen är troligtvis trasig" @@ -14592,8 +14767,8 @@ msgstr "Samlar refererade incheckningar" #, c-format msgid "Finding commits for commit graph in %<PRIuMAX> pack" msgid_plural "Finding commits for commit graph in %<PRIuMAX> packs" -msgstr[0] "Söker incheckningar för incheckingsgraf i %<PRIuMAX> paket" -msgstr[1] "Söker incheckningar för incheckingsgraf i %<PRIuMAX> paket" +msgstr[0] "Söker incheckningar för incheckningsgraf i %<PRIuMAX> paket" +msgstr[1] "Söker incheckningar för incheckningsgraf i %<PRIuMAX> paket" #, c-format msgid "error adding pack %s" @@ -14604,10 +14779,10 @@ msgid "error opening index for %s" msgstr "fel vid öppning av indexet för %s" msgid "Finding commits for commit graph among packed objects" -msgstr "Söker incheckningar för incheckingsgraf i packade objekt" +msgstr "Söker incheckningar för incheckningsgraf i packade objekt" msgid "Finding extra edges in commit graph" -msgstr "Söker ytterligare kanter i incheckingsgraf" +msgstr "Söker ytterligare kanter i incheckningsgraf" msgid "failed to write correct number of base graph ids" msgstr "misslyckades skriva korrekt antal bas-graf-id:n" @@ -14629,7 +14804,7 @@ msgid "unable to open commit-graph chain file" msgstr "kan inte öppna incheckningsgrafkedjefilen" msgid "failed to rename base commit-graph file" -msgstr "misslyckades byta namn på bas-incheckingsgraffilen" +msgstr "misslyckades byta namn på bas-incheckningsgraffilen" msgid "failed to rename temporary commit-graph file" msgstr "misslyckades byta namn på temporär incheckningsgraffil" @@ -14742,7 +14917,7 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" 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" @@ -14751,7 +14926,7 @@ msgstr "" "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 set advice.graftFileDeprecated false”" #, c-format msgid "commit %s exists in commit-graph but not in the object database" @@ -14859,19 +15034,19 @@ msgstr "kunde inte läsa katalogändringar [GLE %ld]" #, c-format msgid "opendir('%s') failed" -msgstr "opendir('%s') misslyckades" +msgstr "opendir(”%s”) misslyckades" #, c-format msgid "lstat('%s') failed" -msgstr "lstat('%s') misslyckades" +msgstr "lstat(”%s”) misslyckades" #, c-format msgid "strbuf_readlink('%s') failed" -msgstr "strbuf_readlink('%s') misslyckades" +msgstr "strbuf_readlink(”%s”) misslyckades" #, c-format msgid "closedir('%s') failed" -msgstr "closedir('%s') misslyckades" +msgstr "closedir(”%s”) misslyckades" #, c-format msgid "[GLE %ld] unable to open for read '%ls'" @@ -15198,7 +15373,7 @@ 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”" +msgstr "kan inte slå upp konfigurerings-blob:en ”%s”" msgid "unable to parse command-line config" msgstr "kan inte tolka kommandoradskonfiguration" @@ -15560,7 +15735,20 @@ msgstr "url saknar protokoll: %s" #, c-format msgid "credential url cannot be parsed: %s" -msgstr "kan inte tolka url för inloggingsuppgifter: %s" +msgstr "kan inte tolka url för inloggningsuppgifter: %s" + +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "felaktig tidsgräns ”%s”, förväntade ett icke-negativt heltal" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "" +"felaktig värde för init-timeout ”%s”, förväntade ett icke-negativt heltal" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "felaktigt värde för max-connections ”%s”, förväntade ett heltal" msgid "in the future" msgstr "i framtiden" @@ -15818,6 +16006,12 @@ msgstr "ogiltigt argument för %s" msgid "invalid regex given to -I: '%s'" msgstr "ogiltigt reguljärt uttryck angavs för -I: ”%s”" +msgid "-G requires a non-empty argument" +msgstr "-G kräver ett icke-tomt argument" + +msgid "-S requires a non-empty argument" +msgstr "-S kräver ett icke-tomt argument" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "misslyckades tolka argument till flaggan --submodule: ”%s”" @@ -15930,7 +16124,7 @@ msgid "" "do not munge pathnames and use NULs as output field terminators in --raw or " "--numstat" msgstr "" -"skriv inte om sökvägsnamn och använd NUL-tecken som fältseparerare i --raw " +"skriv inte om sökvägsnamn och använd NUL-tecken som fältavdelare i --raw " "eller --numstat" msgid "<prefix>" @@ -15952,7 +16146,7 @@ msgid "use default prefixes a/ and b/" msgstr "använd standardprefixen a/ och b/" msgid "show context between diff hunks up to the specified number of lines" -msgstr "visa sammnhang mellan diff-stycken upp till angivet antal rader" +msgstr "visa sammanhang mellan diff-stycken upp till angivet antal rader" msgid "<char>" msgstr "<tecken>" @@ -16261,6 +16455,20 @@ msgstr "felaktig git-namnrymdssökväg ”%s”" msgid "too many args to run %s" msgstr "för många flaggor för att köra %s" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Du försöker hämta %s som är i incheckningsgrafen men inte i " +"objektdatabasen.\n" +"Det händer antagligen på grund av att arkivet är trasigt.\n" +"Om du försöker reparera det trasiga arkivet genom att hämta om det saknade " +"objektet, använd ”git fetch --refetch” med det saknade objektet." + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: förväntade grund lista" @@ -16331,7 +16539,7 @@ msgid "already have %s (%s)" msgstr "har redan %s (%s)" msgid "fetch-pack: unable to fork off sideband demultiplexer" -msgstr "fetch-patch: kan inte grena (fork) av sidbandsmultiplexare" +msgstr "fetch-patch: kan inte grena (fork) av sidbands-avmultiplexare" msgid "protocol error: bad pack header" msgstr "protokollfel: felaktigt packhuvud" @@ -16458,7 +16666,7 @@ 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: ogiltig sökväg ”%s”" #, c-format msgid "fsmonitor_ipc__send_query: unspecified error on '%s'" @@ -16525,7 +16733,7 @@ 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." +"Se ”git help git” för en översikt över systemet." #, c-format msgid "unsupported command listing type '%s'" @@ -16732,7 +16940,7 @@ msgid "Interacting with Others" msgstr "Interaktion med andra" msgid "Low-level Commands / Manipulators" -msgstr "Lågnivåkommandon / maniupulerare" +msgstr "Lågnivåkommandon / manipulerare" msgid "Low-level Commands / Interrogators" msgstr "Lågnivåkommandon / frågare" @@ -16772,7 +16980,7 @@ msgid "External commands" msgstr "Externa kommandon" msgid "Command aliases" -msgstr "Kommadoalias" +msgstr "Kommandoalias" 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" @@ -16845,10 +17053,10 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set 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”." +"Du kan inaktivera varningen med ”git config set advice.ignoredHook false”." msgid "not a git repository" msgstr "inte ett git-arkiv" @@ -16856,7 +17064,7 @@ msgstr "inte ett git-arkiv" #, c-format msgid "argument to --packfile must be a valid hash (got '%s')" msgstr "" -"argumentet till --packfile måste vara ett giltigt hashvärde (fick '%s')" +"argumentet till --packfile måste vara ett giltigt hashvärde (fick ”%s”)" #, c-format msgid "negative value for http.postBuffer; defaulting to %d" @@ -16865,15 +17073,9 @@ msgstr "http.postBuffer har negativt värde; använder förvalet %d" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Delegerad styrning stöds inte av cURL < 7.22.0" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "Fastnålning av öppen nyckel stöds inte av cURL < 7.39.0" - msgid "Unknown value for http.proactiveauth" msgstr "Okänt värde för http.proactiveauth" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE stöds inte av cURL < 7.44.0" - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "SSL-bakändan ”%s” stöds inte. Dessa SSL-bakändor stöds:" @@ -16898,7 +17100,7 @@ msgid "" " asked for: %s\n" " redirect: %s" msgstr "" -"kan inte uppdatera urlbas från omdirigerin:\n" +"kan inte uppdatera urlbas från omdirigering:\n" " bad om: %s\n" " omdirigering: %s" @@ -17031,13 +17233,16 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "Kunde inte skapa ”%s.lock”: %s" +msgid "unable to create temporary object directory" +msgstr "kan inte skapa temporär objektkatalog" + #, c-format msgid "could not write loose object index %s" msgstr "kunde inte skriva löst objektindex %s" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "misslyckades skriva löst objektindex %s\n" +msgid "failed to write loose object index %s" +msgstr "misslyckades skriva löst objektindex %s" #, c-format msgid "unexpected line: '%s'" @@ -17053,6 +17258,10 @@ msgstr "citerad CRLF upptäcktes" msgid "unable to format message: %s" msgstr "kan inte formatera meddelandet: %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "felaktigt värde för marker-size ”%s”, förväntade ett heltal" + #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Misslyckades slå ihop undermodulen %s (ej utcheckad)" @@ -17114,7 +17323,7 @@ msgid "" "CONFLICT (implicit dir rename): Existing file/dir at %s in the way of " "implicit directory rename(s) putting the following path(s) there: %s." msgstr "" -"KONFLIKT (implicit nämnändrad kat): Befintlig fil/kat vid %s är i vägen för " +"KONFLIKT (implicit namnändrad kat): Befintlig fil/kat vid %s är i vägen för " "implicit namnändrad(e) katalog(er) som lägger dit följande sökväg(ar): %s." #, c-format @@ -17276,7 +17485,7 @@ msgid "" " - resolve any other conflicts in the superproject\n" " - commit the resulting index in the superproject\n" msgstr "" -"Rekursiv sammanslaning med undermoduler stöder för närvarande endast enkla " +"Rekursiv sammanslagning med undermoduler stöder för närvarande endast enkla " "fall.\n" "Du måste hantera sammanslagning av undermoduler i konflikt manuellt.\n" "Detta kan göras genom att utföra följande steg:\n" @@ -17586,6 +17795,17 @@ msgstr "kunde inte läsa paket{" msgid "could not open index for %s" msgstr "kunde inte öppna indexet för %s" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "kan inte länka ”%s” till ”%s”" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "misslyckades städa multi-pack-index på %s" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "kan inte skriva inkrementell MIDX med bitkarta" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "ignorerar befintlig multi-pack-index; felaktig kontrollsumma" @@ -17614,18 +17834,33 @@ msgstr "inga paketfiler att indexera." msgid "refusing to write multi-pack .bitmap without any objects" msgstr "kunde inte skriva fler-paketsbitkarta utan några objekt" +msgid "unable to create temporary MIDX layer" +msgstr "kan inte skapa temporärt MIDX-lager" + msgid "could not write multi-pack bitmap" msgstr "kunde inte skriva fler-paketsbitkarta" +msgid "unable to open multi-pack-index chain file" +msgstr "kan inte öppna kedjefil för multi-pack-index" + +msgid "unable to rename new multi-pack-index layer" +msgstr "kan inte byta namn på nytt multi-pack-index-lager" + msgid "could not write multi-pack-index" msgstr "kunde inte skriva flerpakets-index" +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "kan inte låta tid gå ut för paket från inkrementellt multi-pack-index" + msgid "Counting referenced objects" msgstr "Räknar refererade objekt" msgid "Finding and deleting unreferenced packfiles" msgstr "Ser efter och tar bort orefererade packfiler" +msgid "cannot repack an incremental multi-pack-index" +msgstr "kunde packa om ett inkrementellt multi-pack-index" + msgid "could not start pack-objects" msgstr "kunde inte starta pack-objects" @@ -17687,6 +17922,27 @@ msgstr "paketnamnstycke för multi-pack-index är för kort" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "paketnamn för multi-pack-index i fel ordning: ”%s” före ”%s”" +msgid "multi-pack-index chain file too small" +msgstr "kedjefilen för multi-pack-index är för liten" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "antalet paket i bas-MIDX för högt: %<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "antalet object i bas-MIDX för högt: %<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "ogiltig kedja för multi-pack-index: raden ”%s” är inte ett hash-värde" + +msgid "unable to find all multi-pack index files" +msgstr "kan inte hitta alla indexfiler för multi-pack" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "ogiltig MIDX-objektposition, MIDX är troligtvis trasig" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "bad pack-int-id: %u (%u paket totalt)" @@ -17702,11 +17958,7 @@ msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" 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 clear multi-pack-index at %s" -msgstr "misslyckades städa multi-pack-index på %s" +msgstr "stort offset för multi-pack-index utanför gränsen" msgid "multi-pack-index file exists, but failed to parse" msgstr "multi-pack-indexfilen finns, men kunde inte tolkas" @@ -17777,7 +18029,7 @@ msgstr "Kan inte checka in oinitierat/orefererat anteckningsträd" #, c-format msgid "Bad notes.rewriteMode value: '%s'" -msgstr "Felaktigt värde för notes.rewriteMode: '%s'" +msgstr "Felaktigt värde för notes.rewriteMode: ”%s”" #, c-format msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" @@ -17914,10 +18166,22 @@ msgstr "packat objekt %s (lagrat i %s) är trasigt" msgid "missing mapping of %s to %s" msgstr "saknar koppling av %s till %s" +#, c-format +msgid "unable to open %s" +msgstr "kan inte öppna %s" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "filerna ”%s” och ”%s” har olika innehåll" + #, c-format msgid "unable to write file %s" msgstr "kan inte skriva filen %s" +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "kan inte skriva till filen %s som hela tiden försvinner" + #, c-format msgid "unable to set permission to '%s'" msgstr "kan inte sätta behörigheten till ”%s”" @@ -17958,7 +18222,7 @@ 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" @@ -17999,10 +18263,6 @@ msgstr "%s: filtypen stöds ej" msgid "%s is not a valid '%s' object" msgstr "%s är inte ett giltigt ”%s”-objekt" -#, c-format -msgid "unable to open %s" -msgstr "kan inte öppna %s" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "hash stämmer inte för %s (förväntade %s)" @@ -18104,7 +18364,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Git skapar normalt aldrig referenser som slutar med 40 hexadecimala\n" "tecken, då detta ignoreras när du anger 40-hex enbart. Dessa\n" @@ -18114,7 +18374,7 @@ msgstr "" "\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 set advice.objectNameWarning false”" #, c-format msgid "log for '%.*s' only goes back to %s" @@ -18232,7 +18492,7 @@ msgid "" "corrupted bitmap index file (too short to fit pseudo-merge table header)" msgstr "" "trasig bitkarteindexfil (för kort för att få plats för pseudo-" -"sammanslagningsatbellhuvudet)" +"sammanslagningstabellhuvudet)" msgid "corrupted bitmap index file (too short to fit pseudo-merge table)" msgstr "" @@ -18273,13 +18533,6 @@ 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" - msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "trasig bitkarteuppslagstabell: trippelposition utanför indexet" @@ -18333,7 +18586,8 @@ msgstr "bitkarteresultat stämmer inte överens" #, c-format msgid "pseudo-merge index out of range (%<PRIu32> >= %<PRIuMAX>)" -msgstr "pseudosammanslaningsindex utenför intervallet (%<PRIu32> ≥ %<PRIuMAX>)" +msgstr "" +"pseudosammanslagningsindex utanför intervallet (%<PRIu32> ≥ %<PRIuMAX>)" #, c-format msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>" @@ -18428,7 +18682,7 @@ msgstr "offset före slutet av packindex för %s (trasigt index?)" #, c-format msgid "offset beyond end of pack index for %s (truncated index?)" -msgstr "offset borton slutet av packindex för %s (trunkerat index?)" +msgstr "offset bortom slutet av packindex för %s (trunkerat index?)" #, c-format msgid "malformed expiration date '%s'" @@ -18489,6 +18743,52 @@ msgstr "okänd flagga ”%c”" msgid "unknown non-ascii option in string: `%s'" msgstr "okänd icke-ascii-flagga i strängen: ”%s”" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " <%s>" + msgid "..." msgstr "..." @@ -18573,6 +18873,21 @@ msgstr "felaktigt booleskt miljövariabelvärde ”%s” för ”%s”" msgid "failed to parse %s" msgstr "misslyckades tolka %s" +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "misslyckades traversera löven i trädet %s: hittades inte" + +#, c-format +msgid "failed to find object %s" +msgstr "misslyckades hitta objektet %s" + +#, c-format +msgid "failed to find tag %s" +msgstr "misslyckades hitta taggen %s" + +msgid "failed to setup revision walk" +msgstr "misslyckades starta revisionstraversering" + #, c-format msgid "Could not make %s writable by group" msgstr "Kunde inte göra %s skrivbar för gruppen" @@ -18718,6 +19033,22 @@ msgstr "kontraktsfjärr kan inte börja med ”/”: %s" msgid "could not fetch %s from promisor remote" msgstr "kunde inte hämta %s från kontraktsfjärr" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "känd fjärr som heter ”%s” med med url:en ”%s” istället för ”%s”" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "okänt värde ”%s” för inställningen ”%s”" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "okänt värde ”%s” från fjärrinformation" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "godkänd kontraktsfjärr ”%s” hittades inte" + msgid "object-info: expected flush after arguments" msgstr "object-info: förväntade ”flush” efter argument" @@ -18804,7 +19135,7 @@ 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”-utdata: börjar inte med ”commit ”: ”%s”" #, c-format msgid "could not parse git header '%.*s'" @@ -18919,7 +19250,7 @@ msgstr "%s: öppning av indexfilen misslyckades" #, c-format msgid "%s: cannot stat the open index" -msgstr "%s: kan inte ta startus på det öppna indexet" +msgstr "%s: kan inte ta status på det öppna indexet" #, c-format msgid "%s: index file smaller than expected" @@ -19043,7 +19374,7 @@ msgstr "" " enrads, om inget incheckningsmeddelande angavs); använd\n" " -c <incheckning> för att skriva om meddelandet.\n" "u, update-ref <ref> = spåra en platshållare för <ref> att uppdatera\n" -" till denna position bland nya inchecknngar.\n" +" till denna position bland nya incheckningar.\n" " <ref> uppdateras i slutet av ombaseringen.\n" "\n" "Du kan byta ordning på raderna; de utförs uppifrån och ned.\n" @@ -19188,7 +19519,7 @@ msgstr "kan inte helt tolka %s=%s" #, c-format msgid "value expected %s=" -msgstr "vädre förväntades %s=" +msgstr "värde förväntades %s=" #, c-format msgid "positive value expected '%s' in %%(%s)" @@ -19218,6 +19549,10 @@ msgstr "positiv bredd förväntad med atomen %%(align)" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "förväntat format: %%(ahead-behind:<incheckning-igt>)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "förväntat format: %%(is-base:<incheckning-igt>)" + #, c-format msgid "malformed field name: %.*s" msgstr "felformat fältnamn: %.*s" @@ -19390,17 +19725,25 @@ msgstr "loggen för referensen %s slutade oväntat på %s" msgid "log for %s is empty" msgstr "loggen för %s är tom" -msgid "refusing to force and skip creation of reflog" -msgstr "vägrar att tvinga och hoppa över skapande av reflogg" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "vägrar uppdatera referens med trasigt namn ”%s”" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "vägrar uppdatera referenslogg för pseudoreferensen ”%s”" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "vägrar uppdatera pseudoreferensen ”%s”" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "vägrar uppdatera referenslogg med trasigt namn ”%s”" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "vägrar uppdatera referens med trasigt namn ”%s”" + +msgid "refusing to force and skip creation of reflog" +msgstr "vägrar att tvinga och hoppa över skapande av referenslogg" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "update_ref misslyckades för referensen ”%s”: %s" @@ -19450,6 +19793,17 @@ msgstr "" "kan inte läsa referensen ”%s”: förväntade symbolisk referens med målet ”%s”: " "men är en vanlig referens" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "kan inte läsa ref-fil ”%s”" + +#, c-format +msgid "cannot open directory %s" +msgstr "kunde inte öppna katalogen %s" + +msgid "Checking references consistency" +msgstr "Kontrollerar konsistens för referenser" + #, c-format msgid "refname is dangerous: %s" msgstr "refnamnet är farligt: %s" @@ -19520,6 +19874,14 @@ msgstr "referensnamnet %s är en symbolisk referens, kopiering stöds inte" msgid "invalid refspec '%s'" msgstr "felaktig referensspecifikation: ”%s”" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "mönstret ”%s” innehåller ingen ”*”" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "ersättningen ”%s” innehåller ingen ”*”" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "felaktig citering på värde för push-option: ”%s”" @@ -19638,6 +20000,28 @@ msgstr "remote-curl: försökte ta emot utan lokalt arkiv" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: okänt kommando ”%s” från git" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"läser fjärren från ”%s/%s”, som har nominerats för borttagning.\n" +"\n" +"Om du fortfarande använder ”remotes/”-katalogen rekommenderas du\n" +"migrera till konfigurationsbaserade fjärrar:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"Om du inte kan det, berätta för oss varför du fortfarande behöver\n" +"använda det på e-post till <git@vger.kernel.org>." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "konfigurerad kortform för fjärr kan inte börja med ”/”: %s" @@ -19648,6 +20032,10 @@ msgstr "mer än en receivepack angavs, använder den första" msgid "more than one uploadpack given, using the first" msgstr "mer än en uploadpack angavs, använder den första" +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "okänt värde ”%s” för followRemoteHEAD ignorerades" + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "okänt värde transfer.credentialsInUrl: ”%s”" @@ -19668,14 +20056,6 @@ msgstr "%s spårar vanligtvis %s, inte %s" msgid "%s tracks both %s and %s" 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 ”*”" - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "värdet ”%s” i mönstret innehåller ingen ”*”" - #, c-format msgid "src refspec %s does not match any" msgstr "käll-referensspecifikationen %s motsvarar ingen" @@ -19700,7 +20080,7 @@ msgid "" "\n" "Neither worked, so we gave up. You must fully qualify the ref." msgstr "" -"Målet du angav är inte ett komplett referensamn (dvs.,\n" +"Målet du angav är inte ett komplett referensnamn (dvs.,\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" @@ -19958,7 +20338,7 @@ msgstr "misslyckades hitta trädet för %s." #, c-format msgid "unsupported section for hidden refs: %s" -msgstr "sktionen för dolda referenser stöds ej: %s" +msgstr "sektionen för dolda referenser stöds ej: %s" msgid "--exclude-hidden= passed more than once" msgstr "--exclude-hidden= angavs mer än en gång" @@ -20077,12 +20457,15 @@ msgstr "hämta endast metadata för grenen som skall checkas ut" msgid "create repository within 'src' directory" msgstr "skapa arkiv inuti katalogen ”src”" +msgid "specify if tags should be fetched during clone" +msgstr "ange om taggar ska hämtas vid kloning" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <huvudgren>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enrollering>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enrollering>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20100,6 +20483,10 @@ msgstr "misslyckades hämta standardgren för ”%s”" msgid "could not configure remote in '%s'" msgstr "kunde inte ställa in fjärr i ”%s”" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "kunde inte inaktivera taggar i ”%s”" + #, c-format msgid "could not configure '%s'" msgstr "kunde inte ställa in ”%s”" @@ -20234,7 +20621,7 @@ msgid "" "not sending a push certificate since the receiving end does not support --" "signed push" msgstr "" -"sänder inte push-certifikat eftersom mottagarsidan inte stlder push med --" +"sänder inte push-certifikat eftersom mottagarsidan inte stöder push med --" "signed" msgid "the receiving end does not support --atomic push" @@ -20594,7 +20981,7 @@ msgstr "”%s” är inte ett giltigt referensnamn" #, c-format msgid "update-ref requires a fully qualified refname e.g. refs/heads/%s" -msgstr "update-ref kräver ett fullständigt referensnamn, t.ex refs/heads/%s" +msgstr "update-ref kräver ett fullständigt referensnamn, t.ex. refs/heads/%s" #, c-format msgid "'%s' does not accept merge commits" @@ -21161,6 +21548,10 @@ msgstr "kan inte gå tillbaka till arbetskatalogen (cwd)" msgid "failed to stat '%*s%s%s'" msgstr "misslyckades ta status på ”%*ss%s%s”" +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory ”%s” är inte absolut" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -21555,6 +21946,27 @@ 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 "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <flaggor> -- <revision-flaggor>" + +msgid "toggle inclusion of blob objects" +msgstr "växla om blob-objekt ska vara med eller inte" + +msgid "toggle inclusion of commit objects" +msgstr "växla om incheckningsobjekt ska vara med eller inte" + +msgid "toggle inclusion of tag objects" +msgstr "växla om taggobjekt ska vara med eller inte" + +msgid "toggle inclusion of tree objects" +msgstr "växla om trädobjekt ska vara med eller inte" + +msgid "toggle pruning of uninteresting paths" +msgstr "växla bortrensning av ointressanta sökvägar" + +msgid "read a pattern list over stdin" +msgstr "läs en mönsterlista från standard in" + #, c-format msgid "commit %s is not marked reachable" msgstr "incheckning %s är inte märkt nåbar" @@ -21562,6 +21974,9 @@ msgstr "incheckning %s är inte märkt nåbar" msgid "too many commits marked reachable" msgstr "för många incheckningar markerade nåbara" +msgid "could not determine MIDX preferred pack" +msgstr "kunde inte bestämma det föredragna MIDX-paketet" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<flaggor>]" @@ -21595,7 +22010,7 @@ msgstr "" "[<buntstorlek>]" msgid "name or pathname of unix domain socket" -msgstr "namn eller sövkäg till unixdomän-uttag" +msgstr "namn eller sökväg till unixdomän-uttag" msgid "named-pipe name" msgstr "namn på namngivet rör" @@ -21624,6 +22039,24 @@ msgstr "igenkänningstecken" msgid "command token to send to the server" msgstr "igenkänningstecken för kommando att sända till servern" +msgid "unit-test [<options>]" +msgstr "unit-test [<flaggor>]" + +msgid "immediately exit upon the first failed test" +msgstr "avsluta omedelbart vid det första misslyckade testet" + +msgid "suite[::test]" +msgstr "svit[::test]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "kör endast testsviten eller individuella testet <svit[::test]>" + +msgid "suite" +msgstr "svit" + +msgid "exclude test suite <suite>" +msgstr "uteslut testsviten <svit>" + #, c-format msgid "running trailer command '%s' failed" msgstr "misslyckades utföra släpradskommandot ”%s”" @@ -21679,10 +22112,10 @@ msgstr "kunde inte läsa referensen %s" #, c-format msgid "unknown response to connect: %s" -msgstr "okänt svar på ansluntning: %s" +msgstr "okänt svar på anslutning: %s" msgid "setting remote service path not supported by protocol" -msgstr "protkollet stöder inte att sätta sökväg till fjärrtjänst" +msgstr "protokollet 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" @@ -21695,7 +22128,7 @@ 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 motsvarande ”ok/error”-direktiv" #, c-format msgid "expected ok/error, helper said '%s'" @@ -22167,6 +22600,10 @@ msgstr "fel: " msgid "warning: " msgstr "varning: " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() misslyckades med felet ”%s” (%d)\n" + msgid "Fetching objects" msgstr "Hämtar objekt" @@ -22198,6 +22635,9 @@ msgstr ".git-filen är trasig" msgid ".git file incorrect" msgstr ".git-filen är felaktig" +msgid ".git file absolute/relative path mismatch" +msgstr "absolut/relativ sökväg för .git-fil stämmer inte överens" + msgid "not a valid path" msgstr "inte en giltig sökväg" @@ -22213,6 +22653,9 @@ msgstr "kan inte hitta arkivet; ”.git”-filen är trasig" msgid "gitdir unreadable" msgstr "gitdir är oläsbar" +msgid "gitdir absolute/relative path mismatch" +msgstr "absolut/relativ sökväg för git-katalog stämmer inte överens" + msgid "gitdir incorrect" msgstr "gitdir är felaktig" @@ -22247,6 +22690,13 @@ msgstr "kan inte slå av %s i ”%s”" msgid "failed to set extensions.worktreeConfig setting" msgstr "misslyckades ändra inställningen extensions.worktreeConfig" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"kunde inte uppgradera arkivformat till att stöda relativa arbetskataloger" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "misslyckades ändra inställningen extensions.relativeWorktrees" + #, c-format msgid "could not setenv '%s'" msgstr "kunde inte lagra miljövariabeln ”%s”" @@ -22745,7 +23195,7 @@ msgstr "Kan inte byta katalog till $cdup, toppnivån på arbetskatalogen" #, sh-format msgid "fatal: $program_name cannot be used without a working tree." -msgstr "ödesdigetrt: $program_name kan inte användas utan arbetskatalog." +msgstr "ödesdigert: $program_name kan inte användas utan arbetskatalog." msgid "Cannot rewrite branches: You have unstaged changes." msgstr "Kan inte skriva om grenar: Du har oköade ändringar." @@ -22793,6 +23243,9 @@ 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" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases och --translate-aliases är ömsesidigt uteslutande\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -22832,7 +23285,7 @@ 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 till ”/fil” eller ”|rör” stöds inte: %s\n" #, perl-format msgid "warning: sendmail line is not recognized: %s\n" @@ -22985,7 +23438,7 @@ msgstr "Nödvändig SMTP-server har inte angivits korrekt." #, perl-format msgid "Server does not support STARTTLS! %s" -msgstr "Servern stöder inte SMARTTLS! %s" +msgstr "Servern stöder inte STARTTLS! %s" #, perl-format msgid "STARTTLS failed! %s" @@ -23060,7 +23513,7 @@ msgid "cannot send message as 7bit" msgstr "kan inte sända brev som sjubitars" msgid "invalid transfer encoding" -msgstr "ogiltig överföringskondning" +msgstr "ogiltig överföringskodning" #, perl-format msgid "" diff --git a/po/tr.po b/po/tr.po index 61692d4b20a60e..4ed91cbd975c89 100644 --- a/po/tr.po +++ b/po/tr.po @@ -2,7 +2,7 @@ # Git Türkçe çevirileri # 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-2024 +# Emir SARI <emir_sari@icloud.com>, 2020-2025 # # ######################################################### # # Git Türkçe kavramlar dizini / Git Turkish Glossary # @@ -96,8 +96,8 @@ msgid "" msgstr "" "Project-Id-Version: Git Turkish Localization Project\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-19 13:59+0300\n" -"PO-Revision-Date: 2024-07-19 14:00+0300\n" +"POT-Creation-Date: 2025-03-11 15:01+0300\n" +"PO-Revision-Date: 2025-03-11 15: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" @@ -632,7 +632,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - bu parça için sonra karar ver, bir sonraki karar verilmemiş parçayı gör\n" @@ -642,8 +642,8 @@ msgstr "" "g - gidilecek bir parça seç\n" "/ - verilen düzenli ifade ile eşleşen bir parça ara\n" "s - geçerli parçayı daha ufak parçalara böl\n" -"e - geçerli parçayı el ile düzenle\n" -"p - geçerli parçalı yazdır\n" +"e - geçerli parçayı elle düzenle\n" +"p - geçerli parçalı yazdır, sayfalayıcı için 'P' kullan\n" "? - yardımı yazdır\n" #, c-format @@ -714,10 +714,10 @@ msgstr "Yalnızca ikili dosyalar değiştirildi." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Bu iletiyi \"git config advice.%s false\" ile devre dışı bırakın" +"Bu iletiyi \"git config set advice.%s false\" ile devre dışı bırakın" #, c-format msgid "%shint:%s%.*s%s\n" @@ -1314,6 +1314,15 @@ msgstr "ek olarak yamayı da uygula (--stat/--summary/--check ile kullan)" msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "3 yönlü birleştirme dene, başarısız olursa normal yamaya geri çekil" +msgid "for conflicts, use our version" +msgstr "çakışmalarda bizim sürümü kullan" + +msgid "for conflicts, use their version" +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 "build a temporary index based on embedded index information" msgstr "gömülü indeks bilgisini temel alan geçici bir indeks oluştur" @@ -1359,6 +1368,9 @@ msgstr "tüm dosya adlarının başına <kök> ekle" msgid "don't return error for empty patches" msgstr "boş yamalar için hata döndürme" +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs ve --union; --3way gerektiriyor" + #, c-format msgid "cannot stream blob %s" msgstr "%s ikili nesnesi akıtılamıyor" @@ -1429,6 +1441,10 @@ msgstr "geçerli bir nesne adı değil: %s" msgid "not a tree object: %s" msgstr "bir ağaç nesnesi değil: %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "%s ağaç nesnesi açılamadı" + #, c-format msgid "File not found: %s" msgstr "Dosya bulunamadı: %s" @@ -2392,6 +2408,18 @@ msgstr "git archive: Protokol hatası" msgid "git archive: expected a flush" msgstr "git archive: Floş bekleniyordu" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "aralıklı çıkış yüklenirken sorun" + +msgid "Minimum number of objects to request at a time" +msgstr "Bir kerede istenecek en çok nesne sayısı" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Eksik nesneleri geçerli aralıklı çıkışa sınırla" + msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2531,9 +2559,6 @@ msgstr "" "'git bisect terms' için geçersiz argüman %s.\n" "Desteklenen seçenekler: --term-good|--term-old ve --term-bad|--term-new." -msgid "revision walk setup failed\n" -msgstr "revizyonda gezinme ayarlaması başarısız oldu\n" - #, c-format msgid "could not open '%s' for appending" msgstr "'%s' iliştirme için açılamadı" @@ -3060,8 +3085,8 @@ msgid "HEAD not found below refs/heads!" msgstr "HEAD, refs/heads altında bulunamadı!" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" "--recurse-submodules ile dallanma, yalnızca submodule.propagateBranches " "etkinleştirilmişse kullanılabilir" @@ -3136,10 +3161,6 @@ msgstr "" msgid "git version:\n" msgstr "git sürümü:\n" -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() '%s' hatasını verip çıktı (%d)\n" - msgid "compiler info: " msgstr "derleyici bilgisi: " @@ -3508,9 +3529,14 @@ msgstr "git check-mailmap [<seçenekler>] <kişi>..." msgid "also read contacts from stdin" msgstr "stdin'den kişileri de oku" -#, c-format -msgid "unable to parse contact: %s" -msgstr "kişi ayrıştırılamadı: %s" +msgid "read additional mailmap entries from file" +msgstr "dosyadan ek mailmap girdilerini oku" + +msgid "blob" +msgstr "ikili nesne" + +msgid "read additional mailmap entries from blob" +msgstr "ikili nesneden ek mailmap girdilerini oku" msgid "no contacts specified" msgstr "kişi belirtilmedi" @@ -3857,6 +3883,10 @@ msgstr "dal değiştirilirken yollar kullanılamaz" msgid "'%s' cannot be used with switching branches" msgstr "dal değiştirilirken '%s' kullanılamaz" +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "çıkış yapmak için '%s' yollara gereksinim duyuyor" + #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s', '%s' ile birlikte kullanılamaz" @@ -3900,9 +3930,8 @@ msgstr "yeni henüz doğmamış dal" msgid "update ignored files (default)" msgstr "yok sayılan dosyaları güncelle (öntanımlı)" -msgid "do not check if another worktree is holding the given ref" -msgstr "" -"verilen başvuruyu başka bir çalışma ağacının tutup tutmadığını denetleme" +msgid "do not check if another worktree is using this branch" +msgstr "bu dalı başka bir çalışma ağacının kullanıp kullanmadığını denetleme" msgid "checkout our version for unmerged files" msgstr "birleştirilmeyen dosyalar için bizdeki sürümü çıkış yap" @@ -4137,8 +4166,91 @@ msgstr "" "clean.requireForce 'true' olarak ayarlı ve -f verilmedi; temizlik " "reddediliyor" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<seçenekler>] [--] <depo> [<dizin>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info: '%s' için alternatif eklenemedi: %s\n" + +#, c-format +msgid "failed to stat '%s'" +msgstr "'%s' dosyasının bilgileri alınamadı" + +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s var ve bir dizin değil" + +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "'%s' bir sembolik bağ; --local ile klonlama reddediliyor" + +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "yineleyici '%s' üzerinden çalıştırılamadı" + +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "'%s' sembolik bağı var, --local ile klonlama reddediliyor" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "'%s' bağlantısı kesilemedi" + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "sabit bağlantı, '%s' konumunda denetlenemiyor" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "sabit bağlantı, '%s' konumundaki kaynaktan farklı" + +#, c-format +msgid "failed to create link '%s'" +msgstr "'%s' bağı oluşturulamadı" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "dosya şuraya kopyalanamadı: '%s'" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "'%s' üzerinde yinelenemedi" + +#, c-format +msgid "done.\n" +msgstr "bitti.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Klonlama başarılı oldu; ancak çıkış yapılamadı.\n" +"Neyin çıkış yapılıp yapılmadığını 'git status' ile inceleyebilir\n" +"ve 'git restore --source=HEAD' ile yeniden deneyebilirsiniz.\n" + +msgid "remote did not send all necessary objects" +msgstr "uzak konum gereken tüm nesneleri göndermedi" + +#, c-format +msgid "unable to update %s" +msgstr "%s güncellenemiyor" + +msgid "failed to initialize sparse-checkout" +msgstr "sparse-checkout ilklendirilemedi" + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "uzak konum HEAD'i, var olmayan başvuruya başvuruyor; çıkış yapılamıyor" + +msgid "unable to checkout working tree" +msgstr "çalışma ağacı çıkış yapılamıyor" + +msgid "unable to write parameters to config file" +msgstr "parametreler yapılandırma dosyasına yazılamıyor" + +msgid "cannot repack to clean up" +msgstr "temizlik için yeniden paketlenemiyor" + +msgid "cannot unlink temporary alternates file" +msgstr "geçici alternatifler dosyasının bağlantısı kesilemiyor" msgid "don't clone shallow repository" msgstr "sığ depoyu klonlama" @@ -4191,6 +4303,9 @@ msgstr "üstkaynağı izlemek için 'origin' yerine <ad> kullan" msgid "checkout <branch> instead of the remote's HEAD" msgstr "uzak konumun HEAD'i yerine <dal>'ı çıkış yap" +msgid "clone single revision <rev> and check out" +msgstr "tek revizyonlu <rev>'i klonla ve çıkış yap" + msgid "path to git-upload-pack on the remote" msgstr "uzak konumdaki git-upload-pack'e olan yol" @@ -4203,17 +4318,17 @@ msgstr "verilen derinlikte sığ bir depo oluştur" msgid "create a shallow clone since a specific time" msgstr "verilen zamandan sonrasını içeren bir sığ depo oluştur" -msgid "revision" -msgstr "revizyon" +msgid "ref" +msgstr "başvuru" -msgid "deepen history of shallow clone, excluding rev" -msgstr "revizyonu hariç tutarak sığ klonun geçmişini derinleştir" +msgid "deepen history of shallow clone, excluding ref" +msgstr "başvuru hariç tutarak sığ klonun geçmişini derinleştir" msgid "clone only one branch, HEAD or --branch" msgstr "yalnızca bir dal klonla, HEAD veya --branch" -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "etiket klonlama ve sonraki getirmeler de onları izlemesin" +msgid "clone tags, and make later fetches not to follow them" +msgstr "etiketleri klonla ve sonraki getirmelerin onları izlememesini sağla" msgid "any cloned submodules will be shallow" msgstr "klonlanan altmodüller sığ olacak" @@ -4256,95 +4371,8 @@ msgstr "uri" msgid "a URI for downloading bundles before fetching from origin remote" msgstr "uzak konum kökeninden getirmeden önce demetleri indirmek için bir URI" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: '%s' için alternatif eklenemedi: %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "'%s' dosyasının bilgileri alınamadı" - -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s var ve bir dizin değil" - -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "'%s' bir sembolik bağ; --local ile klonlama reddediliyor" - -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "yineleyici '%s' üzerinden çalıştırılamadı" - -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "'%s' sembolik bağı var, --local ile klonlama reddediliyor" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "'%s' bağlantısı kesilemedi" - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "sabit bağlantı, '%s' konumunda denetlenemiyor" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "sabit bağlantı, '%s' konumundaki kaynaktan farklı" - -#, c-format -msgid "failed to create link '%s'" -msgstr "'%s' bağı oluşturulamadı" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "dosya şuraya kopyalanamadı: '%s'" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "'%s' üzerinde yinelenemedi" - -#, c-format -msgid "done.\n" -msgstr "bitti.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Klonlama başarılı oldu; ancak çıkış yapılamadı.\n" -"Neyin çıkış yapılıp yapılmadığını 'git status' ile inceleyebilir\n" -"ve 'git restore --source=HEAD' ile yeniden deneyebilirsiniz.\n" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Klonlanacak %s uzak dal bulunamadı." - -msgid "remote did not send all necessary objects" -msgstr "uzak konum gereken tüm nesneleri göndermedi" - -#, c-format -msgid "unable to update %s" -msgstr "%s güncellenemiyor" - -msgid "failed to initialize sparse-checkout" -msgstr "sparse-checkout ilklendirilemedi" - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "uzak konum HEAD'i, var olmayan başvuruya başvuruyor; çıkış yapılamıyor" - -msgid "unable to checkout working tree" -msgstr "çalışma ağacı çıkış yapılamıyor" - -msgid "unable to write parameters to config file" -msgstr "parametreler yapılandırma dosyasına yazılamıyor" - -msgid "cannot repack to clean up" -msgstr "temizlik için yeniden paketlenemiyor" - -msgid "cannot unlink temporary alternates file" -msgstr "geçici alternatifler dosyasının bağlantısı kesilemiyor" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<seçenekler>] [--] <depo> [<dizin>]" msgid "Too many arguments." msgstr "Çok fazla argüman." @@ -4444,6 +4472,10 @@ msgstr "uzak konum taşıması hata bildirdi" msgid "Remote branch %s not found in upstream %s" msgstr "%s uzak dalı %s üstkaynağında bulunamadı" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "%s uzak revizyonu, %s üstkaynağında bulunamadı" + msgid "You appear to have cloned an empty repository." msgstr "Boş bir depoyu klonlamış görünüyorsunuz." @@ -4620,9 +4652,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree: okunamadı" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4630,15 +4662,15 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<kip>] [--amend]\n" -" [--dry-run] [(-c | -C | --squash) <işleme> | --fixup [(amend|" -"reword):]<işleme>)]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<kip>]] [--amend]\n" +" [--dry-run] [(-c | -C | --squash) <işleme> |\n" +" --fixup [(amend|reword):]<işleme>]\n" " [-F <dosya> | -m <ileti>] [--reset-author] [--allow-empty]\n" -" [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" +" [--allow-empty-message] [--no-verify] [-e] [--author=<yazar>]\n" " [--date=<tarih>] [--cleanup=<kip>] [--[no-]status]\n" " [-i | -o] [--pathspec-from-file=<dosya> [--pathspec-file-nul]]\n" " [(--trailer <jeton>[(=|:)<değer>])...] [-S[<anahtar-kimliği>]]\n" -" [--] [<yol-blrtç>...]" +" [--] [<yol-belirteci>...]" msgid "git status [<options>] [--] [<pathspec>...]" msgstr "git status [<seçenekler>] [--] [<yol-blrtç>...]" @@ -5131,12 +5163,10 @@ msgstr "" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" -"git config get [<dosya-seçeneği>] [<görüntüleme-seçeneği>] [--includes] [--" -"all] [--regexp=<düzenli-ifade>] [--value=<değer>] [--fixed-value] [--" -"default=<öntanımlı>] <ad>" +"git config get [<dosya-sçnği>] [<görüntü-sçnği>] [--includes] [--all] [--" +"regexp] [--value=<değer>] [--fixed-value] [--default=<öntanımlı>] <ad>" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5147,10 +5177,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" "git config unset [<dosya-seçeneği>] [--all] [--value=<değer>] [--fixed-" -"value] <ad> <değer>" +"value] <ad>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [<dosya-seçeneği>] <eski-ad> <yeni-ad>" @@ -5164,6 +5194,15 @@ msgstr "git config edit [<dosya-seçeneği>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "git config [<dosya-seçeneği>] --get-colorbool <ad> [<stdout-tty>]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<dosya-seçeneği>] [<görüntüleme-seçeneği>] [--includes] [--" +"all] [--regexp=<düzenli-ifade>] [--value=<değer>] [--fixed-value] [--" +"default=<öntanımlı>] <ad>" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5576,12 +5615,8 @@ msgid "traversed %lu commits\n" msgstr "%lu işleme katedildi\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"%i etiketten fazla etiket bulundu; en son %i listelendi\n" -"şu konumda arama bırakıldı: %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "%i etiket bulundu; arama şurada bitirildi: %s\n" #, c-format msgid "describe %s\n" @@ -5966,8 +6001,8 @@ msgstr "" "bu denetlemeden kaçınabilirsiniz.\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s tüm gerekli nesneleri göndermedi\n" +msgid "%s did not send all necessary objects" +msgstr "%s tüm gerekli nesneleri göndermedi" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -6004,8 +6039,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "\"%s\" seçeneği \"%s\" değeri %s için geçerli değil" #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "\"%s\" seçeneği %s için yok sayılıyor\n" +msgid "option \"%s\" is ignored for %s" +msgstr "\"%s\" seçeneği %s için yok sayılıyor" #, c-format msgid "%s is not a valid object" @@ -6015,6 +6050,21 @@ msgstr "%s geçerli bir nesne değil" msgid "the object %s does not exist" msgstr "%s diye bir nesne yok" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Değişikliği izlemek için 'git remote set-head %s %s' yapın veya\n" +"'remote.%s.followRemoteHEAD' yapılandırma seçeneğini başka bir\n" +"değere ayarlayın (bu iletiyi görmek istemiyorsanız). Özellikle\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"komutunu çalıştırmak, uyarıyı HEAD'e veya başka bir şeye uzaktan\n" +"değişiklik olana dek devre dışı bırakır." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "birden çok dal algılandı, --set-upstream ile uyumsuz" @@ -6153,6 +6203,9 @@ msgstr "ilgili başvuru" msgid "specify fetch refmap" msgstr "getirme ile ilgili başvuruları belirt" +msgid "revision" +msgstr "revizyon" + msgid "report that we have only objects reachable from this object" msgstr "yalnızca bu nesneden ulaşılabilir nesnelerimiz olduğunu bildir" @@ -6207,8 +6260,8 @@ msgid "protocol does not support --negotiate-only, exiting" msgstr "protokol, --negotiate-only desteklemediğinden çıkılıyor" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" "--filter, yalnızca extensions.partialclone içinde yapılandırılmış uzak konum " "ile kullanılabilir" @@ -6678,12 +6731,18 @@ msgstr "biraz daha titiz ol (artırılmış işleyiş süresi)" msgid "enable auto-gc mode" msgstr "auto-gc kipini etkinleştir" +msgid "perform garbage collection in the background" +msgstr "çöp toplamayı arka planda gerçekleştir" + msgid "force running gc even if there may be another gc running" msgstr "başka bir gc çalışıyor olsa bile zorla gc çalıştır" msgid "repack all other packs except the largest pack" msgstr "en büyük paket dışındaki diğer tüm paketleri yeniden paketle" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "budanan nesneler içeren paketi depolamak için paket öneki" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "gc.logExpiry değeri %s ayrıştırılamadı" @@ -6773,6 +6832,9 @@ msgstr "'%s' görevi birden çok kez seçilemez" msgid "run tasks based on the state of the repository" msgstr "görevleri deponun durumuna göre çalıştır" +msgid "perform maintenance in the background" +msgstr "bakımı arka planda gerçekleştir" + msgid "frequency" msgstr "sıklık" @@ -6867,8 +6929,27 @@ msgstr "ne systemd zamanlayıcıları ne de crontab kullanılabiliyor" msgid "%s scheduler is not available" msgstr "%s planlayıcısı kullanılamıyor" -msgid "another process is scheduling background maintenance" -msgstr "başka bir işlem arka plan bakımı zamanını planlıyor" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"'%s.lock' oluşturulamıyor: %s.\n" +"\n" +"Bu depoda başka bir planlı git-maintenance(1) süreci çalışıyor gibi\n" +"görünüyor. Lütfen başka bir bakım sürecinin çalışmıyor olduğundan emin\n" +"olun ve yeniden deneyin. Eğer hâlâ başarısız oluyorsa bir git-" +"maintenance(1)\n" +"süreci bu depo içinde daha önceden çakılmış olabilir: Sürdürmek için " +"dosyayı\n" +"elle kaldırın." + +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "planlı arka plan bakımı için kilit alınamıyor" msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=<görev-planlayıcı>]" @@ -7441,8 +7522,26 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "zincir uzunluğu = %d: %lu nesne" msgstr[1] "zincir uzunluğu = %d: %lu nesne" +msgid "could not start pack-objects to repack local links" +msgstr "yerel bağlantıları yeniden paketleme için pack-objects başlatılamadı" + +msgid "failed to feed local object to pack-objects" +msgstr "yerel nesne pack-objects'e beslenemedi" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: Onaltılı tam nesne kimliği satırları yalnızca pack-objects'ten " +"bekleniyor." + +msgid "could not finish pack-objects to repack local links" +msgstr "yerel bağlantıları yeniden paketleme için pack-objects bitirilemedi" + msgid "Cannot come back to cwd" -msgstr "Şu anki çalışma dizinine geri gelinemiyor" +msgstr "Geçerli çalışma dizinine geri gelinemiyor" + +#, c-format +msgid "bad --pack_header: %s" +msgstr "hatalı --pack_header: %s" #, c-format msgid "bad %s" @@ -7452,6 +7551,9 @@ msgstr "hatalı %s" msgid "unknown hash algorithm '%s'" msgstr "bilinmeyen sağlama algoritması '%s'" +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor bir paket adıyla kullanılamaz" + msgid "--stdin requires a git repository" msgstr "--stdin bir git dizini gerektirir" @@ -7635,9 +7737,6 @@ msgstr "-L<erim>:<dosya>, yol belirteci ile kullanılamıyor" msgid "Final output: %d %s\n" msgstr "Son çıktı: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "geçici nesne dizini oluşturulamıyor" - #, c-format msgid "git show %s: bad file" msgstr "git show %s: hatalı dosya" @@ -8199,15 +8298,6 @@ msgstr "diff3 tabanlı birleştirme kullan" msgid "use a zealous diff3 based merge" msgstr "gayretli bir diff3 tabanlı birleştirme kullan" -msgid "for conflicts, use our version" -msgstr "çakışmalarda bizim sürümü kullan" - -msgid "for conflicts, use their version" -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>" @@ -8312,10 +8402,6 @@ msgstr "bilinmeyen strateji seçeneği: -X%s" msgid "malformed input line: '%s'." msgstr "hatalı oluşturulmuş girdi satırı: '%s'." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "birleştirme sürdürülemiyor; %d için temiz olmayan sonuçlar alındı" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<seçenekler>] [<işleme>...]" @@ -8670,6 +8756,9 @@ msgstr "bir çoklu paket biteşlemi hesaplanırken yeniden kullanılacak paket" msgid "write multi-pack bitmap" msgstr "çoklu paket biteşlemi yaz" +msgid "write a new incremental MIDX" +msgstr "yeni bir artımlı MIDX yaz" + msgid "write multi-pack index containing only given indexes" msgstr "yalnızca verilen indeksleri içeren çoklu paket indekslerini yaz" @@ -8804,11 +8893,11 @@ msgstr "git notes [--ref <not-bşvr>] [list [<nesne>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" -"git notes [--ref <not-bşv>] add [-f] [--allow-empty] [--[no-]separator|--" -"separator=<paragraf-sonu>] [--[no-]stripspace] [-m <ilet> | -F <dosya> | (-c " -"| -C) <nesne>] [<nesne>]" +"git notes [--ref <notlar-baş>] add [-f] [--allow-empty] [--[no-]separator|--" +"separator=<paragraf-kes>] [--[no-]stripspace] [-m <ileti> | -F <dosya> | (-c " +"| -C) <nesne>] [<nesne>] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "git notes [--ref <not-bşvr>] copy [-f] <nesneden> <nesneye>" @@ -8816,11 +8905,11 @@ msgstr "git notes [--ref <not-bşvr>] copy [-f] <nesneden> <nesneye>" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" -"git notes [--ref <not-bşv>] append [--allow-empty] [--[no-]separator|--" -"separator=<paragraf-sonu>] [--[no-]stripspace] [-m <ileti> | -F <dosya> | (-" -"c | -C) <nesne>] [<nesne>]" +"git notes [--ref <notlar-baş>] append [--allow-empty] [--[no-]separator|--" +"separator=<paragraf-kes>] [--[no-]stripspace] [-m <ileti> | -F <dosya> | (-c " +"| -C) <nesne>] [<nesne>] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref <not-bşvr>] edit [--allow-empty] [<nesne>]" @@ -8938,6 +9027,9 @@ msgstr "not içeriği bir dosyada" msgid "reuse and edit specified note object" msgstr "belirtilen not nesnesini düzenle ve yeniden kullan" +msgid "edit note message in editor" +msgstr "not iletisini düzenleyicide aç" + msgid "reuse specified note object" msgstr "belirtilen not nesnesini yeniden kullan" @@ -9123,6 +9215,13 @@ msgstr "" "git pack-objects [<sçnklr>] <temel-ad> [< <bşvru-listesi> | < <nesne-" "listesi>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "geçersiz --name-hash-version seçeneği: %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "şu anda --write-bitmap-index, --name-hash-version=1 gerektiriyor" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9434,6 +9533,9 @@ msgstr "eksik nesneler için işlem" msgid "do not pack objects in promisor packfiles" msgstr "nesneleri vaatçi paket dosyalarıyla paketleme" +msgid "implies --missing=allow-any" +msgstr "--missing=allow-any ima eder" + msgid "respect islands during delta compression" msgstr "delta sıkıştırması sırasında adalara uy" @@ -9445,6 +9547,9 @@ msgstr "" "bu protokol ile herhangi bir yapılandırılmış uploadpack.blobpackfileuri " "ögesini hariç tut" +msgid "use the specified name-hash function to group similar objects" +msgstr "benzer nesneleri gruplamak için belirtilen name-hash işlevini kullan" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "delta zincir derinliği %d çok derin, %d zorlanıyor" @@ -10675,8 +10780,11 @@ msgstr "silmek için bir başvuru günlüğü belirtilmedi" msgid "invalid ref format: %s" msgstr "geçersiz başvuru biçimi: %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<biçim> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<biçim> [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "dönüştürülecek başvuru biçimini belirt" @@ -10684,6 +10792,9 @@ msgstr "dönüştürülecek başvuru biçimini belirt" msgid "perform a non-destructive dry-run" msgstr "yıkıcı olmayan bir deneme gerçekleştir" +msgid "drop reflogs entirely during the migration" +msgstr "göç sırasında başvuru günlüklerini tümüyle bırak" + msgid "missing --ref-format=<format>" msgstr "--ref-format=<biçim> eksik" @@ -10691,6 +10802,12 @@ msgstr "--ref-format=<biçim> eksik" msgid "repository already uses '%s' format" msgstr "depo halihazırda '%s' biçimini kullanıyor" +msgid "enable strict checking" +msgstr "kesin denetlemeyi etkinleştir" + +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' bir argüman almıyor" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -11026,6 +11143,31 @@ msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " 'git push'%s için yapılandırılan yerel başvuru:" msgstr[1] " 'git push'%s için yapılandırılan yerel başvurular:" +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "'%s/HEAD' değiştirilmedi ve '%s' konumuna işaret ediyor\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "'%s/HEAD', '%s' konumundan '%s' konumuna değiştirildi\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "'%s/HEAD' şimdi oluşturuldu ve '%s' konumuna işaret ediyor\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "" +"'%s/HEAD', '%s' konumunda ayrıldı ve artık '%s' konumuna işaret ediyor\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"'%s/HEAD', uzak dal olmayan '%s' konumuna işaret ediyordu; ancak şimdi '%s' " +"konumuna işaret ediyor\n" + msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "refs/remotes/<ad>/HEAD'i uzak konuma göre ayarla" @@ -11047,7 +11189,7 @@ msgid "Not a valid ref: %s" msgstr "Geçerli bir başvuru değil: %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "%s ayarlanamadı" #, c-format @@ -11119,8 +11261,14 @@ msgstr "Tüm itme olmayan URL'ler silinmeyecek" msgid "be verbose; must be placed before a subcommand" msgstr "ayrıntılı anlat; bir altkomuttan önce yerleştirilmelidir" -msgid "git repack [<options>]" -msgstr "git repack [<seçenekler>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<paket-adı>]\n" +"[--write-midx] [--name-hash-version=<n>]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11194,6 +11342,11 @@ msgstr "'git-pack-objects'e --no-reuse-delta geçir" msgid "pass --no-reuse-object to git-pack-objects" msgstr "'git-pack-objects'e --no-reuse-object geçir" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"benzer nesneleri yola göre gruplamada kullanılacak name-hash sürümünü belirt" + msgid "do not run git-update-server-info" msgstr "'git-update-server-info' çalıştırma" @@ -11242,9 +11395,6 @@ msgstr "<N> faktörlü bir geometrik ilerleme bul" msgid "write a multi-pack index of the resulting packs" 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" @@ -11461,9 +11611,6 @@ 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ı" @@ -12121,11 +12268,11 @@ msgstr "başvuru yok" msgid "failed to look up reference" msgstr "başvuru bakılamadı" -msgid "only show tags (can be combined with branches)" -msgstr "yalnızca etiketleri göster (dallarla birlikte kullanılabilir)" +msgid "only show tags (can be combined with --branches)" +msgstr "yalnızca etiketleri göster (--branches ile birlikte kullanılabilir)" -msgid "only show branches (can be combined with tags)" -msgstr "yalnızca dalları göster (etiketlerle birlikte kullanılabilir)" +msgid "only show branches (can be combined with --tags)" +msgstr "yalnızca dalları göster (--tags ile birlikte kullanılabilir)" msgid "check for reference existence without resolving" msgstr "çözmeden başvuru varlığını denetle" @@ -12177,6 +12324,10 @@ msgstr "'%s' dizini kaldırılamadı" msgid "failed to create directory for sparse-checkout file" msgstr "aralıklı çıkış dosyası için dizin oluşturulamadı" +#, c-format +msgid "unable to fdopen %s" +msgstr "%s fdopen yapılamıyor" + msgid "failed to initialize worktree config" msgstr "çalışma ağacı yapılandırması ilklendirilemedi" @@ -12625,8 +12776,8 @@ msgid "couldn't hash object from '%s'" msgstr "'%s' üzerinden nesne sağlaması yapılamadı" #, c-format -msgid "unexpected mode %o\n" -msgstr "beklenmedik kip %o\n" +msgid "unexpected mode %o" +msgstr "beklenmedik kip %o" msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "altmodül HEAD'i içindeki işleme ile indekstekini karşılaştırmak için" @@ -13744,6 +13895,9 @@ msgstr "izleme kipini ayarla (bkz: git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "yeni dalın adını bir uzak izleme dalıyla eşleştirmeyi dene" +msgid "use relative paths for worktrees" +msgstr "çalışma ağaçları için göreceli yollar kullan" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "'%s', '%s' ve '%s' seçenekleri birlikte kullanılamaz" @@ -14015,6 +14169,25 @@ msgstr "'%s' oluşturulamıyor" msgid "index-pack died" msgstr "index-pack sonlandı" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "'%s' dizini indekste var; ancak aralıklı değil" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "hasarlı cache-tree'de indekste olmayan girdiler var" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s, 0x%x bayraklı olarak cache-tree'de olmamalı" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "hatalı alt ağaç '%.*s'" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "%.*s yolu için olan cache-tree eşleşmiyor. %s bekleniyordu, %s alındı" + msgid "terminating chunk id appears earlier than expected" msgstr "iri parça numarası sonlandırması beklenenden önce ortaya çıkıyor" @@ -14059,6 +14232,9 @@ msgstr "Git'e bir GNU Arch deposu içe aktar" msgid "Create an archive of files from a named tree" msgstr "Ad verilmiş ağaçtan bir dosyalar arşivi oluştur" +msgid "Download missing objects in a partial clone" +msgstr "Eksik nesneleri kısımsal bir klonda indir" + msgid "Use binary search to find the commit that introduced a bug" msgstr "Hatalara neden olan işlemeyi bulmada ikili arama kullan" @@ -14794,8 +14970,8 @@ msgid "" "attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " "(%d) is not supported" msgstr "" -"bir commit-graph yazılmaya çalışılıyor; ancak 'commitGraph." -"changedPathsVersion' (%d) desteklenmiyor" +"bir commit-graph yazılmaya çalışılıyor; ancak " +"'commitGraph.changedPathsVersion' (%d) desteklenmiyor" msgid "too many commits to write graph" msgstr "grafik yazımı için pek fazla işleme" @@ -14874,7 +15050,7 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "<GIT_DIR>/info/grafts desteği artık kullanılmamalı\n" "ve ileriki bir Git sürümünde kaldırılacak.\n" @@ -14882,7 +15058,7 @@ msgstr "" "Aşıları değiştirme başvurularına dönüştürmek için\n" "lütfen \"git replace --convert-graft-file\" kullanın.\n" "\n" -"\"git config advice.graftFileDeprecated false\"\n" +"\"git config set advice.graftFileDeprecated false\"\n" "kullanarak bu iletiyi kapatabilirsiniz" #, c-format @@ -15141,8 +15317,8 @@ msgid "" "remote URLs cannot be configured in file directly or indirectly included by " "includeIf.hasconfig:remote.*.url" msgstr "" -"uzak URL'ler dosya içinde doğrudan veya başka türlü includeIf.hasconfig:" -"remote.*.url kullanarak yapılandırılamaz" +"uzak URL'ler dosya içinde doğrudan veya başka türlü " +"includeIf.hasconfig:remote.*.url kullanarak yapılandırılamaz" #, c-format msgid "invalid config format: %s" @@ -15698,6 +15874,19 @@ msgstr "url'nin şeması yok: %s" msgid "credential url cannot be parsed: %s" msgstr "yetki url'si ayrıştırılamıyor: %s" +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "geçersiz zaman aşımı '%s', negatif olmayan bir tamsayı bekleniyor" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "" +"geçersiz ilklendirme zaman aşımı '%s', negatif olmayan bir tamsayı bekleniyor" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "geçersiz en çok bağlantı '%s', bir tamsayı bekleniyor" + msgid "in the future" msgstr "gelecekte" @@ -15957,6 +16146,12 @@ msgstr "%s için geçersiz argüman" msgid "invalid regex given to -I: '%s'" msgstr "-I'ya geçersiz düzenli ifade verildi: '%s'" +msgid "-G requires a non-empty argument" +msgstr "-G, boş olmayan bir argüman gerektiriyor" + +msgid "-S requires a non-empty argument" +msgstr "-S, boş olmayan bir argüman gerektiriyor" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "--submodule seçenek parametresi ayrıştırılamadı: '%s'" @@ -16404,6 +16599,20 @@ msgstr "hatalı git ad alanı yolu \"%s\"" msgid "too many args to run %s" msgstr "%s çalıştırmak için pek fazla argüman" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"İşleme grafiğinde bulunan; ancak nesne veritabanında bulunmayan %s ögesini " +"getirmeyi deniyorsunuz.\n" +"Bu, büyük olasılıkla depo hasarından dolayı oluyor.\n" +"Bu depo hasarını eksik nesneyi yeniden getirerek onarmayı düşünüyorsanız " +"eksik nesneyle birlikte 'git fetch --refetch' kullanmayı deneyin." + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: sığ bir liste bekleniyordu" @@ -16989,10 +17198,10 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" "'%s' kancası yok sayıldı; çünkü bir yürütülebilir olarak ayarlanmamış.\n" -"Bu uyarıyı 'git config advice.ignoredHook false' ile kapatabilirsiniz." +"Bu uyarıyı 'git config set advice.ignoredHook false' ile kapatabilirsiniz." msgid "not a git repository" msgstr "bir git deposu değil" @@ -17008,15 +17217,9 @@ msgstr "http.postBuffer için negatif değer; %d olarak varsayılıyor" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Delegasyon denetimi cURL < 7.22.0 tarafından desteklenmiyor" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "Ortak anahtar iğnelemesi cURL < 7.39.0 tarafından desteklenmiyor" - msgid "Unknown value for http.proactiveauth" msgstr "http.proactiveauth için bilinmeyen değer" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE cURL < 7.44.0 tarafından desteklenmiyor" - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "Desteklenmeyen SSL arka ucu '%s'. Desteklenen SSL arka uçları:" @@ -17177,13 +17380,16 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "'%s.lock' oluşturulamıyor: %s" +msgid "unable to create temporary object directory" +msgstr "geçici nesne dizini oluşturulamıyor" + #, c-format msgid "could not write loose object index %s" msgstr "gevşek nesne indeksi %s yazılamadı" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "gevşek nesne indeksi %s yazımı başarısız\n" +msgid "failed to write loose object index %s" +msgstr "gevşek nesne indeksi %s yazılamadı" #, c-format msgid "unexpected line: '%s'" @@ -17199,6 +17405,10 @@ msgstr "alıntılanmış CRLF algılandı" msgid "unable to format message: %s" msgstr "ileti biçimlendirilemiyor: %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "geçersiz imleyici boyutu '%s', bir tamsayı bekleniyor" + #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "%s altmodülü birleştirilemedi (çıkış yapılmadı)" @@ -17739,6 +17949,17 @@ msgstr "paket yüklenemedi" msgid "could not open index for %s" msgstr "%s için indeks açılamadı" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "'%s', '%s' ile bağlantılanamıyor" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "multi-pack-index %s konumunda temizlenemedi" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "biteşlem ile artımlı MIDX yazılamıyor" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "var olan multi-pack-index yok sayılıyor; sağlama toplamı uyumsuzluğu" @@ -17767,18 +17988,34 @@ msgstr "indekslenecek paket dosyası yok." msgid "refusing to write multi-pack .bitmap without any objects" msgstr "bir nesne olmadan multi-pack .bitmap yazımı reddediliyor" +msgid "unable to create temporary MIDX layer" +msgstr "geçici MIDX katmanı oluşturulamıyor" + msgid "could not write multi-pack bitmap" msgstr "çoklu paket biteşlem yazılamadı" +msgid "unable to open multi-pack-index chain file" +msgstr "multi-pack-index zincir dosyası açılamıyor" + +msgid "unable to rename new multi-pack-index layer" +msgstr "yeni multi-pack-index katmanı yeniden adlandırılamıyor" + msgid "could not write multi-pack-index" msgstr "multi-pack-index yazılamadı" +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "" +"artımlı bir multi-pack-index ögesinden paketlerin süresi doldurulamıyor" + msgid "Counting referenced objects" msgstr "Başvurulmuş nesneler sayılıyor" msgid "Finding and deleting unreferenced packfiles" msgstr "Başvurulmamış paket dosyaları bulunuyor ve siliniyor" +msgid "cannot repack an incremental multi-pack-index" +msgstr "artımlı bir multi-pack-index yeniden paketlenemiyor" + msgid "could not start pack-objects" msgstr "pack-objects başlatılamadı" @@ -17836,6 +18073,27 @@ msgstr "multi-pack-index pack-name iri parçası pek kısa" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "multi-pack-index paket adlarının sırasız: '%s' şundan önce: '%s'" +msgid "multi-pack-index chain file too small" +msgstr "multi-pack-index zincir dosyası pek küçük" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "temel MIDX içindeki paket sayısı pek yüksek: %<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "temel MIDX içindeki nesne sayısı pek yüksek: %<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "geçersiz multi-pack-index zinciri: '%s' bir sağlama değil" + +msgid "unable to find all multi-pack index files" +msgstr "tüm multi-pack-index dosyaları bulunamıyor" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "geçersiz MIDX nesnesi konumu, MIDX büyük olasılıkla hasarlı" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "hatalı pack-int-id: %u (%u toplam paket)" @@ -17853,10 +18111,6 @@ 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 clear multi-pack-index at %s" -msgstr "multi-pack-index %s konumunda temizlenemedi" - msgid "multi-pack-index file exists, but failed to parse" msgstr "multi-pack-index dosyası var; ancak ayrıştırılamadı" @@ -18064,10 +18318,22 @@ msgstr "paketlenmiş nesne %s (%s içinde depolanıyor) hasarlı" msgid "missing mapping of %s to %s" msgstr "%s ögesinin %s ögesine eksik eşlemlemesi" +#, c-format +msgid "unable to open %s" +msgstr "%s açılamıyor" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "'%s' ve '%s' dosyalarının içeriği farklı" + #, c-format msgid "unable to write file %s" msgstr "%s dosyası yazılamıyor" +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "sürekli olarak kaybolan %s dosyası yazılamıyor" + #, c-format msgid "unable to set permission to '%s'" msgstr "'%s' ögesine izin ayarlanamıyor" @@ -18148,10 +18414,6 @@ msgstr "%s: desteklenmeyen dosya türü" msgid "%s is not a valid '%s' object" msgstr "%s geçerli bir '%s' nesnesi değil" -#, c-format -msgid "unable to open %s" -msgstr "%s açılamıyor" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "%s için sağlama uyuşmazlığı (%s bekleniyordu)" @@ -18253,7 +18515,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Git normalde hiçbir zaman 40 onaltılı karakterlerle biten bir başvuru\n" "oluşturmaz; çünkü 40 onaltılı bir başvuru, onu belirlediğiniz zaman yok\n" @@ -18264,7 +18526,7 @@ msgstr "" "komutunda \"$br\" bir şekilde boş kalmış ve 40 onaltılı bir başvuru\n" "oluşturulmuş. Lütfen bu başvuruları inceleyin ve gerekirse silin. Bu " "iletiyi\n" -"kapatmak için \"git config advice.objectNameWarning\" yapın" +"kapatmak için \"git config set advice.objectNameWarning\" yapın" #, c-format msgid "log for '%.*s' only goes back to %s" @@ -18425,13 +18687,6 @@ 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 "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" @@ -18641,6 +18896,52 @@ msgstr "bilinmeyen anahtar '%c'" msgid "unknown non-ascii option in string: `%s'" msgstr "dizi içinde bilinmeyen ascii dışı seçenek: '%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " <%s>" + msgid "..." msgstr "..." @@ -18726,6 +19027,21 @@ msgstr "hatalı Boole çevre değeri '%s', '%s' için" msgid "failed to parse %s" msgstr "%s ayrıştırılamadı" +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "%s ağacının alt ögeleri yürütülemedi: bulunamadı" + +#, c-format +msgid "failed to find object %s" +msgstr "%s nesnesi bulunamadı" + +#, c-format +msgid "failed to find tag %s" +msgstr "%s etiketi bulunamadı" + +msgid "failed to setup revision walk" +msgstr "revizyon yürüyüşü ayarlanamadı" + #, c-format msgid "Could not make %s writable by group" msgstr "%s grup ile yazılabilir yapılamadı" @@ -18869,6 +19185,22 @@ msgstr "vaatçi uzak konum adı '/' ile başlayamaz: %s" msgid "could not fetch %s from promisor remote" msgstr "vaatçi uzak konumundan %s getirilemedi" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "bilinen uzak konum adı '%s'; ancak url'si '%s'; '%s' olmalı" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "'%s' yapılandırma seçeneği için bilinmeyen değer: '%s'" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "uzak bilgiden bilinmeyen öge '%s'" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "kabul edilmiş vaatçi uzak konum '%s' bulunamadı" + msgid "object-info: expected flush after arguments" msgstr "object-info: argümanlardan sonra floş bekleniyordu" @@ -19257,8 +19589,8 @@ msgid "" msgstr "" "Bu iletiden kaçınmak için, bir işlemeyi kaldırırken açıkça \"drop\" " "kullanın.\n" -"Uyarıların düzeyini değiştirmek için 'git config rebase." -"missingCommitsCheck'\n" +"Uyarıların düzeyini değiştirmek için 'git config " +"rebase.missingCommitsCheck'\n" "kullanın. Kullanılabilir davranışlar: ignore, warn, error.\n" "\n" @@ -19361,6 +19693,10 @@ msgstr "pozitif genişlik %%(align) ögeciği ile birlikte bekleniyordu" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "beklenen biçim: %%(ahead-behind:<işlememsi>)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "beklenen biçim: %%(is-base:<işlememsi>)" + #, c-format msgid "malformed field name: %.*s" msgstr "hatalı oluşturulmuş alan adı: %.*s" @@ -19536,17 +19872,26 @@ msgstr "" msgid "log for %s is empty" msgstr "%s için olan günlük boş" -msgid "refusing to force and skip creation of reflog" -msgstr "başvuru günlüğünün oluşturulma/atlanma zorlanması reddediliyor" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "hatalı ada iye '%s' başvurusunu güncelleme reddediliyor" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "" +"'%s' yalancı başvurusu için olan başvuru günlüğünü güncelleme reddediliyor" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "'%s' yalancı başvurusunun güncellenmesi reddediliyor" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "hatalı adlı '%s' başvuru günlüğünü güncelleme reddediliyor" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "hatalı ada iye '%s' başvurusunu güncelleme reddediliyor" + +msgid "refusing to force and skip creation of reflog" +msgstr "başvuru günlüğünün oluşturulma/atlanma zorlanması reddediliyor" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "'%s' başvurusu için update_ref başarısız oldu: %s" @@ -19596,6 +19941,17 @@ msgstr "" "'%s' başvurusu kilitlenemiyor: '%s' hedefiyle bir sembolik başvuru " "bekleniyordu; ancak bu normal bir başvuru" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "başvuru dosyası '%s' yazılamıyor" + +#, c-format +msgid "cannot open directory %s" +msgstr "%s dizini açılamıyor" + +msgid "Checking references consistency" +msgstr "Başvuruların tutarlılığı denetleniyor" + #, c-format msgid "refname is dangerous: %s" msgstr "başvuru adı tehlikeli: %s" @@ -19667,6 +20023,14 @@ msgstr "başvuru adı %s bir sembolik bağ, onu kopyalamak desteklenmiyor" msgid "invalid refspec '%s'" msgstr "geçersiz başvuru belirteci '%s'" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "'%s' dizgisinde '*' yok" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "'%s' yedeğinde '*' yok" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "push-option değerinde geçersiz tırnak içine alım: '%s'" @@ -19786,6 +20150,31 @@ msgstr "remote-curl: yerel bir depo olmadan getirme yapılmaya çalışıldı" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: git'ten bilinmeyen komut '%s'" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"Kaldırma için aday gösterilmiş \"%s/%s\" konumundan\n" +"uzak konum okunuyor.\n" +"\n" +"Eğer hâlâ \"remotes\" dizinini kullanıyorsanız\n" +"yapılandırma tabanlı uzak konumlara geçiş yapmanız\n" +"önerilir:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"Eğer geçiş yapamıyorsanız bunu neden kullandığınıza\n" +"dair bir iletiyi <git@vger.kernel.org> adresine\n" +"gönderin." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "uzak konum yapılandırma stenografisi '/' ile başlayamaz: %s" @@ -19796,6 +20185,10 @@ msgstr "birden fazla receivepack verildi, birincisi kullanılıyor" msgid "more than one uploadpack given, using the first" msgstr "birden fazla uploadpack verildi, birincisi kullanılıyor" +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "tanımlanamayan followRemoteHEAD değeri '%s' yok sayıldı" + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "tanımlanamayan değer transfer.credentialsInUrl: '%s'" @@ -19816,14 +20209,6 @@ msgstr "%s genelde %s ögesini izler, %s değil" msgid "%s tracks both %s and %s" msgstr "%s hem %s hem %s ögelerini izler" -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "dizginin '%s' anahtarında '*' yoktu" - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "dizginin '%s' değerinde '*' yok" - #, c-format msgid "src refspec %s does not match any" msgstr "kaynak başvuru belirteci %s başka hiçbir şeyle eşleşmiyor" @@ -20227,12 +20612,15 @@ msgstr "yalnızca çıkış yapılacak dalın üstverisini indir" msgid "create repository within 'src' directory" msgstr "'src' dizininde depo oluştur" +msgid "specify if tags should be fetched during clone" +msgstr "etiketlerin klonlama sırasında getirilip getirilmeyeceğini belirt" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <ana-dal>] [--full-clone]\n" -"\t[--[no-]src] <url> [<yazılma>]" +"\t[--[no-]src] [--[no-]tags] <url> [<listeleme>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20250,6 +20638,10 @@ msgstr "'%s' için öntanımlı dal alınamadı" msgid "could not configure remote in '%s'" msgstr "'%s' içindeki uzak konum yapılandırılamadı" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "'%s' içindeki etiketler devre dışı bırakılamıyor" + #, c-format msgid "could not configure '%s'" msgstr "'%s' yapılandırılamadı" @@ -21305,6 +21697,10 @@ msgstr "cwd'ye geri dönülemiyor" msgid "failed to stat '%*s%s%s'" msgstr "'%*s%s%s' bilgileri alınamadı" +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' mutlak değil" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -21699,6 +22095,27 @@ 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 "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <seçenekler> -- <revizyon-seçenekleri>" + +msgid "toggle inclusion of blob objects" +msgstr "ikili nesnelerin içerilmesini aç/kapat" + +msgid "toggle inclusion of commit objects" +msgstr "işleme nesnelerinin içerilmesini aç/kapat" + +msgid "toggle inclusion of tag objects" +msgstr "etiket nesnelerinin içerilmesini aç/kapat" + +msgid "toggle inclusion of tree objects" +msgstr "ağaç nesnelerinin içerilmesini aç/kapat" + +msgid "toggle pruning of uninteresting paths" +msgstr "ilgisiz yolların budanmasını aç/kapat" + +msgid "read a pattern list over stdin" +msgstr "stdin'den bir dizgi listesi oku" + #, c-format msgid "commit %s is not marked reachable" msgstr "%s işlemesi ulaşılabilir olarak imlenmedi" @@ -21706,6 +22123,9 @@ msgstr "%s işlemesi ulaşılabilir olarak imlenmedi" msgid "too many commits marked reachable" msgstr "pek fazla işleme ulaşılabilir olarak imlenmiş" +msgid "could not determine MIDX preferred pack" +msgstr "MIDX yeğlenen paketi algılanamadı" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<seçenekler>]" @@ -21768,6 +22188,24 @@ msgstr "jeton" msgid "command token to send to the server" msgstr "sunucuya gönderilecek komut jetonu" +msgid "unit-test [<options>]" +msgstr "unit-test [<seçenekler>]" + +msgid "immediately exit upon the first failed test" +msgstr "ilk başarısız sınamada anında çık" + +msgid "suite[::test]" +msgstr "suite[::test]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "yalnızca sınama paketini veya bireysel <süit[::sınama]> çalıştır" + +msgid "suite" +msgstr "suite" + +msgid "exclude test suite <suite>" +msgstr "<süit> sınama süitini dışla" + #, c-format msgid "running trailer command '%s' failed" msgstr "'%s' artbilgi komutunu çalıştırma başarısız oldu" @@ -22305,6 +22743,10 @@ msgstr "hata: " msgid "warning: " msgstr "uyarı: " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() '%s' hatasını verip çıktı (%d)\n" + msgid "Fetching objects" msgstr "Nesneler getiriliyor" @@ -22336,6 +22778,9 @@ msgstr ".git dosyası bozuk" msgid ".git file incorrect" msgstr ".git dosyası doğru değil" +msgid ".git file absolute/relative path mismatch" +msgstr ".git dosyası mutlak/göreceli yolu uyumsuzluğu" + msgid "not a valid path" msgstr "geçerli bir yol değil" @@ -22351,6 +22796,9 @@ msgstr "depo konumu bulunamıyor: .git dosyası bozuk" msgid "gitdir unreadable" msgstr "okunamayan gitdir" +msgid "gitdir absolute/relative path mismatch" +msgstr "gitdir mutlak/göreceli yolu uyumsuzluğu" + msgid "gitdir incorrect" msgstr "doğru olmayan gitdir" @@ -22385,6 +22833,13 @@ msgstr "%s, '%s' içinde ayarı kaldırılamıyor" msgid "failed to set extensions.worktreeConfig setting" msgstr "extensions.worktreeConfig yapılandırması ayarlanamadı" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"depo biçimi göreceli çalışma ağaçlarını desteklemesi için yükseltilemiyor" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "extensions.relativeWorktrees yapılandırması ayarlanamadı" + #, c-format msgid "could not setenv '%s'" msgstr "setenv '%s' yapılamadı" @@ -22934,6 +23389,9 @@ msgstr "'%s.final' yazılan e-postayı içeriyor.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases diğer seçeneklerle uyumsuz\n" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases ve --translate-aliases birlikte kullanılamaz\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" diff --git a/po/uk.po b/po/uk.po index 297f7b0687295d..39c22289fa62d5 100644 --- a/po/uk.po +++ b/po/uk.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: Git v2.46\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2023-04-11 09:55-0700\n" -"PO-Revision-Date: 2024-07-24 08:45-0700\n" -"Last-Translator: Arkadii Yakovets <ark@cho.red>\n" +"POT-Creation-Date: 2025-03-09 15:40-0700\n" +"PO-Revision-Date: 2025-03-09 16:53-0700\n" +"Last-Translator: Kateryna Golovanova <kate@kgthreads.com>\n" "Language-Team: Ukrainian <https://github.com/arkid15r/git-uk-l10n/>\n" "Language: uk\n" "MIME-Version: 1.0\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.4.2\n" +"X-Generator: Poedit 3.5\n" #, c-format msgid "Huh (%s)?" @@ -41,7 +41,7 @@ msgstr "Оновити" #, c-format msgid "could not stage '%s'" -msgstr "не вдалося додати до індексу %s" +msgstr "не вдалося додати до індексу \"%s\"" msgid "could not write index" msgstr "не вдалося записати індекс" @@ -549,7 +549,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - залишити цей шматок невизначеним, перейти до наступного невизначеного " @@ -562,7 +562,7 @@ msgstr "" "/ - шукати шматок, що відповідає заданому регвиру\n" "s - розбити поточний шматок на менші шматки\n" "e - редагувати поточний шматок вручну\n" -"p - показати поточний шматок\n" +"p - показати поточний шматок, \"P\" для гортання сторінок\n" "? - показати довідку\n" #, c-format @@ -634,10 +634,11 @@ msgstr "Змінено лише бінарні файли." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Вимкнути це повідомлення можна за допомогою \"git config advice.%s false\"" +"Вимкнути це повідомлення можна за допомогою \"git config set advice.%s " +"false\"" #, c-format msgid "%shint:%s%.*s%s\n" @@ -761,8 +762,8 @@ msgstr "" "\n" " git switch -\n" "\n" -"Щоб вимкнути цю пораду, встановіть конфігураційний параметр advice." -"detachedHead у false\n" +"Щоб вимкнути цю пораду, встановіть конфігураційний параметр " +"advice.detachedHead у false\n" #, c-format msgid "" @@ -1255,6 +1256,15 @@ msgstr "" "спробувати тристороннє злиття, повернутися до звичайного латання, якщо це не " "вдасться" +msgid "for conflicts, use our version" +msgstr "у разі конфліктів використовувати нашу версію" + +msgid "for conflicts, use their version" +msgstr "у разі конфліктів використовувати їхню версію" + +msgid "for conflicts, use a union version" +msgstr "у разі конфліктів використовувати обʼєднану версію" + msgid "build a temporary index based on embedded index information" msgstr "створити тимчасовий індекс на основі вбудованої індексної інформації" @@ -1300,6 +1310,9 @@ msgstr "додати <корінь> до всіх назв файлів" msgid "don't return error for empty patches" msgstr "не повертати помилку для порожніх латок" +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs, та --union вимагають --3way" + #, c-format msgid "cannot stream blob %s" msgstr "неможливо транслювати blob %s" @@ -1371,6 +1384,10 @@ msgstr "невірне ім’я об’єкта: %s" msgid "not a tree object: %s" msgstr "не є об’єктом дерева: %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "не вдалося розпакувати обʼєкт дерева %s" + #, c-format msgid "File not found: %s" msgstr "Файл не знайдено: %s" @@ -1416,7 +1433,7 @@ msgid "write the archive to this file" msgstr "записати архів до цього файлу" msgid "read .gitattributes in working directory" -msgstr "прочитати .gitattributes робочої директорії" +msgstr "читати .gitattributes робочої директорії" msgid "report archived files on stderr" msgstr "звітувати про заархівовані файли в stderr" @@ -2174,7 +2191,7 @@ msgstr "" #, c-format msgid "Could not parse object '%s'." -msgstr "Не вдалося розібрати об'єкт '%s'." +msgstr "Не вдалося розібрати обʼєкт \"%s\"." msgid "failed to clean index" msgstr "не вдалося очистити індекс" @@ -2340,6 +2357,18 @@ msgstr "git archive: помилка протоколу" msgid "git archive: expected a flush" msgstr "git archive: очікувалось flush" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<н>] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "проблема із завантаженням розрідженого переходу" + +msgid "Minimum number of objects to request at a time" +msgstr "Мінімальна кількість обʼєктів для запиту за один раз" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Обмежити відсутні обʼєкти поточним розрідженим переходом" + msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2484,9 +2513,6 @@ msgstr "" "неприпустимий аргумент %s для \"git bisect terms\".\n" "Підтримувані опції: --term-good|--term-old і --term-bad|--term-new." -msgid "revision walk setup failed\n" -msgstr "не вдалося налаштувати проходження по ревізіям\n" - #, c-format msgid "could not open '%s' for appending" msgstr "не вдалося відкрити \"%s\" для додавання" @@ -3026,8 +3052,8 @@ msgid "HEAD not found below refs/heads!" msgstr "HEAD не знайдено під refs/heads!" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" "гілку з --recurse-submodules можна використовувати лише якщо увімкнено " "submodule.propagateBranches" @@ -3103,15 +3129,11 @@ msgstr "" msgid "git version:\n" msgstr "версія git:\n" -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() завершився невдало з помилкою \"%s\" (%d)\n" - msgid "compiler info: " msgstr "інформація щодо компілятора: " msgid "libc info: " -msgstr "информація щодо libc: " +msgstr "інформація щодо libc: " msgid "not run from a git repository - no hooks to show\n" msgstr "запущено не з git сховища - немає гачків для показу\n" @@ -3434,7 +3456,7 @@ msgid "use .gitattributes only from the index" msgstr "використовувати .gitattributes тільки з індексу" msgid "read file names from stdin" -msgstr "зчитувати назви файлів з stdin" +msgstr "читати назви файлів з stdin" msgid "terminate input and output records by a NUL character" msgstr "завершувати вхідні та вихідні записи символом NUL" @@ -3478,9 +3500,14 @@ msgstr "git check-mailmap [<опції>] <контакт>..." msgid "also read contacts from stdin" msgstr "також читати контакти з stdin" -#, c-format -msgid "unable to parse contact: %s" -msgstr "не вдалося розібрати контакт: %s" +msgid "read additional mailmap entries from file" +msgstr "читати додаткові записи mailmap з файлу" + +msgid "blob" +msgstr "blob" + +msgid "read additional mailmap entries from blob" +msgstr "читати додаткові записи mailmap з blob" msgid "no contacts specified" msgstr "контакти не вказані" @@ -3519,10 +3546,10 @@ msgid "update stat information in the index file" msgstr "оновити статистичну інформацію в індексному файлі" msgid "read list of paths from the standard input" -msgstr "зчитати список шляхів зі стандартного вводу" +msgstr "читати список шляхів зі стандартного вводу" msgid "write the content to temporary files" -msgstr "записати вміст у тимчасові файли" +msgstr "записати вміст до тимчасових файлів" msgid "copy out the files from named stage" msgstr "скопіювати файли з іменованої стадії" @@ -3648,7 +3675,7 @@ msgstr "Вже на \"%s\"\n" #, c-format msgid "Switched to and reset branch '%s'\n" -msgstr "Переключено на та скинуто гілку '%s'\n" +msgstr "Переключено на та скинуто гілку \"%s\"\n" #, c-format msgid "Switched to a new branch '%s'\n" @@ -3842,19 +3869,23 @@ msgstr "шляхи не можуть використовуватись при #, c-format msgid "'%s' cannot be used with switching branches" -msgstr "'%s' не може використовуватись при переключенні гілок" +msgstr "\"%s\" не може використовуватись при переключенні гілок" + +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "\"%s\" потрібні шляхи для переходу" #, c-format msgid "'%s' cannot be used with '%s'" -msgstr "'%s' не може використовуватись з '%s'" +msgstr "\"%s\" не може використовуватись з \"%s\"" #, c-format msgid "'%s' cannot take <start-point>" -msgstr "'%s' не може прийняти <стартова-точка>" +msgstr "\"%s\" не може прийняти <стартова-точка>" #, c-format msgid "Cannot switch branch to a non-commit '%s'" -msgstr "Неможливо переключити гілку на не коміт '%s'" +msgstr "Неможливо переключити гілку на не коміт \"%s\"" msgid "missing branch or commit argument" msgstr "відсутня гілка або коміт" @@ -3887,8 +3918,8 @@ msgstr "нова ненароджена гілка" msgid "update ignored files (default)" msgstr "оновити ігноровані файли (за замовчуванням)" -msgid "do not check if another worktree is holding the given ref" -msgstr "не перевіряти, чи інше робоче дерево містить дане посилання" +msgid "do not check if another worktree is using this branch" +msgstr "не перевіряти, чи використовує цю гілку інше робоче дерево" msgid "checkout our version for unmerged files" msgstr "використовувати нашу версію для не злитих файлів" @@ -3919,11 +3950,11 @@ msgstr "неприпустиме зазначення шляху" #, c-format msgid "'%s' is not a commit and a branch '%s' cannot be created from it" -msgstr "'%s' не є комітом, і з нього не можна створити гілку '%s'" +msgstr "\"%s\" не є комітом, і з нього не можна створити гілку \"%s\"" #, c-format msgid "git checkout: --detach does not take a path argument '%s'" -msgstr "git checkout: --detach не приймає аргумент шляху '%s'" +msgstr "git checkout: --detach не приймає аргумент шляху \"%s\"" msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" @@ -4123,11 +4154,94 @@ msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "" "clean.requireForce встановлено у true і -f не задано: відмовлено в прибиранні" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<опції>] [--] <сховище> [<директорія>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "інфо: Не вдалося додати запозичений обʼєкт для \"%s\": %s\n" + +#, c-format +msgid "failed to stat '%s'" +msgstr "не вдалося виконати stat \"%s\"" + +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s існує і не є директорією" + +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "\"%s\" є символьним посиланням, відмовлено в клонуванні з --local" + +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "не вдалося запустити ітератор для \"%s\"" + +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "символьне посилання \"%s\" існує, відмовлено в клонуванні з --local" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "не вдалося видалити \"%s\"" + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "неможливо перевірити жорстке посилання \"%s\"" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "жорстке посилання відрізняється від джерела в \"%s\"" + +#, c-format +msgid "failed to create link '%s'" +msgstr "не вдалося створити посилання \"%s\"" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "не вдалося скопіювати файл у \"%s\"" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "не вдалося здійснити перебір для \"%s\"" + +#, c-format +msgid "done.\n" +msgstr "готово.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Клонування пройшло успішно, але не вдалося перейти на гілку.\n" +"Ви можете перевірити, що було додано за допомогою 'git status'\n" +"і повторити спробу за допомогою \"git restore --source=HEAD :/\"\n" + +msgid "remote did not send all necessary objects" +msgstr "віддалене сховище не надіслало всі необхідні обʼєкти" + +#, c-format +msgid "unable to update %s" +msgstr "не вдалося оновити %s" + +msgid "failed to initialize sparse-checkout" +msgstr "не вдалося ініціалізувати розріджений перехід" + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "віддалений HEAD вказує на неіснуюче посилання, неможливо перейти" + +msgid "unable to checkout working tree" +msgstr "не вдалося завантажити стан робочої директорії" + +msgid "unable to write parameters to config file" +msgstr "не вдалося записати параметри до конфігураційного файлу" + +msgid "cannot repack to clean up" +msgstr "неможливо перепакувати для очищення" + +msgid "cannot unlink temporary alternates file" +msgstr "неможливо видалити тимчасовий файл запозичених обʼєктів" msgid "don't clone shallow repository" -msgstr "не клонувати неглибоке сховище" +msgstr "не клонувати поверхневе сховище" msgid "don't create a checkout" msgstr "не переходити на гілку" @@ -4179,6 +4293,9 @@ msgstr "" msgid "checkout <branch> instead of the remote's HEAD" msgstr "перейти до <гілки> замість HEAD віддаленого сховища" +msgid "clone single revision <rev> and check out" +msgstr "клонувати одну ревізію <rev> і перейти на неї" + msgid "path to git-upload-pack on the remote" msgstr "шлях до git-upload-pack на віддаленому сервері" @@ -4191,18 +4308,17 @@ msgstr "створити неглибокий клон вказаної глиб msgid "create a shallow clone since a specific time" msgstr "створити неглибокий клон з певного часу" -msgid "revision" -msgstr "ревізія" +msgid "ref" +msgstr "посилання" -msgid "deepen history of shallow clone, excluding rev" -msgstr "поглибити історію неглибокого клону, за винятком ревізії" +msgid "deepen history of shallow clone, excluding ref" +msgstr "поглибити історію неглибокого клону, за винятком посилання" msgid "clone only one branch, HEAD or --branch" msgstr "клонувати лише одну гілку, HEAD або --branch" -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "" -"не клонувати жодних тегів і не слідувати за ними під час отримувань пізніше" +msgid "clone tags, and make later fetches not to follow them" +msgstr "клонувати теги і більше не слідкувати за ними" msgid "any cloned submodules will be shallow" msgstr "будь-які клоновані підмодулі будуть неглибокими" @@ -4246,95 +4362,8 @@ msgstr "uri" msgid "a URI for downloading bundles before fetching from origin remote" msgstr "URI для завантаження пакунків перед отриманням з віддаленого джерела" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "инфо: Не вдалося додати запозичений обʼєкт для \"%s\": %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "не вдалося виконати stat \"%s\"" - -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s існує і не є директорією" - -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "\"%s\" є символьним посиланням, відмовлено в клонуванні з --local" - -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "не вдалося запустити перебір для \"%s\"" - -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "символьне посилання \"%s\" існує, не можу клонувати з --local" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "не вдалося видалити \"%s\"" - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "неможливо перевірити жорстке посилання \"%s\"" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "жорстке посилання відрізняється від джерела в \"%s\"" - -#, c-format -msgid "failed to create link '%s'" -msgstr "не вдалося створити посилання \"%s\"" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "не вдалося скопіювати файл у \"%s\"" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "не вдалося перебрати \"%s\"" - -#, c-format -msgid "done.\n" -msgstr "готово.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Клонування пройшло успішно, але не вдалося перейти на гілку.\n" -"Ви можете перевірити, що було додано за допомогою 'git status'\n" -"і повторити спробу за допомогою 'git restore --source=HEAD :/'\n" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Не вдалося знайти віддалену гілку %s для клонування." - -msgid "remote did not send all necessary objects" -msgstr "віддалене сховище не надіслало всі необхідні обʼєкти" - -#, c-format -msgid "unable to update %s" -msgstr "не вдалося оновити %s" - -msgid "failed to initialize sparse-checkout" -msgstr "не вдалося ініціалізувати розріджений перехід" - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "віддалений HEAD посилається на неіснуючого рефа, неможливо перейти" - -msgid "unable to checkout working tree" -msgstr "не вдалося завантажити стан робочої директорії" - -msgid "unable to write parameters to config file" -msgstr "не вдалося записати параметри до конфігураційного файлу" - -msgid "cannot repack to clean up" -msgstr "неможливо перепакувати, щоб очистити" - -msgid "cannot unlink temporary alternates file" -msgstr "неможливо видалити тимчасовий файл запозичених обʼєктів" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<опції>] [--] <сховище> [<директорія>]" msgid "Too many arguments." msgstr "Забагато аргументів." @@ -4428,7 +4457,7 @@ msgstr "не вдалося ініціалізувати сховище, URI п #, c-format msgid "failed to fetch objects from bundle URI '%s'" -msgstr "не вдалося отримати обʼєкти з пакунка URI '%s'" +msgstr "не вдалося отримати обʼєкти з пакунка URI \"%s\"" msgid "failed to fetch advertised bundles" msgstr "не вдалося отримати обіцяні пакунки" @@ -4440,6 +4469,10 @@ msgstr "операція віддаленого отримання повідо msgid "Remote branch %s not found in upstream %s" msgstr "Віддалену гілку %s не знайдено у першоджерельному сховищі %s" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "Віддалена ревізія %s не знайдена у першоджерельному сховищі %s" + msgid "You appear to have cloned an empty repository." msgstr "Здається, ви клонували порожнє сховище." @@ -4616,9 +4649,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree: не вдалося прочитати" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4626,16 +4659,16 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<режим>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<режим>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <коміт> | --fixup [(amend|" -"reword):]<коміт>)]\n" +"reword):]<коміт>]\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" -" [(--trailer <токен>[(=|:)<значення>])...] [-S[<ідентифікатор " +" [(--trailer <токен>[(=|:)<значення>])...] [-S[<ідентифікатор-" "ключа>]]\n" -" [--] [<визначник шляху>...]" +" [--] [<визначник-шляху>...]" msgid "git status [<options>] [--] [<pathspec>...]" msgstr "git status [<опції>] [--] [<визначник шляху>...]" @@ -5121,12 +5154,11 @@ msgstr "git config list [<опція-файлу>] [<опція-відображ msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" "git config get [<опція-файлу>] [<опція-відображення>] [--includes] [--all] " -"[--regexp=<регвир>] [--value=<значення>] [--fixed-value] [--" -"default=<значення -за-умовчанням>] <назва>" +"[--regexp] [--value=<значення>] [--fixed-value] [--default=<за " +"замовчуванням>] <назва>" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5137,10 +5169,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" "git config unset [<опція-файлу>] [--all] [--value=<значення>] [--fixed-" -"value] <назва> <значення>" +"value] <назва>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [<опція-файлу>] <стара-назва> <нова-назва>" @@ -5154,6 +5186,15 @@ msgstr "git config edit [<опція-файлу>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "git config [<опція-файлу>] --get-colorbool <назва> [<stdout-is-tty>]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<опція-файлу>] [<опція-відображення>] [--includes] [--all] " +"[--regexp=<регвир>] [--value=<значення>] [--fixed-value] [--default=<за-" +"замовчуванням>] <назва>" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5183,7 +5224,7 @@ msgid "blob-id" msgstr "blob-id" msgid "read config from given blob object" -msgstr "прочитати конфігурацію з наданого blob-обʼєкту" +msgstr "читати конфігурацію з наданого blob-обʼєкту" msgid "Type" msgstr "Тип" @@ -5574,12 +5615,8 @@ msgid "traversed %lu commits\n" msgstr "пройдено через %lu комітів\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"знайдено більше %i тегів; показані %i останніх\n" -"припинено пошук на %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "знайдено %i тегів; припинено пошук на %s\n" #, c-format msgid "describe %s\n" @@ -5964,13 +6001,13 @@ msgid "" "to avoid this check\n" msgstr "" "перевірка примусових оновлень зайняла %.2f секунд; ви можете скористатися\n" -"\"--no-show-forced-updates\" або виконати \"git config fetch." -"showForcedUpdates false\"\n" +"\"--no-show-forced-updates\" або виконати \"git config " +"fetch.showForcedUpdates false\"\n" "щоб уникнути цієї перевірки\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s не надіслав всіх необхідних обʼєктів\n" +msgid "%s did not send all necessary objects" +msgstr "%s не надіслав усі необхідні обʼєкти" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -6007,8 +6044,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "значення \"%s\" опції \"%s\" неприпустиме для %s" #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "опція \"%s\" ігнорується для %s\n" +msgid "option \"%s\" is ignored for %s" +msgstr "опція \"%s\" ігнорується для %s" #, c-format msgid "%s is not a valid object" @@ -6018,6 +6055,21 @@ msgstr "%s не є припустимим об’єктом" msgid "the object %s does not exist" msgstr "об’єкт %s не існує" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Запустіть \"git remote set-head %s %s\", щоб відстежити зміни, або " +"встановіть\n" +"\"remote.%s.followRemoteHEAD\" параметр конфігурації на інше значення\n" +"якщо ви не хочете бачити це повідомлення. Зокрема, виконання\n" +"\"git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s\"\n" +"вимкне попередження, доки віддалене призначення не змінить HEAD на щось інше." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "виявлено кілька гілок, несумісних з --set-upstream" @@ -6158,6 +6210,9 @@ msgstr "refmap" msgid "specify fetch refmap" msgstr "вказати мапу посилань для fetch" +msgid "revision" +msgstr "ревізія" + msgid "report that we have only objects reachable from this object" msgstr "звітувати, що у нас є тільки обʼєкти, доступні з цього обʼєкта" @@ -6212,8 +6267,8 @@ msgid "protocol does not support --negotiate-only, exiting" msgstr "протокол не підтримує --negotiate-only, вихід" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" "--filter можна використовувати лише з віддаленим призначенням, налаштованим " "у extensions.partialclone" @@ -6686,12 +6741,18 @@ msgstr "працювати ретельніше (збільшує час вик msgid "enable auto-gc mode" msgstr "увімкнути режим автоматичного збору сміття" +msgid "perform garbage collection in the background" +msgstr "виконувати прибирання сміття у фоновому режимі" + msgid "force running gc even if there may be another gc running" msgstr "примусово запускати збирач сміття, навіть якщо інший збирач вже працює" msgid "repack all other packs except the largest pack" msgstr "перепакувати всі пакунки, крім найбільшого" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "префікс для зберігання пакунка з обрізаними обʼєктами" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "не вдалося розібрати gc.logExpiry значення %s" @@ -6786,6 +6847,9 @@ msgstr "завдання \"%s\" не можна вибрати кілька ра msgid "run tasks based on the state of the repository" msgstr "запускати завдання на основі стану сховища" +msgid "perform maintenance in the background" +msgstr "виконувати технічне обслуговування у фоновому режимі" + msgid "frequency" msgstr "частота" @@ -6883,8 +6947,26 @@ msgstr "недоступні ні systemd таймери, ні crontab" msgid "%s scheduler is not available" msgstr "%s планувальник недоступний" -msgid "another process is scheduling background maintenance" -msgstr "ще один процес планує фонове обслуговування" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"не вдалося створити \"%s.lock\": %s.\n" +"\n" +"Здається, у цьому сховищі запущено ще один запланований процес git-" +"maintenance(1). Будь ласка, переконайтеся, що у сховищі не запущено інших " +"процесів обслуговування, і\n" +"і спробуйте ще раз. Якщо все одно не вдасться, можливо, \n" +"раніше у цьому сховищі аварійно завершився git-maintenance(1) процес: " +"видаліть файл вручну, щоб продовжити роботу." + +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "не може отримати блокування для планового фонового обслуговування" msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=<планувальник>]" @@ -7051,7 +7133,7 @@ msgid "show the surrounding function" msgstr "показати навколишню функцію" msgid "read patterns from file" -msgstr "зчитувати шаблони з файлу" +msgstr "читати шаблони з файлу" msgid "match <pattern>" msgstr "зіставляти <шаблон>" @@ -7127,7 +7209,7 @@ msgid "write the object into the object database" msgstr "записати об’єкт до бази даних об’єктів" msgid "read the object from stdin" -msgstr "прочитати об’єкт з stdin" +msgstr "читати об’єкт з stdin" msgid "store file as is without filters" msgstr "зберегти файл як є без фільтрів" @@ -7418,19 +7500,19 @@ msgstr "локальний обʼєкт %s пошкоджено" #, c-format msgid "packfile name '%s' does not end with '.%s'" -msgstr "ім’я файла пакунка '%s' не закінчується на '.%s'" +msgstr "ім’я файла пакунка \"%s\" не закінчується на '.%s'" #, c-format msgid "cannot write %s file '%s'" -msgstr "неможливо записати %s файл '%s'" +msgstr "неможливо записати %s файл \"%s\"" #, c-format msgid "cannot close written %s file '%s'" -msgstr "неможливо закрити записаний %s файл '%s'" +msgstr "неможливо закрити записаний %s файл \"%s\"" #, c-format msgid "unable to rename temporary '*.%s' file to '%s'" -msgstr "не вдається перейменувати тимчасовий файл '*.%s' на '%s'" +msgstr "не вдається перейменувати тимчасовий файл \"*.%s\" на \"%s\"" msgid "error while closing pack file" msgstr "помилка під час закриття файлу пакунка" @@ -7441,11 +7523,11 @@ msgstr "невірний pack.indexVersion=%<PRIu32>" #, c-format msgid "Cannot open existing pack file '%s'" -msgstr "Неможливо відкрити існуючий файл пакунка '%s" +msgstr "Неможливо відкрити існуючий файл пакунка \"%s\"" #, c-format msgid "Cannot open existing pack idx file for '%s'" -msgstr "Неможливо відкрити існуючий індексний файл пакунка для '%s" +msgstr "Неможливо відкрити існуючий індексний файл пакунка для \"%s\"" #, c-format msgid "non delta: %d object" @@ -7461,16 +7543,37 @@ msgstr[0] "довжина ланцюжка = %d: %lu об’єкт" msgstr[1] "довжина ланцюжка = %d: %lu об’єкти" msgstr[2] "довжина ланцюжка = %d: %lu об’єктів" +msgid "could not start pack-objects to repack local links" +msgstr "не вдалося розпочати pack-objects для перепакування локальних посилань" + +msgid "failed to feed local object to pack-objects" +msgstr "не вдалося передати локальний обʼєкт до pack-objects" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: очікуються повні рядки шістнадцяткових ідентифікаторів обʼєктів " +"тільки від pack-objects." + +msgid "could not finish pack-objects to repack local links" +msgstr "не вдалося завершити pack-objects для перепакування локальних посилань" + msgid "Cannot come back to cwd" msgstr "Неможливо повернутися до поточної робочої директорії" +#, c-format +msgid "bad --pack_header: %s" +msgstr "невірний --pack_header: %s" + #, c-format msgid "bad %s" msgstr "невірний %s" #, c-format msgid "unknown hash algorithm '%s'" -msgstr "невідомий хеш-алгоритм '%s'" +msgstr "невідомий хеш-алгоритм \"%s\"" + +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor не можна використовувати з назвою пакунка" msgid "--stdin requires a git repository" msgstr "--stdin потребує наявності git сховища" @@ -7656,9 +7759,6 @@ msgstr "-L<діапазон>:<файл> не можна використовув msgid "Final output: %d %s\n" msgstr "Кінцевий результат: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "не вдалося створити тимчасову директорію об’єкта" - #, c-format msgid "git show %s: bad file" msgstr "git show %s: невірний файл" @@ -8231,15 +8331,6 @@ msgstr "використовувати злиття на основі diff3" msgid "use a zealous diff3 based merge" msgstr "використовувати ретельне злиття на основі diff3" -msgid "for conflicts, use our version" -msgstr "у разі конфліктів використовувати нашу версію" - -msgid "for conflicts, use their version" -msgstr "у разі конфліктів використовувати їхню версію" - -msgid "for conflicts, use a union version" -msgstr "у разі конфліктів використовувати об’єднану версію" - msgid "<algorithm>" msgstr "<алгоритм>" @@ -8346,10 +8437,6 @@ msgstr "невідомий варіант стратегії: -X%s" msgid "malformed input line: '%s'." msgstr "невірно сформований рядок вводу: \"%s\"." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "неможливо продовжити злиття; отримано брудний результат для %d" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<опції>] [<коміт>...]" @@ -8709,6 +8796,9 @@ msgstr "" msgid "write multi-pack bitmap" msgstr "записати multi-pack bitmap" +msgid "write a new incremental MIDX" +msgstr "записати новий інкрементний MIDX" + msgid "write multi-pack index containing only given indexes" msgstr "записати multi-pack індекс, що містить лише задані індекси" @@ -8843,11 +8933,11 @@ msgstr "git notes [--ref <посилання-нотатки>] [list [<об’є msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <посилання-нотатки>] add [-f] [--allow-empty] [--" "[no-]separator|--separator=<розділювач-абзаців>] [--[no-]stripspace] [-m " -"<допис> | -F <файл> | (-c | -C) <обʼєкт>] [<обʼєкт>]" +"<допис> | -F <файл> | (-c | -C) <обʼєкт>] [<обʼєкт>] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" @@ -8856,11 +8946,11 @@ msgstr "" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <посилання-нотатки>] append [--allow-empty] [--" "[no-]separator|--separator=<розділювач-абзаців>] [--[no-]stripspace] [-m " -"<допис> | -F <файл> | (-c | -C) <обʼєкт>] [<обʼєкт>]" +"<допис> | -F <файл> | (-c | -C) <обʼєкт>] [<обʼєкт>] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref <посилання-нотатки>] edit [--allow-empty] [<об’єкт>]" @@ -8979,6 +9069,9 @@ msgstr "вміст нотатки у файлі" msgid "reuse and edit specified note object" msgstr "повторно використати та редагувати вказаний обʼєкт нотатки" +msgid "edit note message in editor" +msgstr "редагувати допис нотатки в редакторі" + msgid "reuse specified note object" msgstr "повторно використати вказаний обʼєкт нотатки" @@ -9014,7 +9107,7 @@ msgid "Removing note for object %s\n" msgstr "Видалення нотатки для обʼєкта %s\n" msgid "read objects from stdin" -msgstr "зчитати обʼєкти з stdin" +msgstr "читати обʼєкти з stdin" msgid "load rewriting config for <command> (implies --stdin)" msgstr "" @@ -9136,7 +9229,7 @@ msgid "attempt to remove non-existent note is not an error" msgstr "спроба видалити неіснуючу нотатку не є помилкою" msgid "read object names from the standard input" -msgstr "зчитати імена обʼєктів зі стандартного вводу" +msgstr "читати імена обʼєктів зі стандартного вводу" msgid "do not remove, show only" msgstr "не видаляти, тільки показувати" @@ -9165,6 +9258,13 @@ msgstr "" "git pack-objects [<опції>] <базова-назва> [< <список-посилань> | < <список-" "обʼєктів>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "неприпустима --name-hash-version опція: %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "наразі --write-bitmap-index потребує --name-hash-version=1" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9195,8 +9295,8 @@ msgstr "очікувався обʼєкт на зміщенні %<PRIuMAX> па msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" msgstr "" -"вимкнення bitmap запису, пакунки розбиваються на частини через pack." -"packSizeLimit" +"вимкнення bitmap запису, пакунки розбиваються на частини через " +"pack.packSizeLimit" msgid "Writing objects" msgstr "Запис обʼєктів" @@ -9401,7 +9501,7 @@ msgid "do not create an empty pack output" msgstr "не створювати вивід порожнього пакунка" msgid "read revision arguments from standard input" -msgstr "зчитувати аргументи ревізії зі стандартного вводу" +msgstr "читати аргументи ревізії зі стандартного вводу" msgid "limit the objects to those that are not yet packed" msgstr "обмежувати обʼєкти тільки тими, які ще не запаковані" @@ -9478,6 +9578,9 @@ msgstr "обробка для відсутніх обʼєктів" msgid "do not pack objects in promisor packfiles" msgstr "не пакувати обʼєкти у promisor пакунки" +msgid "implies --missing=allow-any" +msgstr "мається на увазі --missing=allow-any" + msgid "respect islands during delta compression" msgstr "поважати острови під час дельта компресії" @@ -9487,6 +9590,10 @@ msgstr "протокол" msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "вилучити всі налаштовані uploadpack.blobpackfileuri з цим протоколом" +msgid "use the specified name-hash function to group similar objects" +msgstr "" +"використовувати вказану name-hash функцію для групування схожих обʼєктів" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "глибина дельта ланцюжка %d занадто глибока, примусове %d" @@ -9974,7 +10081,7 @@ msgstr "Надсилання до %s\n" #, c-format msgid "failed to push some refs to '%s'" -msgstr "не вдалося надіслати деякі посилання до '%s'" +msgstr "не вдалося надіслати деякі посилання до \"%s\"" msgid "" "recursing into submodule with push.recurseSubmodules=only; using on-demand " @@ -9985,7 +10092,7 @@ msgstr "" #, c-format msgid "invalid value for '%s'" -msgstr "неприпустиме значення для '%s'" +msgstr "неприпустиме значення для \"%s\"" msgid "repository" msgstr "сховище" @@ -10743,8 +10850,11 @@ msgstr "не вказано журнал посилань для видален msgid "invalid ref format: %s" msgstr "неприпустимий формат посилання: %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<формат> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<формат> [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "вкажіть формат посилання, в який потрібно конвертувати" @@ -10752,6 +10862,9 @@ msgstr "вкажіть формат посилання, в який потріб msgid "perform a non-destructive dry-run" msgstr "виконати неруйнівний пробний запуск" +msgid "drop reflogs entirely during the migration" +msgstr "повністю видалити журнал посилань під час міграції" + msgid "missing --ref-format=<format>" msgstr "відсутній --ref-format=<формат>" @@ -10759,6 +10872,12 @@ msgstr "відсутній --ref-format=<формат>" msgid "repository already uses '%s' format" msgstr "сховище вже використовує формат \"%s\"" +msgid "enable strict checking" +msgstr "увімкнути сувору перевірку" + +msgid "'git refs verify' takes no arguments" +msgstr "\"git refs verify\" не потребує аргументів" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -11100,6 +11219,30 @@ msgstr[0] " Локальне посилання налаштовано для \ msgstr[1] " Локальних посилання налаштовано для \"git push\"%s:" msgstr[2] " Локальних посилань налаштовано для \"git push\"%s:" +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "\"%s/HEAD\" не змінився і вказує на \"%s\"\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "\"%s/HEAD\" змінився з \"%s\" і тепер вказує на \"%s\"\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "Створено \"%s/HEAD\", який вказує на \"%s\"\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "\"%s/HEAD\" був відʼєднаний на \"%s\" і тепер вказує на \"%s\"\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"\"%s/HEAD\" раніше вказував на \"%s\" (який не є віддаленою гілкою), але " +"тепер вказує на \"%s\"\n" + msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "" "встановити refs/remotes/<назва>/HEAD відповідно до віддаленого призначення" @@ -11124,7 +11267,7 @@ msgid "Not a valid ref: %s" msgstr "Не є припустимим посиланням: %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "Не вдалося налаштувати %s" #, c-format @@ -11196,8 +11339,14 @@ msgstr "Не видалятиме всі URL-адреси, що не є приз msgid "be verbose; must be placed before a subcommand" msgstr "розгорнутий вивід; має стояти перед підкомандою" -msgid "git repack [<options>]" -msgstr "git repack [<опції>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<н>] [--depth=<н>] [--threads=<н>] [--keep-pack=<назва-пакунка>]\n" +"[--write-midx] [--name-hash-version=<н>]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11272,6 +11421,10 @@ msgstr "передати --no-reuse-delta до git-pack-objects" msgid "pass --no-reuse-object to git-pack-objects" msgstr "передати --no-reuse-object до git-pack-objects" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "вказати версію назви хешу для групування схожих обʼєктів за шляхом" + msgid "do not run git-update-server-info" msgstr "не запускати git-update-server-info" @@ -11321,9 +11474,6 @@ msgstr "знайти геометричну прогресію з факторо 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 "префікс для зберігання пакунка з обрізаними обʼєктами" - msgid "pack prefix to store a pack containing filtered out objects" msgstr "префікс для зберігання пакунка з відфільтрованими обʼєктами" @@ -11540,9 +11690,6 @@ msgstr "тільки один шаблон може бути заданий з - 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 "всі надані позитивні ревізії мають бути посиланнями" @@ -11696,11 +11843,11 @@ msgstr "записати лише той факт, що вилучені шля #, c-format msgid "Failed to resolve '%s' as a valid revision." -msgstr "Не вдалося розпізнати '%s' як припустиму ревізію." +msgstr "Не вдалося розпізнати \"%s\" як припустиму ревізію." #, c-format msgid "Failed to resolve '%s' as a valid tree." -msgstr "Не вдалося розпізнати '%s' як припустиме дерево." +msgstr "Не вдалося розпізнати \"%s\" як припустиме дерево." msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead." msgstr "" @@ -11729,7 +11876,7 @@ msgstr "" #, c-format msgid "Could not reset index file to revision '%s'." -msgstr "Не вдалося скинути індексний файл до ревізії '%s'." +msgstr "Не вдалося скинути індексний файл до ревізії \"%s\"." msgid "Could not write new index file." msgstr "Не вдалося записати новий індексний файл." @@ -12019,7 +12166,7 @@ msgid "use stateless RPC protocol" msgstr "використовувати протокол RPC без збереження стану" msgid "read refs from stdin" -msgstr "прочитати посилання з stdin" +msgstr "читати посилання з stdin" msgid "print status from remote helper" msgstr "вивести статус з віддаленого помічника" @@ -12211,11 +12358,11 @@ msgstr "посилання не існує" msgid "failed to look up reference" msgstr "не вдалося знайти посилання" -msgid "only show tags (can be combined with branches)" -msgstr "показати тільки теги (можна комбінувати з гілками)" +msgid "only show tags (can be combined with --branches)" +msgstr "показувати тільки теги (можна комбінувати з --branches)" -msgid "only show branches (can be combined with tags)" -msgstr "показати тільки гілки (можна комбінувати з тегами)" +msgid "only show branches (can be combined with --tags)" +msgstr "показувати тільки гілки (можна комбінувати з --tags)" msgid "check for reference existence without resolving" msgstr "перевіряти наявність посилання без розвʼязання" @@ -12268,6 +12415,10 @@ msgstr "не вдалося видалити директорію \"%s\"" msgid "failed to create directory for sparse-checkout file" msgstr "не вдалося створити директорію для файлу розрідженого переходу" +#, c-format +msgid "unable to fdopen %s" +msgstr "не вдалося fdopen %s" + msgid "failed to initialize worktree config" msgstr "не вдалося ініціалізувати конфігурацію робочого дерева" @@ -12726,8 +12877,8 @@ msgid "couldn't hash object from '%s'" msgstr "не вдалося хешувати обʼєкт з \"%s\"" #, c-format -msgid "unexpected mode %o\n" -msgstr "неочікуваний режим %o\n" +msgid "unexpected mode %o" +msgstr "неочікуваний режим %o" msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "використати коміт, збережений в індексі, замість підмодуля HEAD" @@ -12771,8 +12922,8 @@ msgid "" "Submodule work tree '%s' contains a .git directory. This will be replaced " "with a .git file by using absorbgitdirs." msgstr "" -"Робоче дерево підмодуля \"%s\" містить директорію .git. Її буде замінено на ." -"git файл за допомогою absorbgitdirs." +"Робоче дерево підмодуля \"%s\" містить директорію .git. Її буде замінено " +"на .git файл за допомогою absorbgitdirs." #, c-format msgid "" @@ -13503,7 +13654,7 @@ msgid "with --stdin: input lines are terminated by null bytes" msgstr "з --stdin: вхідні рядки завершуються нульовими байтами" msgid "read list of paths to be updated from standard input" -msgstr "прочитати список шляхів для оновлення зі стандартного вводу" +msgstr "читати список шляхів для оновлення зі стандартного вводу" msgid "add entries from standard input to the index" msgstr "додати записи зі стандартного вводу до індексу" @@ -13871,6 +14022,9 @@ msgid "try to match the new branch name with a remote-tracking branch" msgstr "" "спробуйте співставити нову назву гілки з назвою віддалено відстежуваної гілки" +msgid "use relative paths for worktrees" +msgstr "використовувати відносні шляхи для робочих дерев" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "опції \"%s\", \"%s\" та \"%s\" не можна використовувати разом" @@ -14149,6 +14303,25 @@ msgstr "неможливо створити \"%s\"" msgid "index-pack died" msgstr "index-pack завершився невдало" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "Директорія \"%s\" присутня в індексі, але не є розрідженою" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "пошкоджене cache-tree має записи, яких немає в індексі" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s з прапорцями 0x%x не слід бути в cache-tree" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "невірне піддерево \"%.*s\"" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "cache-tree для шляху %.*s не співпадає. Очікувалось %s отримано %s" + msgid "terminating chunk id appears earlier than expected" msgstr "ідентифікатор завершення фрагмента зʼявився раніше, ніж очікувалось" @@ -14193,8 +14366,11 @@ msgstr "Імпортувати GNU Arch сховище до Git" msgid "Create an archive of files from a named tree" msgstr "Створити архів файлів з названого дерева" +msgid "Download missing objects in a partial clone" +msgstr "Завантажити відсутні обʼєкти у частковому клонуванні" + msgid "Use binary search to find the commit that introduced a bug" -msgstr "Використати бінарний пошук, щоб знайти коміт, який вніс помилку" +msgstr "Використати бінарний пошук, щоб знайти коміт, який ввів помилку" msgid "Show what revision and author last modified each line of a file" msgstr "Показати, яка ревізія та автор востаннє змінювали кожен рядок файлу" @@ -15007,16 +15183,16 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "Підтримка <GIT_DIR>/info/grafts застаріла\n" -"і буде вилучена в одній з наступних версій Git.\n" +"і буде вилучена у наступній версії Git'у.\n" "\n" -"Будь ласка, скористайтесь \"git replace --convert-graft-file\"\n" -"щоб перетворити щепи на заміни посилань.\n" +"Будь ласка, використовуйте \"git replace --convert-graft-file\"\n" +"щоб перетворити прищепи на замінювані посилання.\n" "\n" "Щоб вимкнути це повідомлення, виконайте\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" #, c-format msgid "commit %s exists in commit-graph but not in the object database" @@ -15586,7 +15762,7 @@ msgstr "помилка протоколу: неочікувані здібнос #, c-format msgid "protocol error: expected shallow sha-1, got '%s'" -msgstr "помилка протоколу: очікувалось неглибоке sha-1, отримано \"%s\"" +msgstr "помилка протоколу: очікувалось поверхневе sha-1, отримано \"%s\"" msgid "repository on the other end cannot be shallow" msgstr "сховище на іншому кінці не може бути неглибоким" @@ -15834,6 +16010,19 @@ msgstr "url не має схеми: %s" msgid "credential url cannot be parsed: %s" msgstr "неможливо розібрати url облікових даних: %s" +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "неприпустимий таймаут \"%s\", очікується невідʼємне ціле число" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "" +"неприпустимий початковий таймаут \"%s\", очікується невідʼємне ціле число" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "неприпустимі максимальні з'єднання \"%s\", очікується число" + msgid "in the future" msgstr "у майбутньому" @@ -16101,6 +16290,12 @@ msgstr "неприпустимий аргумент до %s" msgid "invalid regex given to -I: '%s'" msgstr "неприпустимий regex, переданий до -I: \"%s\"" +msgid "-G requires a non-empty argument" +msgstr "-G потребує непорожнього аргументу" + +msgid "-S requires a non-empty argument" +msgstr "-S потребує непорожнього аргументу" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "не вдалося розібрати параметр опції --submodule: \"%s\"" @@ -16552,6 +16747,21 @@ msgstr "невірний шлях до простору імен git \"%s\"" msgid "too many args to run %s" msgstr "забагато аргументів для запуску %s" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Ви намагаєтеся отримати %s, який знаходиться у файлі коміт-графа, але не в " +"базі даних обʼєктів.\n" +"Ймовірно, це повʼязано з пошкодженням репозиторію.\n" +"Якщо ви намагаєтеся виправити це пошкодження репозиторію повторним " +"отриманням відсутнього обʼєкта, скористайтеся командою \"git fetch --" +"refetch\" з відсутнім обʼєктом." + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: очікувався неглибокий список" @@ -17077,7 +17287,7 @@ msgstr "" #, c-format msgid "git: '%s' is not a git command. See 'git --help'." -msgstr "git: \"%s\" не є командою git. Дивітья git --help." +msgstr "git: \"%s\" не є командою git. Дивіться git --help." msgid "Uh oh. Your system reports no Git commands at all." msgstr "Ой-ой. Ваша система повідомляє про повну відсутність Git команд." @@ -17140,11 +17350,12 @@ msgstr[2] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" -"Гачок \"%s\" було проігноровано, оскільки він не визначений як виконуваний.\n" -"Ви можете вимкнути це попередження за допомогою \"git config advice." -"ignoredHook false\"." +"Гачок \"%s\" було проігноровано, оскільки він не визначений як придатний для " +"виконання.\n" +"Ви можете вимкнути це попередження за допомогою \"git config set " +"advice.ignoredHook false\"." msgid "not a git repository" msgstr "не є git сховищем" @@ -17161,15 +17372,9 @@ msgstr "" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Контроль делегування не підтримується з cURL < 7.22.0" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "Закріплення відкритих ключів не підтримується з cURL < 7.39.0" - msgid "Unknown value for http.proactiveauth" msgstr "Невідоме значення для http.proactiveauth" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE не підтримується з cURL < 7.44.0" - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "Непідтримуваний SSL обробник \"%s\". Підтримувані SSL обробники:" @@ -17330,13 +17535,16 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "Не вдалося створити \"%s.lock\": %s" +msgid "unable to create temporary object directory" +msgstr "не вдалося створити тимчасову директорію обʼєкта" + #, c-format msgid "could not write loose object index %s" msgstr "не вдалося записати індекс вільного обʼєкта %s" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "не вдалося записати індекс вільного обʼєкта %s\n" +msgid "failed to write loose object index %s" +msgstr "не вдалося записати індекс вільного обʼєкта %s" #, c-format msgid "unexpected line: '%s'" @@ -17352,6 +17560,10 @@ msgstr "виявлено цитований CRLF" msgid "unable to format message: %s" msgstr "не вдалося відформатувати допис: %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "неправильний розмір маркера \"%s\", очікується число" + #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Не вдалося обʼєднати підмодуль %s (не активне)" @@ -17887,6 +18099,17 @@ msgstr "не вдалося завантажити пакунок" msgid "could not open index for %s" msgstr "не вдалося відкрити індекс для %s" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "не вдалося звʼязати \"%s\" з \"%s\"" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "не вдалося очистити multi-pack-index при %s" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "неможливо записати інкрементний MIDX з bitmap" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "" "ігнорування існуючого multi-pack-index; невідповідність контрольних сум" @@ -17916,18 +18139,33 @@ msgstr "немає файлів пакунків для індексації." msgid "refusing to write multi-pack .bitmap without any objects" msgstr "відмовлено в записі мультіпакункового .bitmap без обʼєктів" +msgid "unable to create temporary MIDX layer" +msgstr "не вдалося створити тимчасовий шар MIDX" + msgid "could not write multi-pack bitmap" msgstr "не вдалося записати мультіпакунковий bitmap" +msgid "unable to open multi-pack-index chain file" +msgstr "не вдалося відкрити ланцюжковий файл multi-pack-index" + +msgid "unable to rename new multi-pack-index layer" +msgstr "не вдалося перейменувати новий multi-pack-index шар" + msgid "could not write multi-pack-index" msgstr "не вдалося записати multi-pack-index" +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "неможливо видалити пакунки з інкрементним multi-pack-index" + msgid "Counting referenced objects" msgstr "Підрахунок обʼєктів, на які є посилання" msgid "Finding and deleting unreferenced packfiles" msgstr "Пошук і видалення файлів пакунків без посилань" +msgid "cannot repack an incremental multi-pack-index" +msgstr "неможливо перепакувати інкрементний multi-pack-index" + msgid "could not start pack-objects" msgstr "не вдалося розпочати pack-objects" @@ -17990,6 +18228,27 @@ msgstr "" "multi-pack-index назви пакунків знаходяться у невірній послідовності: \"%s\" " "перед \"%s\"" +msgid "multi-pack-index chain file too small" +msgstr "ланцюжковий файл multi-pack-index занадто малий" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "кількість пакунків у базовому MIDX занадто велика: %<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "кількість обʼєктів у базовому MIDX занадто велика: %<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "неприпустимий multi-pack-index ланцюжок: рядок \"%s\" не є хешем" + +msgid "unable to find all multi-pack index files" +msgstr "не вдалося знайти всі файли multi-pack-index" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "неприпустима позиція MIDX обʼєкта, ймовірно, MIDX пошкоджено" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "невірний pack-int-id: %u (%u всього пакунків)" @@ -18008,10 +18267,6 @@ msgstr "" msgid "multi-pack-index large offset out of bounds" msgstr "large offset multi-pack-index виходить за межі" -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "не вдалося очистити multi-pack-index при %s" - msgid "multi-pack-index file exists, but failed to parse" msgstr "multi-pack-index файл існує, але його не вдалося розібрати" @@ -18220,10 +18475,22 @@ msgstr "упакований обʼєкт %s (що зберігається у % msgid "missing mapping of %s to %s" msgstr "відсутнє зіставлення %s до %s" +#, c-format +msgid "unable to open %s" +msgstr "не вдалося відкрити %s" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "файли \"%s\" та \"%s\" відрізняються за вмістом" + #, c-format msgid "unable to write file %s" msgstr "не вдалося записати файл %s" +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "не вдалося записати файл %s, який постійно зникає" + #, c-format msgid "unable to set permission to '%s'" msgstr "не вдалося встановити дозволи для \"%s\"" @@ -18304,10 +18571,6 @@ msgstr "%s: непідтримуваний тип файлу" msgid "%s is not a valid '%s' object" msgstr "%s не є допустимим \"%s\" обʼєктом" -#, c-format -msgid "unable to open %s" -msgstr "не вдалося відкрити %s" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "невідповідність хешу для %s (очікувалось %s)" @@ -18409,7 +18672,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Зазвичай Git ніколи не створює посилання, яке закінчується 40-hex " "символами,\n" @@ -18584,13 +18847,6 @@ 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) є неприпустимим" - msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "пошкоджена bitmap таблиця пошуку: триплетна позиція поза індексом" @@ -18808,6 +19064,52 @@ msgstr "невідомий перемикач \"%c\"" msgid "unknown non-ascii option in string: `%s'" msgstr "невідомий non-ascii параметр у рядку: \"%s\"" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " <%s>" + msgid "..." msgstr "..." @@ -18894,6 +19196,21 @@ msgstr "невірне булеве значення оточення \"%s\" д msgid "failed to parse %s" msgstr "не вдалося розібрати %s" +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "не вдалося пройти дочірні елементи дерева %s: не знайдено" + +#, c-format +msgid "failed to find object %s" +msgstr "не вдалося знайти обʼєкт %s" + +#, c-format +msgid "failed to find tag %s" +msgstr "не вдалося знайти тег %s" + +msgid "failed to setup revision walk" +msgstr "не вдалося налаштувати проходження по ревізіям" + #, c-format msgid "Could not make %s writable by group" msgstr "Не вдалося зробити %s доступним для запису групою" @@ -19043,6 +19360,22 @@ msgstr "назва віддаленого promisor не може починат msgid "could not fetch %s from promisor remote" msgstr "не вдалося отримати %s з віддаленого promisor" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "відоме віддалене сховище з імʼям \"%s\" має URL \"%s\" замість \"%s\"" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "невідоме значення \"%s\" для параметра конфігурації \"%s\"" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "невідомий елемент \"%s\" з віддаленої інформації" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "прийнятий віддалений promisor \"%s\" не знайдено" + msgid "object-info: expected flush after arguments" msgstr "object-info: очікувався flush після аргументів" @@ -19223,7 +19556,7 @@ msgstr "багатоступеневі записи для злитого фай #, c-format msgid "unordered stage entries for '%s'" -msgstr "невпорядковані записи індексу для '%s'" +msgstr "невпорядковані записи індексу для \"%s\"" #, c-format msgid "unable to create load_cache_entries thread: %s" @@ -19536,6 +19869,10 @@ msgstr "очікувалась додатна ширина з %%(align) част msgid "expected format: %%(ahead-behind:<committish>)" msgstr "очікуваний формат: %%(ahead-behind:<комітоподібне>)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "очікуваний формат: %%(is-base:<комітоподібне>)" + #, c-format msgid "malformed field name: %.*s" msgstr "невірно сформована назва поля: %.*s" @@ -19711,17 +20048,25 @@ msgstr "лог для посилання %s несподівано заверш msgid "log for %s is empty" msgstr "лог для %s порожній" -msgid "refusing to force and skip creation of reflog" -msgstr "відмовлено в примусовому пропуску створення рефлогу" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "відмовлено в оновленні посилання з невірною назвою \"%s\"" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "відмовлено в оновленні псевдопосилання \"%s\"" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "відмовлено в оновленні псевдопосилання \"%s\"" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "відмовлено в оновленні reflog з невірною назвою \"%s\"" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "відмовлено в оновленні посилання з невірною назвою \"%s\"" + +msgid "refusing to force and skip creation of reflog" +msgstr "відмовлено в примусовому пропуску створення рефлогу" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "update_ref завершився невдало для посилання \"%s\": %s" @@ -19771,6 +20116,17 @@ msgstr "" "неможливо заблокувати посилання \"%s\": очікувалось символьне посилання з " "призначенням \"%s\", але це звичайне посилання" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "неможливо прочитати файл посилання \"%s\"" + +#, c-format +msgid "cannot open directory %s" +msgstr "неможливо відкрити директорію %s" + +msgid "Checking references consistency" +msgstr "Перевірка співпадіння посилань" + #, c-format msgid "refname is dangerous: %s" msgstr "refname є небезпечним: %s" @@ -19848,6 +20204,14 @@ msgstr "" msgid "invalid refspec '%s'" msgstr "неприпустимий визначник посилання \"%s\"" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "шаблон \"%s\" не має \"*\"" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "заміна \"%s\" не має \"*\"" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "неприпустимі лапки у значенні push-опції: \"%s\"" @@ -19897,8 +20261,8 @@ msgstr "віддалений сервер надіслав неочікуван msgid "unable to rewind rpc post data - try increasing http.postBuffer" msgstr "" -"не вдалося перемотати вперед rpc post дані - спробуйте збільшити http." -"postBuffer" +"не вдалося перемотати вперед rpc post дані - спробуйте збільшити " +"http.postBuffer" #, c-format msgid "remote-curl: bad line length character: %.4s" @@ -19971,9 +20335,32 @@ msgstr "remote-curl: спроба отримання без локального msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: невідома команда \"%s\" з git" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"читання віддаленого призначення з \"%s/%s\", який номіновано на вилучення.\n" +"\n" +"Якщо ви все ще використовуєте директорію \"remotes/\", рекомендується\n" +"перейти віддалені призначення на основі конфігурації:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"Якщо ви не можете цього зробити, будь ласка, дайте нам знати, чому ви все ще " +"використовуєте її\n" +"надіславши листа на адресу <git@vger.kernel.org>." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" -msgstr "скорочення віддаленої конфігураціі не може починатися з '/': %s" +msgstr "скорочене ім'я віддаленої конфігураціі не може починатися з \"/\": %s" msgid "more than one receivepack given, using the first" msgstr "надано більше одного пакунка для отримання, використано перший" @@ -19981,9 +20368,13 @@ msgstr "надано більше одного пакунка для отрим msgid "more than one uploadpack given, using the first" msgstr "надано більше одного пакунка для завантаження, використано перший" +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "нерозпізнане followRemoteHEAD значення \"%s\" було проігноровано" + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" -msgstr "нерозпізнане значення transfer.credentialsInUrl: '%s'" +msgstr "нерозпізнане значення transfer.credentialsInUrl: \"%s\"" #, c-format msgid "URL '%s' uses plaintext credentials" @@ -20001,14 +20392,6 @@ msgstr "%s зазвичай відстежує %s, а не %s" msgid "%s tracks both %s and %s" msgstr "%s відстежує як %s, так і %s" -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "ключ '%s' шаблону не містив '*'" - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "значення '%s' шаблону не містить '*'" - #, c-format msgid "src refspec %s does not match any" msgstr "визначник посилання джерела %s не збігається з жодним" @@ -20106,11 +20489,11 @@ msgstr "HEAD не вказує на гілку" #, c-format msgid "no such branch: '%s'" -msgstr "немає такої гілки: '%s'" +msgstr "немає такої гілки: \"%s\"" #, c-format msgid "no upstream configured for branch '%s'" -msgstr "першоджерельне сховище не налаштовано для гілки '%s'" +msgstr "першоджерельне сховище не налаштовано для гілки \"%s\"" #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" @@ -20131,7 +20514,7 @@ msgid "push refspecs for '%s' do not include '%s'" msgstr "надіслані визначники посилань для \"%s\" не включають \"%s\"" msgid "push has no destination (push.default is 'nothing')" -msgstr "надсилання не має призначення (push.default дорівнює 'nothing')" +msgstr "надсилання не має призначення (push.default дорівнює \"nothing\")" msgid "cannot resolve 'simple' push to a single destination" msgstr "" @@ -20184,7 +20567,7 @@ msgstr[0] "" msgstr[1] "" "Ваша гілка відстає від \"%s\" на %d коміти, і її можна перемотати вперед.\n" msgstr[2] "" -"Ваша гілка відстає від гілки '%s' на %d комітів, і її можна перемотати " +"Ваша гілка відстає від гілки \"%s\" на %d комітів, і її можна перемотати " "вперед.\n" msgid " (use \"git pull\" to update your local branch)\n" @@ -20219,7 +20602,7 @@ msgstr "неможливо розібрати очікувану назву об #, c-format msgid "cannot strip one component off url '%s'" -msgstr "неможливо вилучити один компонент з url '%s'" +msgstr "неможливо вилучити один компонент з url \"%s\"" #, c-format msgid "bad replace ref name: %s" @@ -20429,12 +20812,15 @@ msgstr "" msgid "create repository within 'src' directory" msgstr "створити сховище в директорії \"src\"" +msgid "specify if tags should be fetched during clone" +msgstr "вказати, чи потрібно отримувати теги під час клонування" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <головна-гілка>] [--full-clone]\n" -"\t[--[no-]src] <URL-адреса> [<коренева-директорія>]" +"\t[--[no-]src] [--[no-]tags] <URL-адреса> [<коренева-директорія-проекту>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20452,6 +20838,10 @@ msgstr "не вдалося отримати гілку за замовчува msgid "could not configure remote in '%s'" msgstr "не вдалося налаштувати віддалене сховище в \"%s\"" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "не вдалося вимкнути теги в \"%s\"" + #, c-format msgid "could not configure '%s'" msgstr "не вдалося налаштувати \"%s\"" @@ -20983,7 +21373,7 @@ msgid "" msgstr "" "\"reword\" не приймає коміти злиття. Якщо ви хочете\n" "відтворити злиття та змінити текст допису, використовуйте\n" -"\"merge -c\" для коміта." +"\"merge -c\" для коміта" #. TRANSLATORS: 'edit', 'merge -C' and 'break' should #. not be translated. @@ -21525,6 +21915,10 @@ msgstr "неможливо повернутися до поточної робо msgid "failed to stat '%*s%s%s'" msgstr "не вдалося записати \"%*s%s%s\"" +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory \"%s\" не є абсолютною" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -21863,7 +22257,7 @@ msgstr "Не вдалося оновити підмодуль \"%s\"." #, c-format msgid "submodule git dir '%s' is inside git dir '%.*s'" -msgstr "підмодуль git dir \"%s\" знаходиться всередині git директорії \"%*s\"" +msgstr "підмодуль git dir \"%s\" знаходиться всередині git директорії \"%.*s\"" #, c-format msgid "expected '%.*s' in submodule path '%s' not to be a symbolic link" @@ -21929,6 +22323,27 @@ msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "" "кількість записів у дереві кешу, які потрібно анулювати (за замовчуванням 0)" +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <опції> -- <опції-ревізії>." + +msgid "toggle inclusion of blob objects" +msgstr "перемикач включення обʼєктів blob" + +msgid "toggle inclusion of commit objects" +msgstr "перемикач включення обʼєктів коміту" + +msgid "toggle inclusion of tag objects" +msgstr "перемикач включення обʼєктів тегів" + +msgid "toggle inclusion of tree objects" +msgstr "перемикач включення обʼєктів дерева" + +msgid "toggle pruning of uninteresting paths" +msgstr "перемикач обрізання нецікавих шляхів" + +msgid "read a pattern list over stdin" +msgstr "читати список шаблонів через stdin" + #, c-format msgid "commit %s is not marked reachable" msgstr "коміт %s не позначений як досяжний" @@ -21936,6 +22351,9 @@ msgstr "коміт %s не позначений як досяжний" msgid "too many commits marked reachable" msgstr "забагато комітів позначено як досяжні" +msgid "could not determine MIDX preferred pack" +msgstr "не вдалося визначити бажаний пакунок MIDX" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<опції>]" @@ -22001,6 +22419,24 @@ msgstr "токен" msgid "command token to send to the server" msgstr "токен команди для відправки на сервер" +msgid "unit-test [<options>]" +msgstr "unit-test [<опції>]" + +msgid "immediately exit upon the first failed test" +msgstr "вихід відразу після першого невдалого тесту" + +msgid "suite[::test]" +msgstr "suite[::test]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "запустити тільки набір тестів або окремий тест <suite[::test]>" + +msgid "suite" +msgstr "набір" + +msgid "exclude test suite <suite>" +msgstr "виключити набір тестів <suite>" + #, c-format msgid "running trailer command '%s' failed" msgstr "не вдалося виконати команду трейлера \"%s\"" @@ -22548,6 +22984,10 @@ msgstr "помилка: " msgid "warning: " msgstr "попередження: " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() завершився невдало з помилкою \"%s\" (%d)\n" + msgid "Fetching objects" msgstr "Отримання обʼєктів" @@ -22580,6 +23020,9 @@ msgstr ".git файл пошкоджено" msgid ".git file incorrect" msgstr ".git файл не є коректним" +msgid ".git file absolute/relative path mismatch" +msgstr "неспівпадіння абсолютного/відносного шляху до .git файлу" + msgid "not a valid path" msgstr "неприпустимий шлях" @@ -22595,6 +23038,9 @@ msgstr "не вдалося знайти сховище; файл .git пошк msgid "gitdir unreadable" msgstr "нечитабельна git директорія" +msgid "gitdir absolute/relative path mismatch" +msgstr "неспівпадіння абсолютного/відносного шляху git директорії" + msgid "gitdir incorrect" msgstr "невірна git директорія" @@ -22630,6 +23076,13 @@ msgstr "не вдалося скинути %s в \"%s\"" msgid "failed to set extensions.worktreeConfig setting" msgstr "не вдалося встановити extensions.worktreeConfig параметр" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"не вдалося оновити формат сховища для підтримки відносних робочих дерев" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "не вдалося встановити параметр extensions.relativeWorktrees" + #, c-format msgid "could not setenv '%s'" msgstr "не вдалося встановити змінну оточення \"%s\"" @@ -22965,7 +23418,7 @@ msgstr "" #, c-format msgid "You are currently bisecting, started from branch '%s'." -msgstr "Наразі ви робите бісекцію, починаючи з гілки '%s'." +msgstr "Наразі ви робите бісекцію, починаючи з гілки \"%s\"." msgid "You are currently bisecting." msgstr "Наразі ви робите бісекцію." @@ -23198,6 +23651,9 @@ msgstr "\"%s.final\" містить створений лист.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases несумісна з іншими опціями\n" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases і --translate-aliases є взаємовиключними\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -23370,8 +23826,8 @@ msgstr "" " Наведений вище список копій було розширено додатковими\n" " адресами, знайденими у дописі до коміту латки. Зазвичай\n" " send-email запитує перед надсиланням, коли це трапляється.\n" -" Цю поведінку можна контролювати за допомогою параметра sendemail." -"confirm\n" +" Цю поведінку можна контролювати за допомогою параметра " +"sendemail.confirm\n" " налаштування конфігурації.\n" "\n" " Для отримання додаткової інформації виконайте команду \"git send-email --" diff --git a/po/vi.po b/po/vi.po index 5f42970d4f1798..803a68e1b6025d 100644 --- a/po/vi.po +++ b/po/vi.po @@ -4,14 +4,14 @@ # https://raw.githubusercontent.com/git-l10n/git-po/pot/main/po/git.pot # --- # Copyright (C) 2012-2022, Translation Project, Vietnamese Team <http://translationproject.org/team/vi.html> -# Copyright (C) 2024, Vũ Tiến Hưng <newcomerminecraft@gmail.com> +# Copyright (C) 2024-2025, Vũ Tiến Hưng <newcomerminecraft@gmail.com> # Nguyễn Thái Ngọc Duy <pclouds@gmail.com>, 2012. # Đoàn Trần Công Danh <congdanhqx@gmail.com>, 2020. # Trần Ngọc Quân <vnwildman@gmail.com>, 2012-2022. -# Vũ Tiến Hưng <newcomerminecraft@gmail.com>, 2024. +# Vũ Tiến Hưng <newcomerminecraft@gmail.com>, 2024-2025. # --- # BẢNG THUẬT NGỮ / TERMINOLOGY -# Updated: 2024-07-26, git 2.46 +# Updated: 2025-03-06, git 2.49 # # Ghi chú: # - Bảng thuật ngữ này chưa hoàn thiện. @@ -59,15 +59,17 @@ # | (v.) rebase | cải tổ | # | (v.) squash | squash | # | (v.) amend | tu bổ | +# | (n.) revision | cải biên | +# | (n.) repo/repository | kho chứa | # | | | # | ... TODO ... | | # +------------------------------------------------------------------+ msgid "" msgstr "" -"Project-Id-Version: git 2.46\n" +"Project-Id-Version: git 2.49\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-21 00:11+0700\n" -"PO-Revision-Date: 2024-07-26 11:31+0700\n" +"POT-Creation-Date: 2025-03-05 22:57+0000\n" +"PO-Revision-Date: 2025-03-06 08:20+0700\n" "Last-Translator: Vũ Tiến Hưng <newcomerminecraft@gmail.com>\n" "Language-Team: Vietnamese <https://github.com/Nekosha/git-po>\n" "Language: vi\n" @@ -605,7 +607,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - để lại khúc này là chưa quyết định, xem khúc chưa quyết định kế tiếp\n" @@ -616,7 +618,7 @@ msgstr "" "/ - tìm một khúc khớp với biểu thức chính quy\n" "s - chia khúc hiện tại thành các khúc nhỏ hơn\n" "e - sửa bằng tay khúc hiện hành\n" -"p - in ra khúc hiện hành\n" +"p - in ra khúc hiện hành, 'P' để chạy trình phân trang\n" "? - hiển thị trợ giúp\n" #, c-format @@ -686,10 +688,10 @@ msgstr "Chỉ có các tập tin nhị phân thay đổi." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Tắt lời nhắn này bằng \"git config advice.%s false\"" +"Tắt lời nhắn này bằng \"git config set advice.%s false\"" #, c-format msgid "%shint:%s%.*s%s\n" @@ -1282,6 +1284,15 @@ msgstr "đồng thời áp dụng bản vá (dùng với tùy chọn --stat/--su msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "thử hòa trộn kiểu three-way, quay lại kiểu bình thường nếu thất bại" +msgid "for conflicts, use our version" +msgstr "nếu xung đột, sử dụng phiên bản của ta" + +msgid "for conflicts, use their version" +msgstr "nếu xung đột, sử dụng phiên bản của họ" + +msgid "for conflicts, use a union version" +msgstr "nếu xung đột, sử dụng phiên bản kết hợp" + msgid "build a temporary index based on embedded index information" msgstr "xây dựng chỉ mục tạm thời dựa trên thông tin chỉ mục được nhúng" @@ -1328,6 +1339,9 @@ msgstr "thêm <gốc> vào trước tất cả các tên tập tin" msgid "don't return error for empty patches" msgstr "đừng trả về lỗi khi các bản vá trống rỗng" +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours, --theirs, và --union cần tuỳ chọn --3way" + #, c-format msgid "cannot stream blob %s" msgstr "không thể stream blob '%s'" @@ -1399,6 +1413,10 @@ msgstr "không phải là tên đối tượng hợp lệ: %s" msgid "not a tree object: %s" msgstr "không phải là đối tượng cây: %s" +#, c-format +msgid "failed to unpack tree object %s" +msgstr "gặp lỗi khi giải nén đối tượng cây %s" + #, c-format msgid "File not found: %s" msgstr "Không tìm thấy tập tin: %s" @@ -1585,7 +1603,7 @@ msgid "" "git bisect cannot work properly in this case.\n" "Maybe you mistook %s and %s revs?\n" msgstr "" -"Một số điểm xét duyệt %s không phải tổ tiên của điểm xét duyệt %s.\n" +"Một số lần cải biên %s không phải tổ tiên của lần cải biên %s.\n" "git bisect không thể làm việc đúng trong trường hợp này.\n" "Liệu có phải bạn nhầm lẫn các điểm %s và %s không?\n" @@ -1605,7 +1623,7 @@ msgstr "Đang bisect: gốc hòa trộn cần phải được kiểm tra\n" #, c-format msgid "a %s revision is needed" -msgstr "cần một điểm xét duyệt %s" +msgstr "cần lần cải biên %s" #, c-format msgid "could not create file '%s'" @@ -1645,7 +1663,7 @@ msgstr[0] "(cần khoảng chừng %d bước)" #, c-format msgid "Bisecting: %d revision left to test after this %s\n" msgid_plural "Bisecting: %d revisions left to test after this %s\n" -msgstr[0] "Bisecting: còn %d điểm xét duyệt để kiểm tra %s\n" +msgstr[0] "Bisecting: còn %d lần cải biên để kiểm tra %s\n" msgid "--contents and --reverse do not blend well." msgstr "tùy chọn --contents và --reverse không nên đi với nhau." @@ -1655,7 +1673,7 @@ msgstr "" "cùng sử dụng --reverse và --first-parent cần chỉ định lần chuyển giao cuối" msgid "revision walk setup failed" -msgstr "cài đặt việc di chuyển qua các điểm xét duyệt gặp lỗi" +msgstr "cài đặt việc duyệt qua các lần cải biên gặp lỗi" msgid "" "--reverse --first-parent together require range along first-parent chain" @@ -1888,7 +1906,7 @@ msgid "update tracked files" msgstr "cập nhật các tập tin được theo dõi" msgid "renormalize EOL of tracked files (implies -u)" -msgstr "thường hóa lại EOL của các tập tin được theo dõi (ngụ ý -u)" +msgstr "thường hóa lại EOL của các tập tin được theo dõi (ngầm chỉ định -u)" msgid "record only the fact that the path will be added later" msgstr "chỉ ghi lại sự việc mà đường dẫn sẽ được thêm vào sau" @@ -2001,7 +2019,7 @@ msgstr "không hiểu cú pháp %s" #, c-format msgid "'%s' was deleted by the applypatch-msg hook" -msgstr "'%s' bị xóa bởi móc applypatch-msg" +msgstr "'%s' bị xóa bởi hook applypatch-msg" #, c-format msgid "Malformed input line: '%s'." @@ -2355,6 +2373,18 @@ msgstr "git archive: lỗi giao thức" msgid "git archive: expected a flush" msgstr "git archive: cần flush dữ liệu" +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +msgid "problem loading sparse-checkout" +msgstr "không thể tải checkout thưa" + +msgid "Minimum number of objects to request at a time" +msgstr "Số đối tượng tối thiểu mỗi lần yêu cầu" + +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Chỉ lấy về đối tượng còn thiếu trong checkout thưa hiện tại" + msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" "checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]" @@ -2425,7 +2455,7 @@ msgstr "Đối số bisect_write sai: %s" #, c-format msgid "couldn't get the oid of the rev '%s'" -msgstr "không thể lấy oid của điểm xét duyệt '%s'" +msgstr "không thể lấy oid của lần cải biên '%s'" #, c-format msgid "couldn't open the file '%s'" @@ -2450,7 +2480,7 @@ msgid "" "You can use \"git bisect %s\" and \"git bisect %s\" for that." msgstr "" "Bạn cần bắt đầu bằng lệnh \"git bisect start\".\n" -"Bạn sau đó cần phải chỉ cho tôi ít nhất một điểm xét duyệt %s và một %s.\n" +"Bạn sau đó cần phải chỉ cho tôi ít nhất một lần cải biên %s và một %s.\n" "Bạn có thể sử dụng \"git bisect %s\" và \"git bisect %s\" cho chúng." #, c-format @@ -2497,9 +2527,6 @@ msgstr "" "tham số không hợp lệ %s cho 'git bisect terms'.\n" "Các tùy chọn hỗ trợ là: --term-good|--term-old và --term-bad|--term-new." -msgid "revision walk setup failed\n" -msgstr "gặp lỗi cài đặt việc di chuyển qua các điểm xét duyệt\n" - #, c-format msgid "could not open '%s' for appending" msgstr "không thể mở '%s' để nối thêm" @@ -2513,7 +2540,7 @@ msgstr "không nhận ra tuỳ chọn: '%s'" #, c-format msgid "'%s' does not appear to be a valid revision" -msgstr "'%s' không có vẻ như là một điểm xét duyệt hợp lệ" +msgstr "'%s' không có vẻ như là một lần cải biên hợp lệ" msgid "bad HEAD - I need a HEAD" msgstr "sai HEAD - Tôi cần một HEAD" @@ -2574,11 +2601,11 @@ msgstr "bisect chạy gặp lỗi: không đưa ra lệnh." #, c-format msgid "unable to verify %s on good revision" -msgstr "không thể xác nhận '%s' trên điểm xét duyệt tốt" +msgstr "không thể xác nhận '%s' trên lần cải biên tốt" #, c-format msgid "bogus exit code %d for good revision" -msgstr "mã trả về %d bất thường cho điểm xét duyệt tốt" +msgstr "mã trả về %d bất thường cho lần cải biên tốt" #, c-format msgid "bisect run failed: exit code %d from %s is < 0 or >= 128" @@ -2645,7 +2672,7 @@ msgstr "phải kết thúc bằng một màu" #, c-format msgid "cannot find revision %s to ignore" -msgstr "không thể tìm thấy điểm xét duyệt %s để bỏ qua" +msgstr "không thể tìm thấy lần cải biên %s để bỏ qua" msgid "show blame entries as we find them, incrementally" msgstr "hiển thị các mục 'blame' theo thời gian, tăng dần" @@ -2704,20 +2731,20 @@ msgid "ignore <rev> when blaming" msgstr "bỏ qua <rev> khi blame" msgid "ignore revisions from <file>" -msgstr "bỏ qua các điểm xét duyệt từ <tập tin>" +msgstr "bỏ qua các lần cải biên từ <tập tin>" msgid "color redundant metadata from previous line differently" -msgstr "siêu dữ liệu dư thừa màu từ dòng trước khác hẳn" +msgstr "tô màu khác cho siêu dữ liệu dư thừa từ dòng trước" msgid "color lines by age" -msgstr "các dòng màu theo tuổi" +msgstr "tô màu các dòng theo tuổi" msgid "spend extra cycles to find better match" -msgstr "tiêu thụ thêm năng tài nguyên máy móc để tìm kiếm tốt hơn nữa" +msgstr "tiêu thụ thêm tài nguyên để tìm kiếm tốt hơn nữa" msgid "use revisions from <file> instead of calling git-rev-list" msgstr "" -"sử dụng các điểm xét duyệt (revision) từ <tập tin> thay vì gọi 'git-rev-list'" +"sử dụng các lần cải biên (revision) từ <tập tin> thay vì gọi git-rev-list" msgid "use <file>'s contents as the final image" msgstr "sử dụng nội dung của <tập tin> như là ảnh cuối cùng" @@ -3027,11 +3054,11 @@ msgid "HEAD not found below refs/heads!" msgstr "Không tìm thấy HEAD ở dưới refs/heads!" msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" -"nhánh với --recurse-submodules chỉ có thể được sử dụng nếu submodule." -"propagateBranches được kích hoạt" +"nhánh với --recurse-submodules chỉ có thể được sử dụng nếu " +"submodule.propagateBranches được kích hoạt" msgid "--recurse-submodules can only be used to create branches" msgstr "--recurse-submodules chỉ có thể được sử dụng để tạo ra các nhánh" @@ -3101,10 +3128,6 @@ msgstr "" msgid "git version:\n" msgstr "phiên bản git:\n" -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() gặp lỗi '%s' (%d)\n" - msgid "compiler info: " msgstr "thông tin trình biên dịch: " @@ -3112,7 +3135,7 @@ msgid "libc info: " msgstr "thông tin libc: " msgid "not run from a git repository - no hooks to show\n" -msgstr "không chạy từ một kho git - nên chẳng có móc nào để hiển thị cả\n" +msgstr "không chạy từ một kho git - nên chẳng có hook nào để hiển thị cả\n" msgid "" "git bugreport [(-o | --output-directory) <path>]\n" @@ -3187,7 +3210,7 @@ msgid "System Info" msgstr "Thông tin hệ thống" msgid "Enabled Hooks" -msgstr "Các Móc đã được bật" +msgstr "Các hook đã được bật" #, c-format msgid "unable to write to %s" @@ -3474,9 +3497,14 @@ msgstr "git check-mailmap [<các tùy chọn>] <danh-bạ>..." msgid "also read contacts from stdin" msgstr "đồng thời đọc các danh bạ từ stdin" -#, c-format -msgid "unable to parse contact: %s" -msgstr "không thể đọc danh bạ: '%s'" +msgid "read additional mailmap entries from file" +msgstr "đọc thêm mục mailmap từ tập-tin" + +msgid "blob" +msgstr "blob" + +msgid "read additional mailmap entries from blob" +msgstr "đọc thêm mục mailmap từ blob" msgid "no contacts specified" msgstr "chưa chỉ ra danh bạ" @@ -3692,7 +3720,7 @@ msgstr[0] "" "\n" msgid "internal error in revision walk" -msgstr "lỗi nội bộ trong khi di chuyển qua các điểm xét duyệt" +msgstr "lỗi nội bộ trong khi di chuyển qua các lần cải biên" msgid "Previous HEAD position was" msgstr "Vị trí trước kia của HEAD là" @@ -3813,7 +3841,11 @@ msgstr "các đường dẫn không thể dùng cùng với các nhánh chuyển #, c-format msgid "'%s' cannot be used with switching branches" -msgstr "'%s' không thể được sử dụng với các nhánh chuyển" +msgstr "'%s' không thể được sử dụng khi chuyển nhánh" + +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "'%s' cần đường dẫn để checkout" #, c-format msgid "'%s' cannot be used with '%s'" @@ -3858,8 +3890,8 @@ msgstr "nhánh chưa sinh mới" msgid "update ignored files (default)" msgstr "cập nhật các tập tin bị bỏ qua (mặc định)" -msgid "do not check if another worktree is holding the given ref" -msgstr "không kiểm tra nếu cây làm việc khác đang giữ tham chiếu đã cho" +msgid "do not check if another worktree is using this branch" +msgstr "không kiểm tra nếu cây làm việc khác đang sử dụng nhánh này" msgid "checkout our version for unmerged files" msgstr "checkout phiên bản của ta cho các tập tin chưa được hòa trộn" @@ -4094,8 +4126,91 @@ msgstr "" "clean.requireForce được đặt thành true và không có tuỳ chọn -f; từ chối dọn " "dẹp" -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<các tùy chọn>] [--] <kho> [<t.mục>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "thông tin: không thể thêm thay thế cho '%s': %s\n" + +#, c-format +msgid "failed to stat '%s'" +msgstr "gặp lỗi khi stat '%s'" + +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s có tồn tại nhưng lại không phải là một thư mục" + +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "'%s' là liên kết mềm, từ chối sao chép với --local" + +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "gặp lỗi khi bắt đầu lặp qua '%s'" + +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "liên kết mềm '%s' đã tồn tại, từ chối sao chép với --local" + +#, c-format +msgid "failed to unlink '%s'" +msgstr "gặp lỗi khi unlink '%s'" + +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "không thể kiểm tra liên kết cứng '%s'" + +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "liên kết cứng '%s' khác với nguồn" + +#, c-format +msgid "failed to create link '%s'" +msgstr "gặp lỗi khi tạo liên kết mềm %s" + +#, c-format +msgid "failed to copy file to '%s'" +msgstr "gặp lỗi khi sao chép tập tin tới '%s'" + +#, c-format +msgid "failed to iterate over '%s'" +msgstr "gặp lỗi khi lặp qua '%s'" + +#, c-format +msgid "done.\n" +msgstr "hoàn tất.\n" + +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"Việc nhân bản thành công, nhưng checkout gặp lỗi.\n" +"Kiểm tra xem cái gì đã được checkout bằng lệnh 'git status'\n" +"và thử lại với lệnh 'git restore --source=HEAD :/'\n" + +msgid "remote did not send all necessary objects" +msgstr "máy chủ đã không gửi tất cả các đối tượng cần thiết" + +#, c-format +msgid "unable to update %s" +msgstr "không thể cập nhật %s" + +msgid "failed to initialize sparse-checkout" +msgstr "gặp lỗi khi khởi tạo sparse-checkout" + +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "HEAD ở máy chủ chỉ đến ref không tồn tại, không thể checkout" + +msgid "unable to checkout working tree" +msgstr "không thể checkout cây làm việc" + +msgid "unable to write parameters to config file" +msgstr "không thể ghi các tham số vào tập tin cấu hình" + +msgid "cannot repack to clean up" +msgstr "không thể đóng gói để dọn dẹp" + +msgid "cannot unlink temporary alternates file" +msgstr "không thể bỏ liên kết tập tin thay thế tạm thời" msgid "don't clone shallow repository" msgstr "đừng nhân bản từ kho nông" @@ -4107,7 +4222,7 @@ msgid "create a bare repository" msgstr "tạo kho bare" msgid "create a mirror repository (implies --bare)" -msgstr "tạo kho bản sao (ngụ ý --bare)" +msgstr "tạo kho bản sao (ngầm chỉ định --bare)" msgid "to clone from a local repository" msgstr "để nhân bản từ kho nội bộ" @@ -4148,6 +4263,9 @@ msgstr "dùng <tên> thay cho 'origin' để theo dõi thượng nguồn" msgid "checkout <branch> instead of the remote's HEAD" msgstr "checkout <nhánh> thay cho HEAD của máy chủ" +msgid "clone single revision <rev> and check out" +msgstr "nhân bản chỉ lần cải biên <rev> and check out" + msgid "path to git-upload-pack on the remote" msgstr "đường dẫn đến git-upload-pack trên máy chủ" @@ -4160,19 +4278,17 @@ msgstr "tạo bản sao không đầy đủ cho mức sâu đã cho" msgid "create a shallow clone since a specific time" msgstr "tạo bản sao không đầy đủ từ thời điểm đã cho" -msgid "revision" -msgstr "điểm xét duyệt" +msgid "ref" +msgstr "ref" -msgid "deepen history of shallow clone, excluding rev" -msgstr "làm sâu hơn lịch sử của bản sao shallow, bằng điểm xét duyệt loại trừ" +msgid "deepen history of shallow clone, excluding ref" +msgstr "làm sâu hơn lịch sử của bản sao shallow, loại trừ tham chiếu" msgid "clone only one branch, HEAD or --branch" msgstr "chỉ nhân bản một nhánh, HEAD hoặc --branch" -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "" -"đứng có nhân bản bất kỳ nhánh nào, và làm cho những lần lấy về sau không " -"theo chúng nữa" +msgid "clone tags, and make later fetches not to follow them" +msgstr "nhân bản thẻ, và làm cho những lần lấy về sau không theo chúng nữa" msgid "any cloned submodules will be shallow" msgstr "mọi mô-đun-con nhân bản sẽ là shallow (nông)" @@ -4213,95 +4329,8 @@ msgstr "uri" msgid "a URI for downloading bundles before fetching from origin remote" msgstr "URI để tải xuống bundle trước khi lấy về từ máy chủ origin" -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "thông tin: không thể thêm thay thế cho '%s': %s\n" - -#, c-format -msgid "failed to stat '%s'" -msgstr "gặp lỗi khi stat '%s'" - -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s có tồn tại nhưng lại không phải là một thư mục" - -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "'%s' là liên kết mềm, từ chối sao chép với --local" - -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "gặp lỗi khi bắt đầu lặp qua '%s'" - -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "liên kết mềm '%s' đã tồn tại, từ chối sao chép với --local" - -#, c-format -msgid "failed to unlink '%s'" -msgstr "gặp lỗi khi unlink '%s'" - -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "không thể kiểm tra liên kết cứng '%s'" - -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "liên kết cứng '%s' khác với nguồn" - -#, c-format -msgid "failed to create link '%s'" -msgstr "gặp lỗi khi tạo liên kết mềm %s" - -#, c-format -msgid "failed to copy file to '%s'" -msgstr "gặp lỗi khi sao chép tập tin tới '%s'" - -#, c-format -msgid "failed to iterate over '%s'" -msgstr "gặp lỗi khi lặp qua '%s'" - -#, c-format -msgid "done.\n" -msgstr "hoàn tất.\n" - -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"Việc nhân bản thành công, nhưng checkout gặp lỗi.\n" -"Kiểm tra xem cái gì đã được checkout bằng lệnh 'git status'\n" -"và thử lại với lệnh 'git restore --source=HEAD :/'\n" - -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "Không tìm thấy nhánh máy chủ %s để nhân bản (clone)." - -msgid "remote did not send all necessary objects" -msgstr "máy chủ đã không gửi tất cả các đối tượng cần thiết" - -#, c-format -msgid "unable to update %s" -msgstr "không thể cập nhật %s" - -msgid "failed to initialize sparse-checkout" -msgstr "gặp lỗi khi khởi tạo sparse-checkout" - -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "HEAD ở máy chủ chỉ đến ref không tồn tại, không thể checkout" - -msgid "unable to checkout working tree" -msgstr "không thể checkout cây làm việc" - -msgid "unable to write parameters to config file" -msgstr "không thể ghi các tham số vào tập tin cấu hình" - -msgid "cannot repack to clean up" -msgstr "không thể đóng gói để dọn dẹp" - -msgid "cannot unlink temporary alternates file" -msgstr "không thể bỏ liên kết tập tin thay thế tạm thời" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<các tùy chọn>] [--] <kho> [<t.mục>]" msgid "Too many arguments." msgstr "Quá nhiều đối số." @@ -4408,6 +4437,10 @@ msgstr "trình vận chuyển đã báo lỗi" msgid "Remote branch %s not found in upstream %s" msgstr "Nhánh máy chủ %s không tìm thấy trong thượng nguồn %s" +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "Lần cải biên %s không tìm thấy trong thượng nguồn %s" + msgid "You appear to have cloned an empty repository." msgstr "Bạn hình như là đã nhân bản một kho trống rỗng." @@ -4583,9 +4616,9 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree: gặp lỗi khi đọc" msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -4660,7 +4693,7 @@ msgid "updating files failed" msgstr "cập nhật tập tin gặp lỗi" msgid "failed to unpack HEAD tree object" -msgstr "gặp lỗi khi tháo dỡ HEAD đối tượng cây" +msgstr "gặp lỗi khi giải nén đối tượng cây HEAD" msgid "No paths with --include/--only does not make sense." msgstr "Không đường dẫn với các tùy chọn --include/--only không hợp lý." @@ -5046,7 +5079,7 @@ msgid "commit only specified files" msgstr "chỉ chuyển giao các tập tin đã chỉ ra" msgid "bypass pre-commit and commit-msg hooks" -msgstr "vòng qua móc (hook) pre-commit và commit-msg" +msgstr "bỏ qua hook pre-commit và commit-msg" msgid "show what would be committed" msgstr "hiển thị xem cái gì có thể được chuyển giao" @@ -5055,7 +5088,7 @@ msgid "amend previous commit" msgstr "'tu bổ' (amend) lần commit trước" msgid "bypass post-rewrite hook" -msgstr "vòng qua móc (hook) post-rewrite" +msgstr "bỏ qua hook post-rewrite" msgid "ok to record an empty change" msgstr "ok để ghi lại một thay đổi trống rỗng" @@ -5106,12 +5139,11 @@ msgstr "git config list [<tuỳ-chọn>] [<tuỳ-chọn-hiển-thị>] [--includ msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" "git config get [<tuỳ-chọn>] [<tuỳ-chọn-hiển-thị>] [--includes] [--all] [--" -"regexp=<biểu-thức-chính-quy>] [--value=<giá-trị>] [--fixed-value] [--" -"default=<giá-trị-mặc-định>] <khoá>" +"regexp] [--value=<giá-trị>] [--fixed-value] [--default=<giá-trị-mặc-định>] " +"<tên>" msgid "" "git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" @@ -5122,10 +5154,10 @@ msgstr "" msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" "git config unset [<tuỳ-chọn>] [--all] [--value=<giá-trị>] [--fixed-value] " -"<khoá> <giá-trị>" +"<khoá>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [<tuỳ-chọn>] <tên-cũ> <tên-mới>" @@ -5140,6 +5172,15 @@ msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "" "git config [<tuỳ-chọn>] --get-colorbool <tên> [<stdout-là-tty-hay-không>]" +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<tuỳ-chọn>] [<tuỳ-chọn-hiển-thị>] [--includes] [--all] [--" +"regexp=<biểu-thức-chính-quy>] [--value=<giá-trị>] [--fixed-value] [--" +"default=<giá-trị-mặc-định>] <khoá>" + msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " "[--value=<value>] [--fixed-value] <name> <value>" @@ -5546,15 +5587,11 @@ msgstr "" #, c-format msgid "traversed %lu commits\n" -msgstr "đã xuyên %lu qua lần chuyển giao\n" +msgstr "đã chạy qua %lu lần chuyển giao\n" #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"tìm thấy nhiều hơn %i thẻ; đã liệt kê %i cái gần\n" -"đây nhất bỏ đi tìm kiếm tại %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "tìm thấy %i thẻ; từ bỏ tìm kiếm tại %s\n" #, c-format msgid "describe %s\n" @@ -5941,8 +5978,8 @@ msgstr "" "để tránh kiểm tra này\n" #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s đã không gửi tất cả các đối tượng cần thiết\n" +msgid "%s did not send all necessary objects" +msgstr "%s đã không gửi tất cả các đối tượng cần thiết" #, c-format msgid "rejected %s because shallow roots are not allowed to be updated" @@ -5979,8 +6016,8 @@ msgid "option \"%s\" value \"%s\" is not valid for %s" msgstr "tùy chọn \"%s\" có giá trị \"%s\" là không hợp lệ cho %s" #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "tùy chọn \"%s\" bị bỏ qua với %s\n" +msgid "option \"%s\" is ignored for %s" +msgstr "tùy chọn \"%s\" bị bỏ qua với %s" #, c-format msgid "%s is not a valid object" @@ -5990,6 +6027,19 @@ msgstr "%s không phải là một đối tượng hợp lệ" msgid "the object %s does not exist" msgstr "đối tượng '%s' không tồn tại" +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Chạy 'git remote set-head %s %s' để làm theo thay đổi, hoặc đặt tuỳ chọn\n" +"'remote.%s.followRemoteHEAD' sang giá trị khác nếu bạn không muốn thấy\n" +"thông báo này. Cụ thể, 'git config set remote.%s.followRemoteHEAD %s'\n" +"sẽ vô hiệu cảnh báo này tới khi máy chủ đổi HEAD về chỗ khác." + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "phát hiện nhiều nhánh, không tương thích với --set-upstream" @@ -6034,7 +6084,7 @@ msgid "" "remote name from which new revisions should be fetched" msgstr "" "chưa chỉ ra kho chứa máy chủ; xin hãy chỉ định hoặc là URL hoặc\n" -"tên máy chủ từ cái mà những điểm xét duyệt mới có thể được fetch (lấy về)" +"tên máy chủ từ cái mà những lần cải biên mới có thể được fetch (lấy về)" msgid "you need to specify a tag name" msgstr "bạn cần chỉ định một tên thẻ" @@ -6127,6 +6177,9 @@ msgstr "refmap" msgid "specify fetch refmap" msgstr "chỉ ra refmap cần lấy về" +msgid "revision" +msgstr "lần cải biên" + msgid "report that we have only objects reachable from this object" msgstr "báo rằng ta chỉ có các đối tượng tiếp cận được từ đối tượng này" @@ -6179,11 +6232,11 @@ msgid "protocol does not support --negotiate-only, exiting" msgstr "giao thức không hỗ trợ --negotiate-only, nên thoát" msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "" -"--filter chỉ có thể được dùng với máy chủ được cấu hình bằng extensions." -"partialclone" +"--filter chỉ có thể được dùng với máy chủ được cấu hình bằng " +"extensions.partialclone" msgid "--atomic can only be used when fetching from one remote" msgstr "--atomic chỉ có thể dùng khi lấy về từ một máy chủ" @@ -6652,7 +6705,10 @@ msgid "be more thorough (increased runtime)" msgstr "cẩn thận hơn nữa (tăng thời gian chạy)" msgid "enable auto-gc mode" -msgstr "bật chế độ auto-gc" +msgstr "bật chế độ auto-gc (tự động dọn rác)" + +msgid "perform garbage collection in the background" +msgstr "tiến hành gc (dọn rác) trong nền" msgid "force running gc even if there may be another gc running" msgstr "buộc gc chạy ngay cả khi có tiến trình gc khác đang chạy" @@ -6660,6 +6716,9 @@ msgstr "buộc gc chạy ngay cả khi có tiến trình gc khác đang chạy" msgid "repack all other packs except the largest pack" msgstr "đóng gói lại tất cả các gói khác ngoại trừ gói lớn nhất" +msgid "pack prefix to store a pack containing pruned objects" +msgstr "tiền tố của gói để lưu gói gồm những đối tượng đã loại bỏ" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "gặp lỗi khi đọc giá trị gc.logExpiry %s" @@ -6751,6 +6810,9 @@ msgstr "nhiệm vụ '%s' không được chọn nhiều lần" msgid "run tasks based on the state of the repository" msgstr "chạy nhiệm vụ dựa trên trạng thái của kho chứa" +msgid "perform maintenance in the background" +msgstr "tiến hành bảo trì trong nền" + msgid "frequency" msgstr "tần số" @@ -6846,8 +6908,24 @@ msgstr "hoặc là bộ lập lịch systemd hoặc là crontab không sẵn có msgid "%s scheduler is not available" msgstr "bộ lên lịch %s không sẵn có" -msgid "another process is scheduling background maintenance" -msgstr "một tiến trình khác được lập kế hoạch chạy nền để bảo trì" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"Không thể tạo '%s.lock': %s.\n" +"\n" +"Tiến trình git-maintenance(1) khác có lẽ đang chạy ở kho này. Vui lòng\n" +"chắc chắn rằng mọi tiến trình đã kết thúc và sau đó thử lại. Nếu vẫn lỗi,\n" +"một tiến trình git-maintenance(1) có lẽ đã crash ở kho này trước đó:\n" +"gõ bỏ tập tin thủ công để tiếp tục." + +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "không thể lấy được lock để bảo trì nền theo kế hoạch" msgid "git maintenance start [--scheduler=<scheduler>]" msgstr "git maintenance start [--scheduler=<bộ lên lịch>]" @@ -7030,10 +7108,10 @@ msgid "show only matches from files that match all patterns" msgstr "chỉ hiển thị những cái khớp từ tập tin mà nó khớp toàn bộ các mẫu" msgid "pager" -msgstr "dàn trang" +msgstr "trình phân trang" msgid "show matching files in the pager" -msgstr "hiển thị các tập tin khớp trong trang giấy" +msgstr "hiển thị các tập tin khớp trong trình phân trang" msgid "allow calling of grep(1) (ignored by this build)" msgstr "cho phép gọi grep(1) (bị bỏ qua bởi lần dịch này)" @@ -7049,7 +7127,7 @@ msgstr "--no-index hay --untracked không được sử dụng cùng với revs" #, c-format msgid "unable to resolve revision: %s" -msgstr "không thể phân giải điểm xét duyệt: %s" +msgstr "không thể phân giải lần cải biên: %s" msgid "--untracked not supported with --recurse-submodules" msgstr "tùy chọn --untracked không được hỗ trợ với --recurse-submodules" @@ -7214,8 +7292,8 @@ msgid "" "git hook run [--ignore-missing] [--to-stdin=<path>] <hook-name> [-- <hook-" "args>]" msgstr "" -"git hook run [--ignore-missing] [--to-stdin=</đường/dẫn/>] <tên-móc> [-- " -"<các tham số cho móc>]" +"git hook run [--ignore-missing] [--to-stdin=</đường/dẫn/>] <tên-hook> [-- " +"<các tham số cho hook>]" msgid "silently ignore missing requested <hook-name>" msgstr "âm thầm bỏ qua các <hook-name> đã yêu cầu còn thiếu" @@ -7409,9 +7487,27 @@ msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "chiều dài chuỗi = %d: %lu đối tượng" +msgid "could not start pack-objects to repack local links" +msgstr "không thể bắt đầu pack-objects để đóng gói lại các link cục bộ" + +msgid "failed to feed local object to pack-objects" +msgstr "gặp lỗi khi đưa local object cho pack-objects" + +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: Đang chỉ cần các dòng ID đối tượng dạng hexa đầy đủ từ pack-" +"objects." + +msgid "could not finish pack-objects to repack local links" +msgstr "không thể hoàn tất pack-objects để đóng gói các link cục bộ" + msgid "Cannot come back to cwd" msgstr "Không thể quay lại thư mục hiện hành" +#, c-format +msgid "bad --pack_header: %s" +msgstr "--pack_header sai: %s" + #, c-format msgid "bad %s" msgstr "%s sai" @@ -7420,6 +7516,9 @@ msgstr "%s sai" msgid "unknown hash algorithm '%s'" msgstr "không hiểu thuật toán băm dữ liệu '%s'" +msgid "--promisor cannot be used with a pack name" +msgstr "không được dùng --promisor với tên pack" + msgid "--stdin requires a git repository" msgstr "--stdin cần một kho git" @@ -7519,7 +7618,7 @@ msgid "edit files in place" msgstr "sửa các tập tin tại chỗ" msgid "trim empty trailers" -msgstr "cắt bỏ phần trống thừa ở đuôi" +msgstr "cắt bỏ phần trailer trống ở đuôi" msgid "placement" msgstr "vị trí" @@ -7603,9 +7702,6 @@ msgstr "-L<vùng>:<tập tin> không thể được sử dụng với đặc t msgid "Final output: %d %s\n" msgstr "Đầu ra cuối cùng: %d %s\n" -msgid "unable to create temporary object directory" -msgstr "không thể tạo thư mục đối tượng tạm thời" - #, c-format msgid "git show %s: bad file" msgstr "git show %s: sai tập tin" @@ -7680,10 +7776,10 @@ msgid "failed to find exact merge base" msgstr "gặp lỗi khi tìm gốc hòa trộn chính xác" msgid "base commit should be the ancestor of revision list" -msgstr "lần chuyển giao nền không là tổ tiên của danh sách điểm xét duyệt" +msgstr "lần chuyển giao nền không là tổ tiên của danh sách lần cải biên" msgid "base commit shouldn't be in revision list" -msgstr "lần chuyển giao nền không được trong danh sách điểm xét duyệt" +msgstr "lần chuyển giao nền không được trong danh sách lần cải biên" msgid "cannot get patch id" msgstr "không thể lấy mã bản vá" @@ -8068,7 +8164,8 @@ msgid "use full path names" msgstr "dùng tên đường dẫn đầy đủ" msgid "list entire tree; not just current directory (implies --full-name)" -msgstr "liệt kê cây mục tin; không chỉ thư mục hiện hành (ngụ ý --full-name)" +msgstr "" +"liệt kê cây mục tin; không chỉ thư mục hiện hành (ngầm chỉ định --full-name)" msgid "--format can't be combined with other format-altering options" msgstr "" @@ -8174,15 +8271,6 @@ msgstr "dùng kiểu hòa dựa trên diff3" msgid "use a zealous diff3 based merge" msgstr "dùng kiểu hòa trộn dựa trên 'zealous diff3'" -msgid "for conflicts, use our version" -msgstr "nếu xung đột, sử dụng phiên bản của ta" - -msgid "for conflicts, use their version" -msgstr "nếu xung đột, sử dụng phiên bản của họ" - -msgid "for conflicts, use a union version" -msgstr "nếu xung đột, sử dụng phiên bản kết hợp" - msgid "<algorithm>" msgstr "<thuật toán>" @@ -8286,10 +8374,6 @@ msgstr "không hiểu chiến lược: -X%s" msgid "malformed input line: '%s'." msgstr "dòng đầu vào sai quy cách: '%s'." -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "không thể tiếp tục hoà trộn; kết quả không hoàn toàn %d" - msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<các tùy chọn>] [<commit>...]" @@ -8366,10 +8450,10 @@ msgid "continue the current in-progress merge" msgstr "tiếp tục quá trình hòa trộn hiện tại đang thực hiện" msgid "bypass pre-merge-commit and commit-msg hooks" -msgstr "vòng qua móc (hook) pre-merge-commit và commit-msg" +msgstr "bỏ qua hook pre-merge-commit và commit-msg" msgid "could not run stash." -msgstr "không thể chạy stash." +msgstr "không thể chạy tạm cất." msgid "stash failed" msgstr "lệnh tạm cất gặp lỗi" @@ -8654,6 +8738,9 @@ msgstr "gói được sử dụng khi tính toán một \"multi-pack bitmap\"" msgid "write multi-pack bitmap" msgstr "ghi multi-pack bitmap" +msgid "write a new incremental MIDX" +msgstr "ghi incremental MIDX mới" + msgid "write multi-pack index containing only given indexes" msgstr "ghi chỉ mục multi-pack chỉ chứa các chỉ mục đã cho" @@ -8788,11 +8875,11 @@ msgstr "git notes [--ref <notes-ref>] [list [<đối-tượng>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <lời-nhắn> | -F <tập-" -"tin> | (-c | -C) <đối-tượng>] [<đối-tượng>]" +"tin> | (-c | -C) <đối-tượng>] [<đối-tượng>] [-e]" msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "git notes [--ref <notes-ref>] copy [-f] <từ-đối-tượng> <đến-đối-tượng>" @@ -8800,11 +8887,11 @@ msgstr "git notes [--ref <notes-ref>] copy [-f] <từ-đối-tượng> <đến- msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <lời-nhắn> | -F <tập-" -"tin> | (-c | -C) <đối-tượng>] [<đối-tượng>]" +"tin> | (-c | -C) <đối-tượng>] [<đối-tượng>] [-e]" msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" msgstr "git notes [--ref <notes-ref>] edit [--allow-empty] [<đối-tượng>]" @@ -8923,6 +9010,9 @@ msgstr "nội dung ghi chú (note) nằm trong một tập tin" msgid "reuse and edit specified note object" msgstr "dùng lại nhưng có sửa chữa đối tượng note đã chỉ ra" +msgid "edit note message in editor" +msgstr "sửa lại chú thích trong trình soạn thảo" + msgid "reuse specified note object" msgstr "dùng lại đối tượng ghi chú (note) đã chỉ ra" @@ -8961,7 +9051,7 @@ msgid "read objects from stdin" msgstr "đọc các đối tượng từ stdin" msgid "load rewriting config for <command> (implies --stdin)" -msgstr "tải cấu hình chép lại cho <lệnh> (ngụ ý --stdin)" +msgstr "tải cấu hình chép lại cho <lệnh> (ngầm chỉ định --stdin)" msgid "too few arguments" msgstr "quá ít đối số" @@ -9110,6 +9200,13 @@ msgstr "" "git pack-objects [<các tùy chọn>] <base-name> [< <danh-sách-ref> | < <danh-" "sách-đối-tượng>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "tùy chọn --name-hash-version không hợp lệ: %d" + +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "--write-bitmap-index hiện cần --name-hash-version=1" + #, c-format msgid "" "write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " @@ -9287,7 +9384,7 @@ msgstr "không phải một rev '%s'" #, c-format msgid "bad revision '%s'" -msgstr "điểm xem xét sai '%s'" +msgstr "lần cải biên sai '%s'" msgid "unable to add recent objects" msgstr "không thể thêm các đối tượng mới dùng" @@ -9328,7 +9425,7 @@ msgid "limit pack window by memory in addition to object limit" msgstr "giới hạn cửa sổ đóng gói theo bộ nhớ cộng thêm với giới hạn đối tượng" msgid "maximum length of delta chain allowed in the resulting pack" -msgstr "độ dài tối đa của chuỗi móc xích 'delta' được phép trong gói kết quả" +msgstr "độ dài tối đa của chuỗi delta được phép trong gói kết quả" msgid "reuse existing deltas" msgstr "dùng lại các delta sẵn có" @@ -9421,8 +9518,11 @@ msgstr "xử lý cho thiếu đối tượng" msgid "do not pack objects in promisor packfiles" msgstr "không thể đóng gói các đối tượng trong các tập tin gói promisor" +msgid "implies --missing=allow-any" +msgstr "ngầm chỉ định --missing=allow-any" + msgid "respect islands during delta compression" -msgstr "tôn trọng island trong suốt quá trình nén 'delta'" +msgstr "tôn trọng island trong suốt quá trình nén delta" msgid "protocol" msgstr "giao thức" @@ -9430,6 +9530,9 @@ msgstr "giao thức" msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "loại trừ bất kỳ cấu hình uploadpack.blobpackfileuri với giao thức này" +msgid "use the specified name-hash function to group similar objects" +msgstr "dùng hàm băm này để nhóm các đối tượng giống nhau" + #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "mức delta chain %d là quá sâu, buộc dùng %d" @@ -9557,7 +9660,7 @@ msgid "allow fast-forward" msgstr "cho phép chuyển-tiếp-nhanh" msgid "control use of pre-merge-commit and commit-msg hooks" -msgstr "điều khiển cách dùng các móc (hook) pre-merge-commit và commit-msg" +msgstr "điều khiển cách dùng các hook pre-merge-commit và commit-msg" msgid "automatically stash/stash pop before and after" msgstr "tự động stash/stash pop trước và sau" @@ -9758,8 +9861,8 @@ msgid "" msgstr "" "\n" "Để tránh tự động cấu hình nhánh thượng nguồn khi tên của chúng\n" -"không khớp với nhánh nội bộ, xem tùy chọn 'simple' của branch." -"autoSetupMerge\n" +"không khớp với nhánh nội bộ, xem tùy chọn 'simple' của " +"branch.autoSetupMerge\n" "trong 'git help config'.\n" #, c-format @@ -9967,7 +10070,7 @@ msgid "prune locally removed refs" msgstr "xén tỉa những tham chiếu bị gỡ bỏ" msgid "bypass pre-push hook" -msgstr "vòng qua móc tiền-đẩy (pre-push)" +msgstr "bỏ qua hook tiền-đẩy (pre-push)" msgid "push missing but relevant tags" msgstr "push phần bị thiếu nhưng các thẻ lại thích hợp" @@ -10182,7 +10285,7 @@ msgid "" msgstr "" "\n" "git gặp phải một lỗi trong khi đang chuẩn bị các bản vá để diễn lại\n" -"những điểm xét duyệt này:\n" +"những lần cải biên này:\n" "\n" " %s\n" "\n" @@ -10262,10 +10365,10 @@ msgid "use the merge-base of upstream and branch as the current base" msgstr "sử dụng gốc hòa trộn của thượng nguồn và nhánh làm gốc hiện tại" msgid "allow pre-rebase hook to run" -msgstr "cho phép móc (hook) pre-rebase được chạy" +msgstr "cho phép hook pre-rebase được chạy" msgid "be quiet. implies --no-stat" -msgstr "im lặng. ngụ ý --no-stat" +msgstr "im lặng. ngầm chỉ định --no-stat" msgid "display a diffstat of what changed upstream" msgstr "hiển thị diffstat của những thay đổi thượng nguồn" @@ -10499,14 +10602,14 @@ msgid "Current branch %s is up to date.\n" msgstr "Nhánh hiện tại %s đã được cập nhật rồi.\n" msgid "HEAD is up to date, rebase forced." -msgstr "HEAD hiện đã được cập nhật rồi, bị ép buộc rebase." +msgstr "HEAD hiện đã được cập nhật rồi, ép buộc rebase." #, c-format msgid "Current branch %s is up to date, rebase forced.\n" -msgstr "Nhánh hiện tại %s đã được cập nhật rồi, lệnh rebase ép buộc.\n" +msgstr "Nhánh hiện tại %s đã được cập nhật rồi, ép buộc rebase.\n" msgid "The pre-rebase hook refused to rebase." -msgstr "Móc (hook) pre-rebase từ chối rebase." +msgstr "Hook pre-rebase từ chối rebase." #, c-format msgid "Changes to %s:\n" @@ -10519,7 +10622,7 @@ msgstr "Thay đổi từ %s thành %s:\n" #, c-format msgid "First, rewinding head to replay your work on top of it...\n" msgstr "" -"Trước tiên, di chuyển head để xem lại các công việc trên đỉnh của nó...\n" +"Trước tiên, di chuyển lại head để thực hiện lại các thay đổi trên nó...\n" msgid "Could not detach HEAD" msgstr "Không thể tách rời HEAD" @@ -10671,8 +10774,11 @@ msgstr "chưa chỉ ra reflog để xóa" msgid "invalid ref format: %s" msgstr "định dạng tham chiếu không hợp lệ: %s" -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<định dạng> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<định dạng> [--no-reflog] [--dry-run]" + +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" msgid "specify the reference format to convert to" msgstr "chỉ định định dạng tham chiếu để chuyển đổi sang" @@ -10680,6 +10786,9 @@ msgstr "chỉ định định dạng tham chiếu để chuyển đổi sang" msgid "perform a non-destructive dry-run" msgstr "chạy thử mà không thay đổi gì" +msgid "drop reflogs entirely during the migration" +msgstr "bỏ reflog khi chuyển đổi" + msgid "missing --ref-format=<format>" msgstr "thiếu --ref-format=<định dạng>" @@ -10687,6 +10796,12 @@ msgstr "thiếu --ref-format=<định dạng>" msgid "repository already uses '%s' format" msgstr "kho đã dùng định dạng '%s'" +msgid "enable strict checking" +msgstr "cho phép kiểm tra nghiêm ngặt" + +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' không nhận tham số" + msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" "mirror=<fetch|push>] <name> <url>" @@ -11012,6 +11127,29 @@ msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Những tham chiếu nội bộ được cấu hình cho lệnh 'git push'%s:" +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "'%s/HEAD' không đổi và trỏ đến '%s'\n" + +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' đã đổi từ '%s' để trỏ đến '%s'\n" + +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "'%s/HEAD' đã tạo và trỏ đến '%s'\n" + +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' đã tách ra ở '%s' và trỏ đến '%s'\n" + +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"'%s/HEAD' từng trỏ đến '%s' (không phải nhánh máy chủ) và giờ trỏ đến '%s'\n" + msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "đặt refs/remotes/<tên>/HEAD cho phù hợp với máy chủ" @@ -11033,7 +11171,7 @@ msgid "Not a valid ref: %s" msgstr "Không phải là tham chiếu hợp lệ: %s" #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "Không thể cài đặt %s" #, c-format @@ -11105,8 +11243,14 @@ msgstr "Sẽ không xóa những địa chỉ URL không-push" msgid "be verbose; must be placed before a subcommand" msgstr "chi tiết; phải được đặt trước một lệnh-con" -msgid "git repack [<options>]" -msgstr "git repack [<các tùy chọn>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<tên-pack>]\n" +"[--write-midx] [--name-hash-version=<n>]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11182,6 +11326,10 @@ msgstr "chuyển --no-reuse-delta cho git-pack-objects" msgid "pass --no-reuse-object to git-pack-objects" msgstr "chuyển --no-reuse-object cho git-pack-objects" +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "phiên bản hàm băm để nhóm đối tượng giống nhau theo đường dẫn" + msgid "do not run git-update-server-info" msgstr "không chạy git-update-server-info" @@ -11230,9 +11378,6 @@ msgstr "tìm một tiến trình hình học với hệ số <N>" msgid "write a multi-pack index of the resulting packs" msgstr "ghi chỉ mục 'multi-pack' của các gói kết quả" -msgid "pack prefix to store a pack containing pruned objects" -msgstr "tiền tố của gói để lưu gói gồm những đối tượng đã loại bỏ" - msgid "pack prefix to store a pack containing filtered out objects" msgstr "tiền tố của gói để lưu gói gồm những đối tượng đã lọc bỏ" @@ -11449,11 +11594,8 @@ msgstr "chỉ được chỉ định một mẫu cùng với tùy chọn -l" msgid "need some commits to replay" msgstr "cần các chuyển giao để phát lại" -msgid "--onto and --advance are incompatible" -msgstr "--onto và --advance xung khắc" - msgid "all positive revisions given must be references" -msgstr "mọi điểm xét duyệt cộng thêm phải là tên tham chiếu" +msgstr "mọi lần cải biên cộng thêm phải là tên tham chiếu" msgid "argument to --advance must be a reference" msgstr "tham số cho --advance phải là tham chiếu" @@ -11499,11 +11641,11 @@ msgid "" "some rev walking options will be overridden as '%s' bit in 'struct rev_info' " "will be forced" msgstr "" -"một số tuỳ chọn duyệt qua điểm xét duyệt sẽ bị bỏ qua do bit '%s' trong " +"một số tuỳ chọn duyệt qua lần cải biên sẽ bị bỏ qua do bit '%s' trong " "'struct rev_info' bị ép bật/tắt" msgid "error preparing revisions" -msgstr "gặp lỗi khi chuẩn bị các điểm xét duyệt" +msgstr "gặp lỗi khi chuẩn bị các lần cải biên" msgid "replaying down to root commit is not supported yet!" msgstr "chưa hỗ trợ phát lại đến lần chuyển giao gốc!" @@ -11598,7 +11740,7 @@ msgstr "chỉ ghi lại những đường dẫn thực sự sẽ được thêm #, c-format msgid "Failed to resolve '%s' as a valid revision." -msgstr "Gặp lỗi khi phân giải '%s' thành điểm xét duyệt hợp lệ." +msgstr "Gặp lỗi khi phân giải '%s' thành lần cải biên hợp lệ." #, c-format msgid "Failed to resolve '%s' as a valid tree." @@ -11631,7 +11773,7 @@ msgstr "" #, c-format msgid "Could not reset index file to revision '%s'." -msgstr "Không thể đặt lại (reset) chỉ mục thành điểm xét duyệt '%s'." +msgstr "Không thể đặt lại (reset) chỉ mục thành lần cải biên '%s'." msgid "Could not write new index file." msgstr "Không thể ghi tập tin chỉ mục mới." @@ -11673,7 +11815,7 @@ msgid "missing opt-spec before option flags" msgstr "thiếu opt-spec trước các tuỳ chọn" msgid "Needed a single revision" -msgstr "Cần một điểm xét duyệt đơn" +msgstr "Cần một lần cải biên đơn" msgid "" "git rev-parse --parseopt [<options>] -- [<args>...]\n" @@ -12049,7 +12191,7 @@ msgstr "không có tham chiếu nào như thế %s" #, c-format msgid "cannot handle more than %d rev." msgid_plural "cannot handle more than %d revs." -msgstr[0] "không thể xử lý nhiều hơn %d điểm xét duyệt." +msgstr[0] "không thể xử lý nhiều hơn %d lần cải biên." #, c-format msgid "'%s' is not a valid ref." @@ -12095,11 +12237,11 @@ msgstr "tham chiếu không tồn tại" msgid "failed to look up reference" msgstr "gặp lỗi khi tìm tham chiếu" -msgid "only show tags (can be combined with branches)" -msgstr "chỉ hiển thị thẻ (có thể tổ hợp cùng với nhánh)" +msgid "only show tags (can be combined with --branches)" +msgstr "chỉ hiển thị thẻ (có thể kết hợp với --branches)" -msgid "only show branches (can be combined with tags)" -msgstr "chỉ hiển thị đầu (có thể tổ hợp cùng với thẻ)" +msgid "only show branches (can be combined with --tags)" +msgstr "chỉ hiển thị đầu (có thể kết hợp với --tags)" msgid "check for reference existence without resolving" msgstr "kiểm tra tồn tại tham chiếu nhưng không phân giải" @@ -12151,6 +12293,10 @@ msgstr "gặp lỗi khi gỡ bỏ thư mục \"%s\"" msgid "failed to create directory for sparse-checkout file" msgstr "gặp lỗi khi tạo thư mục cho tập tin sparse-checkout" +#, c-format +msgid "unable to fdopen %s" +msgstr "không thể fdopen %s" + msgid "failed to initialize worktree config" msgstr "gặp lỗi khi khởi tạo cấu hình cây làm việc" @@ -12323,7 +12469,7 @@ msgstr "'%s' không phải là lần chuyển giao kiểu-stash" #, c-format msgid "Too many revisions specified:%s" -msgstr "Chỉ ra quá nhiều điểm xét duyệt: %s" +msgstr "Chỉ ra quá nhiều lần cải biên: %s" msgid "No stash entries found." msgstr "Không tìm thấy các mục tạm cất (stash) nào." @@ -12394,7 +12540,7 @@ msgid "failed to parse tree" msgstr "gặp lỗi khi đọc cây" msgid "failed to unpack trees" -msgstr "gặp lỗi khi tháo dỡ cây" +msgstr "gặp lỗi khi giải nén cây" msgid "include untracked files in the stash" msgstr "bao gồm các tập tin không được theo dõi trong stash" @@ -12605,8 +12751,8 @@ msgid "couldn't hash object from '%s'" msgstr "không thể băm đối tượng từ '%s'" #, c-format -msgid "unexpected mode %o\n" -msgstr "gặp chế độ không như mong chờ %o\n" +msgid "unexpected mode %o" +msgstr "gặp chế độ không rõ %o" msgid "use the commit stored in the index instead of the submodule HEAD" msgstr "hùng lần chuyển giao đã lưu trong chỉ mục thay cho HEAD mô-đun-con" @@ -12627,7 +12773,7 @@ msgstr "" "dẫn>]" msgid "could not fetch a revision for HEAD" -msgstr "không thể lấy về một điểm xem xét cho HEAD" +msgstr "không thể lấy về một lần cải biên cho HEAD" #, c-format msgid "Synchronizing submodule url for '%s'\n" @@ -12862,8 +13008,7 @@ msgstr "" #, c-format msgid "Unable to find current revision in submodule path '%s'" -msgstr "" -"Không tìm thấy điểm xét duyệt hiện hành trong đường dẫn mô-đun-con '%s'" +msgstr "Không tìm thấy lần cải biên hiện hành trong đường dẫn mô-đun-con '%s'" #, c-format msgid "Unable to fetch in submodule path '%s'" @@ -12871,7 +13016,7 @@ msgstr "Không thể lấy về trong đường dẫn mô-đun-con '%s'" #, c-format msgid "Unable to find %s revision in submodule path '%s'" -msgstr "Không tìm thấy điểm xét duyệt %s trong đường dẫn mô-đun-con '%s'" +msgstr "Không tìm thấy lần cải biên %s trong đường dẫn mô-đun-con '%s'" #, c-format msgid "Failed to recurse into submodule path '%s'" @@ -12902,8 +13047,7 @@ msgid "use the 'rebase' update strategy" msgstr "dùng chiến lược hòa trộn 'rebase'" msgid "create a shallow clone truncated to the specified number of revisions" -msgstr "" -"tạo một bản sao nông được cắt ngắn thành số lượng điểm xét duyệt đã cho" +msgstr "tạo một bản sao nông được cắt ngắn thành số lượng lần cải biên đã cho" msgid "parallel jobs" msgstr "công việc đồng thời" @@ -12915,7 +13059,7 @@ msgid "don't print cloning progress" msgstr "đừng in tiến trình nhân bản" msgid "disallow cloning into non-empty directory, implies --init" -msgstr "không cho phép nhân bản vào thư mục trống, ngụ ý --init" +msgstr "không cho phép nhân bản vào thư mục trống, ngầm chỉ định --init" msgid "" "git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] " @@ -13738,6 +13882,9 @@ msgstr "cài đặt chế độ theo dõi (xem git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "có khớp tên tên nhánh mới với một nhánh theo dõi máy chủ" +msgid "use relative paths for worktrees" +msgstr "dùng đường dẫn tương đối cho thư mục làm việc" + #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" msgstr "tùy chọn '%s', '%s' và '%s' không thể dùng cùng nhau" @@ -14009,6 +14156,25 @@ msgstr "không thể tạo '%s'" msgid "index-pack died" msgstr "index-pack đã chết" +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "Thư mục '%s' có ở trong chỉ mục, mà không phải dạng sparse?" + +msgid "corrupted cache-tree has entries not present in index" +msgstr "cache-tree bị hỏng, chứa mục không có trong chỉ mục" + +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s với cờ 0x%x không nên có trong cache-tree" + +#, c-format +msgid "bad subtree '%.*s'" +msgstr "subtree sai '%.*s'" + +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "cache-tree cho đường dẫn %.*s không khớp. Cần %s nhưng có %s" + msgid "terminating chunk id appears earlier than expected" msgstr "id chunk kết thúc sớm hơn bình thường" @@ -14053,6 +14219,9 @@ msgstr "Nhập một kho GNU Arch vào một kho Git" msgid "Create an archive of files from a named tree" msgstr "Tạo một kho nén các tập tin từ cây làm việc có tên" +msgid "Download missing objects in a partial clone" +msgstr "Tải về các đối tượng còn thiếu khi nhân bản một phần" + msgid "Use binary search to find the commit that introduced a bug" msgstr "Tìm kiếm dạng nhị phân để tìm ra lần chuyển giao nào đưa ra lỗi" @@ -14224,7 +14393,7 @@ msgid "Display help information about Git" msgstr "Hiển thị thông tin trợ giúp về Git" msgid "Run git hooks" -msgstr "Chạy các móc git" +msgstr "Chạy các hook git" msgid "Server side implementation of Git over HTTP" msgstr "Hỗ trợ phía máy chủ của Git qua HTTP" @@ -14590,7 +14759,7 @@ msgid "Git Repository Layout" msgstr "Bố cục kho Git" msgid "Specifying revisions and ranges for Git" -msgstr "Chỉ định điểm xét duyệt và vùng cho Git" +msgstr "Chỉ định lần cải biên và vùng cho Git" msgid "Mounting one repository inside another" msgstr "Gắn một kho chứa vào trong một cái khác" @@ -14774,7 +14943,7 @@ msgid_plural "Writing out commit graph in %d passes" msgstr[0] "Đang ghi ra đồ thị các lần chuyển giao trong lần %d" msgid "unable to open commit-graph chain file" -msgstr "không thể mở tập tin mắt xích đồ thị chuyển giao" +msgstr "không thể mở tập tin chain đồ thị chuyển giao" msgid "failed to rename base commit-graph file" msgstr "gặp lỗi khi đổi tên tập tin đồ-thị-chuyển-giao" @@ -14890,7 +15059,7 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "Hỗ trợ cho <GIT_DIR>/info/grafts đã không còn\n" "và sẽ bị xóa bỏ ở phiên bản Git tương lai.\n" @@ -14899,7 +15068,7 @@ msgstr "" "để chuyển đổi các graft thành các tham chiếu thay thế.\n" "\n" "Tắt lời nhắn này bằng cách chạy\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" #, c-format msgid "commit %s exists in commit-graph but not in the object database" @@ -15345,7 +15514,7 @@ msgstr "tham chiếu '%s' không chỉ đến một blob nào cả" #, c-format msgid "unable to resolve config blob '%s'" -msgstr "không thể phân giải điểm xét duyệt '%s'" +msgstr "không thể phân giải lần cải biên '%s'" msgid "unable to parse command-line config" msgstr "không thể đọc cấu hình dòng lệnh" @@ -15710,6 +15879,18 @@ msgstr "url không có lược đồ: %s" msgid "credential url cannot be parsed: %s" msgstr "không hiểu cú pháp giấy chứng thực url: %s" +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "timeout không hợp lệ '%s', cần số nguyên không âm" + +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "init-timeout không hợp lệ '%s', cần số nguyên không âm" + +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "max-connections không hợp lệ '%s', cần số nguyên" + msgid "in the future" msgstr "ở tương lai" @@ -15957,6 +16138,12 @@ msgstr "tham số cho %s không hợp lệ" msgid "invalid regex given to -I: '%s'" msgstr "đưa cho -I biểu thức chính quy không hợp lệ: '%s'" +msgid "-G requires a non-empty argument" +msgstr "-G cần một tham số" + +msgid "-S requires a non-empty argument" +msgstr "-S cần một tham số" + #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "gặp lỗi khi đọc đối số tùy chọn --submodule: '%s'" @@ -16405,6 +16592,20 @@ msgstr "đường dẫn không gian tên git \"%s\" sai" msgid "too many args to run %s" msgstr "quá nhiều tham số để chạy %s" +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Bạn đang muốn lấy về %s, nằm trong tập tin đồ-thị-chuyển-giao nhưng nằm " +"ngoài cơ sở dữ liệu đối tượng.\n" +"Nhiều khả năng kho chứa đã bị hỏng.\n" +"Nếu bạn đang cần sửa chữa lại kho chứa bằng cách lấy về đối tượng còn thiếu, " +"dùng 'git fetch --refetch' với đối tượng đó." + msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: cần danh sách shallow" @@ -16838,8 +17039,8 @@ msgid "" "given pattern contains NULL byte (via -f <file>). This is only supported " "with -P under PCRE v2" msgstr "" -"mẫu đã cho có chứa NULL byte (qua -f <file>). Điều này chỉ được hỗ trợ với -" -"P dưới PCRE v2" +"mẫu đã cho có chứa NULL byte (qua -f <file>). Điều này chỉ được hỗ trợ với " +"-P dưới PCRE v2" #, c-format msgid "'%s': unable to read %s" @@ -16983,10 +17184,10 @@ msgstr[0] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" -"Móc '%s' bị bỏ qua bởi vì nó không có cờ thực thi được.\n" -"Bạn có thể tắt cảnh báo này bằng 'git config advice.ignoredHook false'." +"Hook '%s' bị bỏ qua bởi vì nó không có cờ thực thi được.\n" +"Bạn có thể tắt cảnh báo này bằng 'git config set advice.ignoredHook false'." msgid "not a git repository" msgstr "không phải là kho git" @@ -17002,15 +17203,9 @@ msgstr "giá trị âm cho http.postBuffer; đặt thành mặc định là %d" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Điều khiển giao quyền không được hỗ trợ với cURL < 7.22.0" -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "Chốt khóa công không được hỗ trợ với cURL < 7.39.0" - msgid "Unknown value for http.proactiveauth" msgstr "không hiểu giá trị cho http.proactiveauth" -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE không được hỗ trợ với cURL < 7.44.0" - #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "" @@ -17164,20 +17359,23 @@ msgstr "" "Tiến trình git khác có lẽ đang chạy ở kho này, ví dụ\n" "một trình soạn thảo được mở bởi 'git commit'. Vui lòng chắc chắn\n" "rằng mọi tiến trình đã kết thúc và sau đó thử lại. Nếu vẫn lỗi,\n" -"một tiến trình git có lẽ đã crash khi thực hiện ở kho này trước đó:\n" +"một tiến trình git có lẽ đã crash ở kho này trước đó:\n" "gõ bỏ tập tin một cách thủ công để tiếp tục." #, c-format msgid "Unable to create '%s.lock': %s" msgstr "Không thể tạo '%s.lock': %s" +msgid "unable to create temporary object directory" +msgstr "không thể tạo thư mục đối tượng tạm thời" + #, c-format msgid "could not write loose object index %s" msgstr "không thể ghi tập tin đối tượng loose %s" #, c-format -msgid "failed to write loose object index %s\n" -msgstr "ghi chỉ mục đối tượng loose %s thất bại\n" +msgid "failed to write loose object index %s" +msgstr "ghi chỉ mục đối tượng loose %s thất bại" #, c-format msgid "unexpected line: '%s'" @@ -17193,9 +17391,13 @@ msgstr "phát hiện CRLF được trích dẫn" msgid "unable to format message: %s" msgstr "không thể định dạng thông điệp: %s" +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "marker-size không hợp lệ '%s', cần số nguyên" + #, c-format msgid "Failed to merge submodule %s (not checked out)" -msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (không checkout được)" +msgstr "Gặp lỗi khi hòa trộn mô-đun-con %s (không checkout)" #, c-format msgid "Failed to merge submodule %s (no merge base)" @@ -17701,7 +17903,7 @@ msgstr "gặp lỗi khi đọc bộ nhớ đệm" #, c-format msgid "failed to add packfile '%s'" -msgstr "gặp lỗi khi thêm tập tin gói '%s'" +msgstr "gặp lỗi khi thêm packfile '%s'" #, c-format msgid "failed to open pack-index '%s'" @@ -17729,6 +17931,17 @@ msgstr "không thể tải gói" msgid "could not open index for %s" msgstr "không thể mở chỉ mục cho %s" +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "không thể liên kết '%s' vào '%s'" + +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "gặp lỗi khi xóa multi-pack-index tại %s" + +msgid "cannot write incremental MIDX with bitmap" +msgstr "không thể ghi incremental MIDX với bitmap" + msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "bỏ qua multi-pack-index sẵn có; tổng kiểm không khớp" @@ -17737,7 +17950,7 @@ msgstr "Đang thêm tập tin gói từ multi-pack-index" #, c-format msgid "unknown preferred pack: '%s'" -msgstr "không hiểu \"preferred pack\": %s" +msgstr "không hiểu preferred pack: %s" #, c-format msgid "cannot select preferred pack %s with no objects" @@ -17749,19 +17962,31 @@ msgstr "đã không thấy tập tin gói %s để xóa" #, c-format msgid "preferred pack '%s' is expired" -msgstr "\"preferred pack\" '%s' đã hết hạn" +msgstr "preferred pack '%s' đã hết hạn" msgid "no pack files to index." msgstr "không có tập tin gói để đánh chỉ mục." msgid "refusing to write multi-pack .bitmap without any objects" -msgstr "từ chối ghi 'multi-pack bitmap' mà không có bất kỳ đối tượng nào" +msgstr "từ chối ghi multi-pack bitmap mà không có bất kỳ đối tượng nào" + +msgid "unable to create temporary MIDX layer" +msgstr "không thể tạo lớp MIDX tạm thời" msgid "could not write multi-pack bitmap" -msgstr "không thể ghi 'multi-pack bitmap'" +msgstr "không thể ghi multi-pack bitmap" + +msgid "unable to open multi-pack-index chain file" +msgstr "không thể mở tập tin chain multi-pack-index" + +msgid "unable to rename new multi-pack-index layer" +msgstr "gặp lỗi khi đổi tên lớp multi-pack-index" msgid "could not write multi-pack-index" -msgstr "không thể ghi 'multi-pack-index'" +msgstr "không thể ghi multi-pack-index" + +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "không thể hết hạn gói từ incremental multi-pack-index" msgid "Counting referenced objects" msgstr "Đang đếm các đối tượng được tham chiếu" @@ -17769,6 +17994,9 @@ msgstr "Đang đếm các đối tượng được tham chiếu" msgid "Finding and deleting unreferenced packfiles" msgstr "Đang tìm và xóa các gói không được tham chiếu" +msgid "cannot repack an incremental multi-pack-index" +msgstr "không thể repack incremental multi-pack-index" + msgid "could not start pack-objects" msgstr "không thể khởi chạy pack-objects" @@ -17825,6 +18053,27 @@ msgstr "tập tin đồ thị multi-pack-index %s quá nhỏ" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "các tên gói multi-pack-index không đúng thứ tự: '%s' trước '%s'" +msgid "multi-pack-index chain file too small" +msgstr "tập tin chain multi-pack-index quá nhỏ" + +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "số pack trong base MIDX quá lớn: %<PRIuMAX>" + +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "số đối tượng trong base MIDX quá lớn: %<PRIuMAX>" + +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "multi-pack-index chain không hợp lệ: dòng '%s' không phải là mã băm" + +msgid "unable to find all multi-pack index files" +msgstr "không thể tìm thấy tất cả các tập tin multi-pack index" + +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "vị trí đối tượng MIDX không hợp lệ. MIDX có vẻ như đã bị hỏng" + #, c-format msgid "bad pack-int-id: %u (%u total packs)" msgstr "pack-int-id sai: %u (%u các gói tổng)" @@ -17842,10 +18091,6 @@ msgstr "multi-pack-index lưu trữ một offset 64-bít, nhưng off_t là quá msgid "multi-pack-index large offset out of bounds" msgstr "multi-pack-index large offset nằm ngoài biên" -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "gặp lỗi khi xóa multi-pack-index tại %s" - msgid "multi-pack-index file exists, but failed to parse" msgstr "đã có tập tin multi-pack-index, nhưng gặp lỗi khi đọc cú pháp" @@ -18055,10 +18300,22 @@ msgstr "đối tượng đã đóng gói %s (được lưu trong %s) bị hỏng msgid "missing mapping of %s to %s" msgstr "thiếu ánh xạ %s sang %s" +#, c-format +msgid "unable to open %s" +msgstr "không thể mở %s" + +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "tập tin '%s' và '%s' có nội dung khác nhau" + #, c-format msgid "unable to write file %s" msgstr "không thể ghi tập tin %s" +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "không thể ghi vào tập tin biến mất liên tục %s" + #, c-format msgid "unable to set permission to '%s'" msgstr "không thể đặt quyền thành '%s'" @@ -18103,7 +18360,7 @@ msgstr "deflateEnd trên đối tượng stream gặp lỗi (%d)" #, c-format msgid "unable to create directory %s" -msgstr "tạo thư mục \"%s\" gặp lỗi" +msgstr "tạo thư mục %s gặp lỗi" #, c-format msgid "cannot read object for %s" @@ -18140,10 +18397,6 @@ msgstr "%s: kiểu tập tin không được hỗ trợ" msgid "%s is not a valid '%s' object" msgstr "%s không phải là một đối tượng '%s' hợp lệ" -#, c-format -msgid "unable to open %s" -msgstr "không thể mở %s" - #, c-format msgid "hash mismatch for %s (expected %s)" msgstr "mã băm không khớp cho %s (cần %s)" @@ -18245,7 +18498,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Git thường không bao giờ tạo tham chiếu kết thúc với 40 ký tự hex\n" "bởi vì nó sẽ bị bỏ qua khi bạn chỉ định 40 ký tự hex. Những tham chiếu\n" @@ -18254,8 +18507,8 @@ msgstr "" " git switch -c $br $(git rev-parse ...)\n" "\n" "với \"$br\" không hiểu lý do vì sao rỗng và tạo ra tham chiếu 40-hex.\n" -" Xin hãy kiểm tra những tham chiếu này và xóa chúng đi nếu cần. Tắt\n" -"lời nhắn này bằng cách chạy lệnh \"git config advice.objectNameWarning " +"Xin hãy kiểm tra những tham chiếu này và xóa chúng đi nếu cần. Tắt\n" +"lời nhắn này bằng cách chạy lệnh \"git config set advice.objectNameWarning " "false\"" #, c-format @@ -18412,13 +18665,6 @@ msgstr "bitmap multi-pack thiếu chỉ mục để dành cần thiết" msgid "could not open pack %s" msgstr "không thể mở gói '%s'" -msgid "could not determine MIDX preferred pack" -msgstr "không thể xác định gói MIDX ưa dùng" - -#, c-format -msgid "preferred pack (%s) is invalid" -msgstr "preferred pack (%s) không hợp lệ" - msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "bảng tìm kiếm bitmap bị hỏng: vị trí bộ ba nằm ngoài chỉ mục" @@ -18531,7 +18777,7 @@ msgstr "checksum không hợp lệ" #, c-format msgid "invalid rev-index position at %<PRIu64>: %<PRIu32> != %<PRIu32>" -msgstr "vị trí mục xét duyệt không hợp lệ %<PRIu64>: %<PRIu32> != %<PRIu32>" +msgstr "vị trí mục cải biên không hợp lệ %<PRIu64>: %<PRIu32> != %<PRIu32>" msgid "multi-pack-index reverse-index chunk is the wrong size" msgstr "chunk chỉ mục ngược của chỉ mục đa gói có kích thước sai" @@ -18629,6 +18875,52 @@ msgstr "không hiểu tùy chọn '%c'" msgid "unknown non-ascii option in string: `%s'" msgstr "không hiểu tùy chọn non-ascii trong chuỗi: '%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#, c-format +msgid " <%s>" +msgstr " <%s>" + msgid "..." msgstr "..." @@ -18715,6 +19007,21 @@ msgstr "sai giá trị kiểu boolean của cấu hình '%s' cho '%s'" msgid "failed to parse %s" msgstr "gặp lỗi khi đọc cú pháp %s" +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "gặp lỗi khi duyệt nhánh của cây %s: không tìm thấy" + +#, c-format +msgid "failed to find object %s" +msgstr "gặp lỗi khi tìm đối tượng '%s'." + +#, c-format +msgid "failed to find tag %s" +msgstr "gặp lỗi khi tìm thẻ %s" + +msgid "failed to setup revision walk" +msgstr "gặp lỗi khi thiết lập duyệt lần cải biên" + #, c-format msgid "Could not make %s writable by group" msgstr "Không thể làm %s được ghi bởi nhóm" @@ -18859,6 +19166,22 @@ msgstr "tên máy chủ promisor không thể bắt đầu bằng '/': %s" msgid "could not fetch %s from promisor remote" msgstr "không thể tải %s từ máy chủ promisor" +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "có máy chủ '%s' nhưng với url '%s' thay vì '%s'" + +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "không hiểu giá trị '%s' cho cho cấu hình '%s'" + +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "không hiểu phần '%s' từ thông tin máy chủ" + +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "không tìm thấy accepted promisor remote '%s'" + msgid "object-info: expected flush after arguments" msgstr "object-info: cần đẩy dữ liệu lên đĩa sau các tham số" @@ -19079,10 +19402,10 @@ msgid "broken index, expect %s in %s, got %s" msgstr "chỉ mục bị hỏng, cần %s trong %s, nhưng lại có %s" msgid "cannot write split index for a sparse index" -msgstr "không thể ghi chỉ mục chia tách cho \"sparse index\"" +msgstr "không thể ghi chỉ mục chia tách cho sparse index" msgid "failed to convert to a sparse-index" -msgstr "gặp lỗi khi chuyển đổi sang \"sparse-index\"" +msgstr "gặp lỗi khi chuyển đổi sang sparse-index" #, c-format msgid "unable to open git dir: %s" @@ -19351,6 +19674,10 @@ msgstr "cần giá trị độ rộng dương với atom %%(align)" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "cần định dạng: %%(ahead-behind:<committish>)" +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "cần định dạng: %%(is-base:<committish>)" + #, c-format msgid "malformed field name: %.*s" msgstr "tên trường sai quy cách: %.*s" @@ -19525,17 +19852,25 @@ msgstr "nhật ký cho tham chiếu %s kết thúc bất ngờ trên %s" msgid "log for %s is empty" msgstr "nhật ký cho %s trống rỗng" -msgid "refusing to force and skip creation of reflog" -msgstr "từ chối bỏ qua việc tạo log tham chiếu" - #, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "từ chối cập nhật tham chiếu với tên sai '%s'" +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "từ chối cập nhật reflog cho tham chiếu ảo '%s'" #, c-format msgid "refusing to update pseudoref '%s'" msgstr "từ chối cập nhật tham chiếu ảo '%s'" +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "từ chối cập nhật reflog với tên sai '%s'" + +#, c-format +msgid "refusing to update ref with bad name '%s'" +msgstr "từ chối cập nhật tham chiếu với tên sai '%s'" + +msgid "refusing to force and skip creation of reflog" +msgstr "từ chối bỏ qua việc tạo reflog" + #, c-format msgid "update_ref failed for ref '%s': %s" msgstr "update_ref bị lỗi cho ref '%s': %s" @@ -19548,7 +19883,7 @@ msgid "ref updates forbidden inside quarantine environment" msgstr "cập nhật tham chiếu bị cấm trong môi trường kiểm tra" msgid "ref updates aborted by hook" -msgstr "các cập nhật tham chiếu bị huỷ bỏ bởi móc" +msgstr "các cập nhật tham chiếu bị huỷ bỏ bởi hook" #, c-format msgid "'%s' exists; cannot create '%s'" @@ -19585,6 +19920,17 @@ msgstr "" "không thể lock tham chiếu '%s': cần tham chiếu mềm tới '%s': nhưng lại là " "tham chiếu thường" +#, c-format +msgid "cannot read ref file '%s'" +msgstr "không thể đọc tập tin ref '%s'" + +#, c-format +msgid "cannot open directory %s" +msgstr "không thể mở thư mục %s" + +msgid "Checking references consistency" +msgstr "Đang kiểm tra tính nhất quán các tham chiếu" + #, c-format msgid "refname is dangerous: %s" msgstr "tên tham chiếu không an toàn: %s" @@ -19656,6 +20002,14 @@ msgstr "tên tham chiếu %s là tham chiếu biểu trưng, không hỗ trợ s msgid "invalid refspec '%s'" msgstr "refspec không hợp lệ '%s'" +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "giá trị '%s' không có '*'" + +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "thay thế '%s' không có '*'" + #, c-format msgid "invalid quoting in push-option value: '%s'" msgstr "sai trích dẫn trong giá trị push-option :'%s'" @@ -19775,6 +20129,27 @@ msgstr "remote-curl: đã cố gắng fetch mà không có kho nội bộ" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl: không hiểu lệnh '%s' từ git" +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"đang đọc máy chủ từ \"%s/%s\", đã được đề cử để loại bỏ.\n" +"Nếu bạn vẫn còn sử dụng thư mục \"remotes\", chúng tôi khuyên bạn\n" +"hãy chuyển đổi sang sử dụng máy chủ qua tập tin cấu hình:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"Nếu bạn không thể đổi, hãy cho chúng tôi biết tại sao bạn cần nó\n" +"bằng cách gửi e-mail đến <git@vger.kernel.org>." + #, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "cấu hình viết tắt máy chủ không thể bắt đầu bằng '/': %s" @@ -19785,6 +20160,10 @@ msgstr "đã đưa ra nhiều hơn một gói nhận về, đang sử dụng cá msgid "more than one uploadpack given, using the first" msgstr "đã đưa ra nhiều hơn một gói tải lên, đang sử dụng cái đầu tiên" +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "bỏ qua giá trị không chấp nhận cho followRemoteHEAD '%s'" + #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "không chấp nhận giá trị transfer.credentialsInUrl: '%s'" @@ -19805,14 +20184,6 @@ msgstr "%s thường theo dõi %s, không phải %s" msgid "%s tracks both %s and %s" msgstr "%s theo dõi cả %s và %s" -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "khóa '%s' của mẫu k có '*'" - -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "giá trị '%s' của mẫu k có '*'" - #, c-format msgid "src refspec %s does not match any" msgstr "refspec (đặc tả tham chiếu) nguồn %s không khớp bất kỳ cái gì" @@ -20086,7 +20457,7 @@ msgid "update the index with reused conflict resolution if possible" msgstr "cập nhật chỉ mục với phân giải xung đột dùng lại nếu được" msgid "could not determine HEAD revision" -msgstr "không thể dò tìm điểm xét duyệt HEAD" +msgstr "không thể dò tìm lần cải biên HEAD" #, c-format msgid "failed to find tree of %s" @@ -20144,7 +20515,7 @@ msgstr "không thể tạo tuyến trình async: %s" #, c-format msgid "'%s' does not exist" -msgstr "\"%s\" không tồn tại" +msgstr "'%s' không tồn tại" #, c-format msgid "could not switch to '%s'" @@ -20212,12 +20583,15 @@ msgstr "chỉ siêu dữ liệu tải về cho nhánh mà sẽ được checkout msgid "create repository within 'src' directory" msgstr "tạo kho chứa trong thư mục 'src'" +msgid "specify if tags should be fetched during clone" +msgstr "có nên lấy về thẻ khi nhân bản" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <nhánh-chính>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20235,6 +20609,10 @@ msgstr "gặp lỗi khi lấy nhánh mặc định cho '%s'" msgid "could not configure remote in '%s'" msgstr "không thể cấu hình máy chủ trong '%s'" +#, c-format +msgid "could not disable tags in '%s'" +msgstr "không thể vô hiệu thẻ trong '%s'" + #, c-format msgid "could not configure '%s'" msgstr "không thể cấu hình '%s'" @@ -20542,7 +20920,7 @@ msgstr "" " git rebase --continue\n" msgid "'prepare-commit-msg' hook failed" -msgstr "móc 'prepare-commit-msg' bị lỗi" +msgstr "hook 'prepare-commit-msg' bị lỗi" msgid "" "Your name and email address were configured automatically based\n" @@ -21218,10 +21596,10 @@ msgid "" "Use '--' to separate paths from revisions, like this:\n" "'git <command> [<revision>...] -- [<file>...]'" msgstr "" -"tham số chưa rõ ràng '%s': chưa biết điểm xét duyệt hay đường dẫn không " -"trong cây làm việc.\n" -"Dùng '--' để ngăn cách các đường dẫn khỏi điểm xét duyệt, như thế này:\n" -"'git <lệnh> [<điểm xét duyệt>...] -- [<tập tin>...]'" +"tham số chưa rõ ràng '%s': chưa biết lần cải biên hay đường dẫn không trong " +"cây làm việc.\n" +"Dùng '--' để ngăn cách các đường dẫn khỏi lần cải biên, như thế này:\n" +"'git <lệnh> [<lần cải biên>...] -- [<tập tin>...]'" #, c-format msgid "option '%s' must come before non-option arguments" @@ -21233,9 +21611,9 @@ msgid "" "Use '--' to separate paths from revisions, like this:\n" "'git <command> [<revision>...] -- [<file>...]'" msgstr "" -"tham số chưa rõ ràng '%s': cả điểm xem xét và tên tập tin.\n" -"Dùng '--' để ngăn cách các đường dẫn khỏi điểm xem xét, như thế này:\n" -"'git <lệnh> [<điểm xem xét>...] -- [<tập tin>...]'" +"tham số chưa rõ ràng '%s': cả lần cải biên và tên tập tin.\n" +"Dùng '--' để ngăn cách các đường dẫn khỏi lần cải biên, như thế này:\n" +"'git <lệnh> [<lần cải biên>...] -- [<tập tin>...]'" msgid "unable to set up work tree using invalid config" msgstr "không thể thiết lập thư mục làm việc với cấu hình không hợp lệ" @@ -21300,6 +21678,10 @@ msgstr "không thể quay lại thư mục làm việc hiện hành" msgid "failed to stat '%*s%s%s'" msgstr "gặp lỗi khi stat'%*s%s%s'" +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' không phải đường dẫn tuyệt đối" + #, c-format msgid "" "detected dubious ownership in repository at '%s'\n" @@ -21693,6 +22075,27 @@ msgstr "dọn cây nhớ tạm trước mỗi chu kỳ" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "số mục cần huỷ trong câu nhớ tạm (mặc định 0)" +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <tuỳ chọn> -- <tuỳ chọn cải biên>" + +msgid "toggle inclusion of blob objects" +msgstr "bao gồm các đối tượng blob" + +msgid "toggle inclusion of commit objects" +msgstr "bao gồm các đối tượng chuyển giao" + +msgid "toggle inclusion of tag objects" +msgstr "bao gồm các đối tượng thẻ" + +msgid "toggle inclusion of tree objects" +msgstr "bao gồm các đối tượng cây" + +msgid "toggle pruning of uninteresting paths" +msgstr "lược bỏ những đường dẫn ít ý nghĩa" + +msgid "read a pattern list over stdin" +msgstr "đọc các mẫu từ stdin" + #, c-format msgid "commit %s is not marked reachable" msgstr "lần chuyển giao %s chưa được đánh dấu là tiếp cận được" @@ -21700,6 +22103,9 @@ msgstr "lần chuyển giao %s chưa được đánh dấu là tiếp cận đư msgid "too many commits marked reachable" msgstr "có quá nhiều lần chuyển giao được đánh dấu là tiếp cận được" +msgid "could not determine MIDX preferred pack" +msgstr "không thể xác định gói MIDX ưa dùng" + msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<các tùy chọn>]" @@ -21762,9 +22168,27 @@ msgstr "thẻ bài" msgid "command token to send to the server" msgstr "thẻ bài lệnh để gửi lên cho máy chủ" +msgid "unit-test [<options>]" +msgstr "unit-test [<các tùy chọn>]" + +msgid "immediately exit upon the first failed test" +msgstr "thoát ngay khi gặp test thất bại" + +msgid "suite[::test]" +msgstr "suite[::test]" + +msgid "run only test suite or individual test <suite[::test]>" +msgstr "chạy riêng test suite hoặc test <suite[::test]>" + +msgid "suite" +msgstr "suite" + +msgid "exclude test suite <suite>" +msgstr "loại trừ test suite <suite>" + #, c-format msgid "running trailer command '%s' failed" -msgstr "chạy lệnh kéo theo '%s' gặp lỗi" +msgstr "chạy lệnh trailer '%s' gặp lỗi" #, c-format msgid "unknown value '%s' for key '%s'" @@ -21772,7 +22196,7 @@ msgstr "không hiểu giá trị '%s' cho khóa '%s'" #, c-format msgid "empty trailer token in trailer '%.*s'" -msgstr "thẻ thừa trống rỗng trong phần thừa '%.*s'" +msgstr "thẻ trailer trống rỗng trong phần trailer '%.*s'" msgid "full write to remote helper failed" msgstr "ghi đầy đủ lên helper máy chủ gặp lỗi" @@ -22316,6 +22740,10 @@ msgstr "lỗi: " msgid "warning: " msgstr "cảnh báo: " +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() gặp lỗi '%s' (%d)\n" + msgid "Fetching objects" msgstr "Đang lấy về các đối tượng" @@ -22348,6 +22776,9 @@ msgstr "tập tin .git bị hỏng" msgid ".git file incorrect" msgstr "tập tin .git không chính xác" +msgid ".git file absolute/relative path mismatch" +msgstr "đường dẫn tương đối/tuyệt đối đến file .git không khớp" + msgid "not a valid path" msgstr "không phải là một đường dẫn hợp lệ" @@ -22363,6 +22794,9 @@ msgstr "không thể định vị kho chứa; tập tin .git bị hỏng" msgid "gitdir unreadable" msgstr "gitdir không thể đọc được" +msgid "gitdir absolute/relative path mismatch" +msgstr "đường dẫn tương đối/tuyệt đối đến gitdir không khớp" + msgid "gitdir incorrect" msgstr "gitdir không chính xác" @@ -22397,6 +22831,13 @@ msgstr "không thể bỏ đặt %s trong '%s'" msgid "failed to set extensions.worktreeConfig setting" msgstr "gặp lỗi khi đặt cài đặt extensions.worktreeConfig" +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"không thể nâng cấp định định dạng kho chứa để hỗ trợ cây làm việc tương đối" + +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "gặp lỗi khi đặt cài đặt extensions.relativeWorktrees" + #, c-format msgid "could not setenv '%s'" msgstr "không thể setenv '%s'" @@ -22962,6 +23403,9 @@ msgstr "'%s.final' chứa emal đã soạn thảo.\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases không tương thích với các tùy chọn khác\n" +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases và --translate-aliases không tương thích với nhau\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -23257,3 +23701,21 @@ msgstr "Bỏ qua %s với hậu tố sao lưu '%s'.\n" #, perl-format msgid "Do you really want to send %s? [y|N]: " msgstr "Bạn có thực sự muốn gửi %s? [y|N](có/KHÔNG): " + +#, c-format +#~ msgid "Could not find remote branch %s to clone." +#~ msgstr "Không tìm thấy nhánh máy chủ %s để nhân bản (clone)." + +#, c-format +#~ msgid "merging cannot continue; got unclean result of %d" +#~ msgstr "không thể tiếp tục hoà trộn; kết quả không hoàn toàn %d" + +#~ msgid "git repack [<options>]" +#~ msgstr "git repack [<các tùy chọn>]" + +#~ msgid "--onto and --advance are incompatible" +#~ msgstr "--onto và --advance xung khắc" + +#, c-format +#~ msgid "key '%s' of pattern had no '*'" +#~ msgstr "khóa '%s' của mẫu k có '*'" diff --git a/po/zh_CN.po b/po/zh_CN.po index 91b8b79de8ec02..5cde4011e750ce 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -93,6 +93,7 @@ # pack index | 包索引 # packfile | 包文件 # parent | 父提交 +# partial clone | 部分克隆 # patch | 补丁 # pathspec | 路径规格 # pattern | 模式 @@ -154,8 +155,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-27 22:28+0800\n" -"PO-Revision-Date: 2024-07-28 19:52+0800\n" +"POT-Creation-Date: 2025-03-09 20:34+0800\n" +"PO-Revision-Date: 2025-03-12 14:47+0800\n" "Last-Translator: Teng Long <dyroneteng@gmail.com>\n" "Language-Team: GitHub <https://github.com/dyrone/git/>\n" "Language: zh_CN\n" @@ -784,7 +785,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - 维持该块未决状态,查看下一个未决块\n" @@ -795,7 +796,7 @@ msgstr "" "/ - 查找和给定正则表达式匹配的块\n" "s - 拆分当前块为更小的块\n" "e - 手动编辑当前块\n" -"p - 显示当前块\n" +"p - 显示当前块, 'P' 使用分页器\n" "? - 显示帮助\n" #: add-patch.c @@ -886,10 +887,10 @@ msgstr "只有二进制文件被修改。" #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"使用 \"git config advice.%s false\" 来关闭此消息" +"使用 \"git config set advice.%s false\" 来关闭此消息" #: advice.c #, c-format @@ -1613,6 +1614,18 @@ msgstr "还应用此补丁(与 --stat/--summary/--check 选项同时使用)" msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "尝试三路合并,如果失败则回落至正常补丁模式" +#: apply.c builtin/merge-file.c +msgid "for conflicts, use our version" +msgstr "如果冲突,使用我们的版本" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use their version" +msgstr "如果冲突,使用他们的版本" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use a union version" +msgstr "如果冲突,使用联合版本" + #: apply.c msgid "build a temporary index based on embedded index information" msgstr "创建一个临时索引基于嵌入的索引信息" @@ -1674,6 +1687,10 @@ msgstr "为所有文件名前添加 <根目录>" msgid "don't return error for empty patches" msgstr "对空的补丁不返回错误" +#: apply.c +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours、--theirs 和 --union 需要 --3way" + #: archive-tar.c archive-zip.c #, c-format msgid "cannot stream blob %s" @@ -1762,6 +1779,11 @@ msgstr "不是一个有效的对象名:%s" msgid "not a tree object: %s" msgstr "不是一个树对象:%s" +#: archive.c +#, c-format +msgid "failed to unpack tree object %s" +msgstr "无法解包树对象 %s" + #: archive.c #, c-format msgid "File not found: %s" @@ -1878,7 +1900,7 @@ msgstr "选项 '%s' 需要 '%s'" msgid "Unexpected option --output" msgstr "未知参数 --output" -#: archive.c +#: archive.c t/unit-tests/unit-test.c #, c-format msgid "extra command line parameter '%s'" msgstr "额外的命令行参数:'%s'" @@ -1937,7 +1959,7 @@ msgstr "忽略过大的 gitattributes 数据对象 '%s'" #: attr.c msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo" -msgstr "无法在没有存储库的情况下使用 --attr-source 或 GIT_ATTR_SOURCE" +msgstr "无法在没有仓库的情况下使用 --attr-source 或 GIT_ATTR_SOURCE" #: attr.c msgid "bad --attr-source or GIT_ATTR_SOURCE" @@ -1949,7 +1971,7 @@ 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 +#: builtin/pack-objects.c combine-diff.c object-file.c rerere.c #, c-format msgid "unable to read %s" msgstr "不能读 %s" @@ -2086,7 +2108,7 @@ msgstr "--contents 和 --reverse 不能混用。" msgid "--reverse and --first-parent together require specified latest commit" msgstr "--reverse 和 --first-parent 共用,需要指定最新的提交" -#: blame.c builtin/commit.c builtin/log.c builtin/merge.c +#: blame.c builtin/bisect.c builtin/commit.c builtin/log.c builtin/merge.c #: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c #: remote.c sequencer.c submodule.c msgid "revision walk setup failed" @@ -2333,7 +2355,7 @@ msgstr "演习" #: builtin/add.c builtin/check-ignore.c builtin/commit.c #: builtin/count-objects.c builtin/fsck.c builtin/log.c builtin/mv.c -#: builtin/read-tree.c +#: builtin/read-tree.c builtin/refs.c msgid "be verbose" msgstr "冗长输出" @@ -2813,7 +2835,7 @@ msgstr "n" #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c #: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c #: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c -#: builtin/tag.c builtin/verify-tag.c +#: builtin/submodule--helper.c builtin/tag.c builtin/verify-tag.c msgid "format" msgstr "格式" @@ -2941,6 +2963,22 @@ msgstr "git archive:协议错误" msgid "git archive: expected a flush" msgstr "git archive:应有一个 flush 包" +#: builtin/backfill.c +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +#: builtin/backfill.c +msgid "problem loading sparse-checkout" +msgstr "加载稀疏检出时出现问题" + +#: builtin/backfill.c +msgid "Minimum number of objects to request at a time" +msgstr "单次请求的最少对象数量" + +#: builtin/backfill.c +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "将缺少的对象限制在当前的稀疏检出中" + #: builtin/bisect.c msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" @@ -3107,10 +3145,6 @@ msgstr "" "命令 'git bisect terms' 的参数 %s 无效。\n" "支持的选项有:--term-good|--term-old 和 --term-bad|--term-new。" -#: builtin/bisect.c -msgid "revision walk setup failed\n" -msgstr "版本遍历设置失败\n" - #: builtin/bisect.c #, c-format msgid "could not open '%s' for appending" @@ -3364,7 +3398,7 @@ msgstr "显示作者的邮箱而不是名字(默认:关闭)" msgid "ignore whitespace differences" msgstr "忽略空白差异" -#: builtin/blame.c builtin/log.c +#: builtin/blame.c builtin/clone.c builtin/log.c msgid "rev" msgstr "版本" @@ -3786,8 +3820,8 @@ msgstr "HEAD 没有位于 /refs/heads 之下!" #: builtin/branch.c msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" +"branch with --recurse-submodules can only be used if " +"submodule.propagateBranches is enabled" msgstr "" "带有 --recurse-submodules 的分支只能在 submodule.propagateBranches 启用时使用" @@ -3874,11 +3908,6 @@ msgstr "不再支持选项 '--set-upstream'。请使用 '--track' 或 '--set-ups msgid "git version:\n" msgstr "git 版本:\n" -#: builtin/bugreport.c -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() 失败,错误为 '%s'(%d)\n" - #: builtin/bugreport.c msgid "compiler info: " msgstr "编译器信息:" @@ -4337,9 +4366,16 @@ msgid "also read contacts from stdin" msgstr "还从标准输入读取联系地址" #: builtin/check-mailmap.c -#, c-format -msgid "unable to parse contact: %s" -msgstr "不能解析联系地址:%s" +msgid "read additional mailmap entries from file" +msgstr "从文件中读取附加邮件映射条目" + +#: builtin/check-mailmap.c +msgid "blob" +msgstr "数据对象" + +#: builtin/check-mailmap.c +msgid "read additional mailmap entries from blob" +msgstr "从数据对象中读取附加邮件映射条目" #: builtin/check-mailmap.c msgid "no contacts specified" @@ -4757,6 +4793,11 @@ msgstr "路径不能和切换分支同时使用" msgid "'%s' cannot be used with switching branches" msgstr "'%s' 不能和切换分支同时使用" +#: builtin/checkout.c +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "'%s' 需要路径进行检出" + #: builtin/checkout.c #, c-format msgid "'%s' cannot be used with '%s'" @@ -4785,7 +4826,7 @@ msgstr "未知的冲突风格 '%s'" msgid "perform a 3-way merge with the new branch" msgstr "和新的分支执行三方合并" -#: builtin/checkout.c builtin/log.c parse-options.h +#: builtin/checkout.c builtin/log.c builtin/range-diff.c parse-options.h msgid "style" msgstr "风格" @@ -4814,8 +4855,8 @@ msgid "update ignored files (default)" msgstr "更新忽略的文件(默认)" #: builtin/checkout.c -msgid "do not check if another worktree is holding the given ref" -msgstr "不检查指定的引用是否被其他工作区所占用" +msgid "do not check if another worktree is using this branch" +msgstr "不检查其他工作区是否正在使用该分支" #: builtin/checkout.c msgid "checkout our version for unmerged files" @@ -5105,8 +5146,112 @@ msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "clean.requireForce 设置为 true 且未提供 -f 选项:拒绝执行清理动作" #: builtin/clone.c -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<选项>] [--] <仓库> [<路径>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info: 不能为 '%s' 添加一个备用:%s\n" + +#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c +#, c-format +msgid "failed to stat '%s'" +msgstr "无法对 '%s' 调用 stat" + +#: builtin/clone.c +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s 存在且不是一个目录" + +#: builtin/clone.c +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "'%s' 为符号链接,拒绝用 --local 克隆" + +#: builtin/clone.c +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "无法在 '%s' 上启动迭代器" + +#: builtin/clone.c +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "符号链接 '%s' 存在,拒绝用 --local 克隆" + +#: builtin/clone.c compat/precompose_utf8.c +#, c-format +msgid "failed to unlink '%s'" +msgstr "无法删除 '%s'" + +#: builtin/clone.c +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "无法检查 '%s' 处的硬链接" + +#: builtin/clone.c +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "硬链接与 '%s' 处的来源不同" + +#: builtin/clone.c +#, c-format +msgid "failed to create link '%s'" +msgstr "无法创建链接 '%s'" + +#: builtin/clone.c +#, c-format +msgid "failed to copy file to '%s'" +msgstr "无法拷贝文件至 '%s'" + +#: builtin/clone.c refs/files-backend.c +#, c-format +msgid "failed to iterate over '%s'" +msgstr "无法在 '%s' 上迭代" + +#: builtin/clone.c +#, c-format +msgid "done.\n" +msgstr "完成。\n" + +#: builtin/clone.c +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"克隆成功,但是检出失败。\n" +"您可以通过 'git status' 检查哪些已被检出,然后使用命令\n" +"'git restore --source=HEAD :/' 重试\n" + +#: builtin/clone.c fetch-pack.c +msgid "remote did not send all necessary objects" +msgstr "远程没有发送所有必需的对象" + +#: builtin/clone.c +#, c-format +msgid "unable to update %s" +msgstr "不能更新 %s" + +#: builtin/clone.c +msgid "failed to initialize sparse-checkout" +msgstr "无法初始化稀疏检出" + +#: builtin/clone.c +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "远程 HEAD 指向一个不存在的引用,无法检出" + +#: builtin/clone.c +msgid "unable to checkout working tree" +msgstr "不能检出工作区" + +#: builtin/clone.c +msgid "unable to write parameters to config file" +msgstr "无法将参数写入配置文件" + +#: builtin/clone.c +msgid "cannot repack to clean up" +msgstr "无法执行 repack 来清理" + +#: builtin/clone.c +msgid "cannot unlink temporary alternates file" +msgstr "无法删除临时的备用文件" #: builtin/clone.c msgid "don't clone shallow repository" @@ -5178,6 +5323,10 @@ msgstr "使用 <名称> 而不是 'origin' 去跟踪上游" msgid "checkout <branch> instead of the remote's HEAD" msgstr "检出 <分支> 而不是远程 HEAD" +#: builtin/clone.c +msgid "clone single revision <rev> and check out" +msgstr "克隆单个版本 <版本> 并检出" + #: builtin/clone.c msgid "path to git-upload-pack on the remote" msgstr "远程 git-upload-pack 路径" @@ -5194,22 +5343,21 @@ msgstr "创建一个指定深度的浅克隆" 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 "版本" +#: builtin/clone.c builtin/fetch.c builtin/pull.c +msgid "ref" +msgstr "引用" #: builtin/clone.c builtin/fetch.c builtin/pull.c -msgid "deepen history of shallow clone, excluding rev" -msgstr "深化浅克隆的历史,除了特定版本" +msgid "deepen history of shallow clone, excluding ref" +msgstr "深化浅克隆的历史,除了给定的引用" #: builtin/clone.c builtin/submodule--helper.c msgid "clone only one branch, HEAD or --branch" msgstr "只克隆一个分支、HEAD 或 --branch" #: builtin/clone.c -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "不要克隆任何标签,并且后续获取操作也不下载它们" +msgid "clone tags, and make later fetches not to follow them" +msgstr "克隆标签,并在后续获取时不跟随它们" #: builtin/clone.c msgid "any cloned submodules will be shallow" @@ -5223,7 +5371,7 @@ msgstr "git目录" msgid "separate git dir from working tree" msgstr "git目录和工作区分离" -#: builtin/clone.c builtin/init-db.c +#: builtin/clone.c builtin/init-db.c builtin/submodule--helper.c msgid "specify the reference format to use" msgstr "指定要使用的引用格式" @@ -5266,117 +5414,8 @@ msgid "a URI for downloading bundles before fetching from origin remote" msgstr "用于在从 origin 远程获取之前下载归档包的 URI" #: builtin/clone.c -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: 不能为 '%s' 添加一个备用:%s\n" - -#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c -#, c-format -msgid "failed to stat '%s'" -msgstr "无法对 '%s' 调用 stat" - -#: builtin/clone.c -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s 存在且不是一个目录" - -#: builtin/clone.c -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "'%s' 为符号链接,拒绝用 --local 克隆" - -#: builtin/clone.c -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "无法在 '%s' 上启动迭代器" - -#: builtin/clone.c -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "符号链接 '%s' 存在,拒绝用 --local 克隆" - -#: builtin/clone.c compat/precompose_utf8.c -#, c-format -msgid "failed to unlink '%s'" -msgstr "无法删除 '%s'" - -#: builtin/clone.c -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "无法检查 '%s' 处的硬链接" - -#: builtin/clone.c -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "硬链接与 '%s' 处的源不同" - -#: builtin/clone.c -#, c-format -msgid "failed to create link '%s'" -msgstr "无法创建链接 '%s'" - -#: builtin/clone.c -#, c-format -msgid "failed to copy file to '%s'" -msgstr "无法拷贝文件至 '%s'" - -#: builtin/clone.c -#, c-format -msgid "failed to iterate over '%s'" -msgstr "无法在 '%s' 上迭代" - -#: builtin/clone.c -#, c-format -msgid "done.\n" -msgstr "完成。\n" - -#: builtin/clone.c -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"克隆成功,但是检出失败。\n" -"您可以通过 'git status' 检查哪些已被检出,然后使用命令\n" -"'git restore --source=HEAD :/' 重试\n" - -#: builtin/clone.c -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "不能发现要克隆的远程分支 %s。" - -#: builtin/clone.c fetch-pack.c -msgid "remote did not send all necessary objects" -msgstr "远程没有发送所有必需的对象" - -#: builtin/clone.c -#, c-format -msgid "unable to update %s" -msgstr "不能更新 %s" - -#: builtin/clone.c -msgid "failed to initialize sparse-checkout" -msgstr "无法初始化稀疏检出" - -#: builtin/clone.c -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "远程 HEAD 指向一个不存在的引用,无法检出" - -#: builtin/clone.c -msgid "unable to checkout working tree" -msgstr "不能检出工作区" - -#: builtin/clone.c -msgid "unable to write parameters to config file" -msgstr "无法将参数写入配置文件" - -#: builtin/clone.c -msgid "cannot repack to clean up" -msgstr "无法执行 repack 来清理" - -#: builtin/clone.c -msgid "cannot unlink temporary alternates file" -msgstr "无法删除临时的 alternates 文件" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<选项>] [--] <仓库> [<目录>]" #: builtin/clone.c msgid "Too many arguments." @@ -5386,7 +5425,8 @@ msgstr "太多参数。" msgid "You must specify a repository to clone." msgstr "您必须指定一个仓库来克隆。" -#: builtin/clone.c builtin/init-db.c builtin/refs.c setup.c +#: builtin/clone.c builtin/init-db.c builtin/refs.c builtin/submodule--helper.c +#: setup.c #, c-format msgid "unknown ref storage format '%s'" msgstr "未知的引用存储格式 '%s'" @@ -5501,6 +5541,11 @@ msgstr "远程传输报告错误" msgid "Remote branch %s not found in upstream %s" msgstr "远程分支 %s 在上游 %s 未发现" +#: builtin/clone.c +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "在上游 %2$s 未发现远程版本 %1$s" + #: builtin/clone.c msgid "You appear to have cloned an empty repository." msgstr "您似乎克隆了一个空仓库。" @@ -5564,7 +5609,8 @@ msgstr "" "[no-]progress]\n" " <切分选项>" -#: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c +#: builtin/commit-graph.c builtin/fetch.c builtin/gc.c builtin/log.c +#: builtin/repack.c msgid "dir" msgstr "目录" @@ -5722,9 +5768,9 @@ msgstr "git commit-tree:无法读取" #: builtin/commit.c msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -5732,9 +5778,9 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<模式>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<模式>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <提交> | --fixup [(amend|" -"reword):]<提交>)]\n" +"reword):]<提交>]\n" " [-F <文件> | -m <消息>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<作者>]\n" " [--date=<日期>] [--cleanup=<模式>] [--[no-]status]\n" @@ -6327,11 +6373,10 @@ msgstr "git config list [<文件选项>] [<显示选项>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" -"git config get [<文件选项>] [<显示选项>] [--includes] [--all] [--regexp=<正则" -"表达式>] [--value=<值>] [--fixed-value] [--default=<默认值>] <名称>" +"git config get [<文件选项>] [<显示选项>] [--includes] [--all] [--regexp] [--" +"value=<值>] [--fixed-value] [--default=<默认值>] <名称>" #: builtin/config.c msgid "" @@ -6344,10 +6389,9 @@ msgstr "" #: builtin/config.c msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" -"git config unset [<文件选项>] [--all] [--value=<值>] [--fixed-value] <名称> <" -"值>" +"git config unset [<文件选项>] [--all] [--value=<值>] [--fixed-value] <名称>" #: builtin/config.c msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -6365,6 +6409,15 @@ msgstr "git config edit [<文件选项>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "git config [<文件选项>] --get-colorbool <名称> [<标准输出为tty>]" +#: builtin/config.c +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<文件选项>] [<显示选项>] [--includes] [--all] [--regexp=<正则" +"表达式>] [--value=<值>] [--fixed-value] [--default=<默认值>] <名称>" + #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " @@ -6882,12 +6935,8 @@ msgstr "已遍历 %lu 个提交\n" #: builtin/describe.c #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"发现多于 %i 个标签,列出最近的 %i 个\n" -"在 %s 放弃搜索\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "找到 %i 个标签;在 %s 处放弃搜索\n" #: builtin/describe.c #, c-format @@ -7373,8 +7422,8 @@ msgstr "" #: builtin/fetch.c #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s 未发送所有必需的对象\n" +msgid "%s did not send all necessary objects" +msgstr "%s 未发送所有必需的对象" #: builtin/fetch.c #, c-format @@ -7422,8 +7471,8 @@ msgstr "选项 \"%s\" 的值 \"%s\" 对于 %s 是无效的" #: builtin/fetch.c #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "选项 \"%s\" 为 %s 所忽略\n" +msgid "option \"%s\" is ignored for %s" +msgstr "选项 \"%s\" 为 %s 所忽略" #: builtin/fetch.c object-file.c #, c-format @@ -7435,6 +7484,20 @@ msgstr "%s 不是一个有效的对象" msgid "the object %s does not exist" msgstr "对象 '%s' 不存在" +#: builtin/fetch.c +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"运行 'git remote set-head %s %s' 同步变更,或通过配置选项\n" +"'remote.%s.followRemoteHEAD' 设置为其他值以屏蔽此提示。具体可通过\n" +"运行命令 'git config remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"以禁用该警告,直到远程将 HEAD 更改为其他内容。" + #: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "检测到多分支,和 --set-upstream 不兼容" @@ -7602,6 +7665,10 @@ msgstr "引用映射" msgid "specify fetch refmap" msgstr "指定获取操作的引用映射" +#: builtin/fetch.c builtin/pull.c builtin/rebase.c builtin/replay.c +msgid "revision" +msgstr "版本" + #: builtin/fetch.c builtin/pull.c msgid "report that we have only objects reachable from this object" msgstr "报告我们只拥有从该对象开始可达的对象" @@ -7670,8 +7737,8 @@ msgstr "协议不支持 --negotiate-only,退出" #: builtin/fetch.c msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" +"--filter can only be used with the remote configured in " +"extensions.partialclone" msgstr "只可以将 --filter 用于在 extensions.partialclone 中配置的远程仓库" #: builtin/fetch.c @@ -7797,7 +7864,7 @@ msgstr "存储着仓库路径列表的配置项键名" #: builtin/for-each-repo.c msgid "keep going even if command fails in a repository" -msgstr "即使存储库中的命令失败,仍继续执行" +msgstr "即使仓库中的命令失败,仍继续执行" #: builtin/for-each-repo.c msgid "missing --config=<config>" @@ -8265,6 +8332,10 @@ msgstr "更彻底(增加运行时间)" msgid "enable auto-gc mode" msgstr "启用自动垃圾回收模式" +#: builtin/gc.c +msgid "perform garbage collection in the background" +msgstr "在后台进行垃圾回收" + #: builtin/gc.c msgid "force running gc even if there may be another gc running" msgstr "强制执行 gc 即使另外一个 gc 正在执行" @@ -8273,6 +8344,10 @@ msgstr "强制执行 gc 即使另外一个 gc 正在执行" msgid "repack all other packs except the largest pack" msgstr "除了最大的包之外,对所有其它包文件重新打包" +#: builtin/gc.c builtin/repack.c +msgid "pack prefix to store a pack containing pruned objects" +msgstr "用于存储修剪对象的包前缀" + #: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" @@ -8382,6 +8457,10 @@ msgstr "任务 '%s' 不能被多次选择" msgid "run tasks based on the state of the repository" msgstr "基于仓库状态来运行任务" +#: builtin/gc.c +msgid "perform maintenance in the background" +msgstr "在后台执行运维" + #: builtin/gc.c msgid "frequency" msgstr "频率" @@ -8505,8 +8584,24 @@ msgid "%s scheduler is not available" msgstr "%s 调度器不可用" #: builtin/gc.c -msgid "another process is scheduling background maintenance" -msgstr "另外一个进程正运行于后台维护" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"无法创建 '%s.lock':%s。\n" +"\n" +"另一个已计划的 git-maintenance(1) 进程似乎正在该仓库中运行。\n" +"请确保没有其他维护进程正在运行,然后重试。如果仍然运行失败,则\n" +"git-maintenance(1) 进程可能之前已在此仓库中崩溃:请手动删除该文件以继续。" + +#: builtin/gc.c +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "无法获取计划的后台维护锁" #: builtin/gc.c msgid "git maintenance start [--scheduler=<scheduler>]" @@ -9231,10 +9326,32 @@ msgid_plural "chain length = %d: %lu objects" msgstr[0] "链长 = %d: %lu 对象" msgstr[1] "链长 = %d: %lu 对象" +#: builtin/index-pack.c +msgid "could not start pack-objects to repack local links" +msgstr "无法启动 pack-objects 来重新打包本地链接" + +#: builtin/index-pack.c +msgid "failed to feed local object to pack-objects" +msgstr "无法将本地对象提供给 pack-objects" + +#: builtin/index-pack.c +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack:期望仅从 pack-objects 的输出行中获得完整的十六进制对象 ID。" + +#: builtin/index-pack.c +msgid "could not finish pack-objects to repack local links" +msgstr "无法完成 pack-objects 来重新打包本地链接" + #: builtin/index-pack.c msgid "Cannot come back to cwd" msgstr "无法返回当前工作目录" +#: builtin/index-pack.c builtin/unpack-objects.c +#, c-format +msgid "bad --pack_header: %s" +msgstr "错误的 --pack_header:%s" + #: builtin/index-pack.c #, c-format msgid "bad %s" @@ -9245,6 +9362,10 @@ msgstr "错误选项 %s" msgid "unknown hash algorithm '%s'" msgstr "未知的哈希算法 '%s'" +#: builtin/index-pack.c +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor 无法与包名称一起使用" + #: builtin/index-pack.c msgid "--stdin requires a git repository" msgstr "--stdin 需要 git 仓库" @@ -9473,10 +9594,6 @@ msgstr "-L<范围>:<文件> 不能和路径表达式共用" msgid "Final output: %d %s\n" msgstr "最终输出:%d %s\n" -#: builtin/log.c -msgid "unable to create temporary object directory" -msgstr "无法创建临时对象目录" - #: builtin/log.c #, c-format msgid "git show %s: bad file" @@ -10205,18 +10322,6 @@ msgstr "使用基于 diff3 的合并" msgid "use a zealous diff3 based merge" msgstr "使用基于狂热 diff3(zealous diff3)的合并" -#: builtin/merge-file.c -msgid "for conflicts, use our version" -msgstr "如果冲突,使用我们的版本" - -#: builtin/merge-file.c -msgid "for conflicts, use their version" -msgstr "如果冲突,使用他们的版本" - -#: builtin/merge-file.c -msgid "for conflicts, use a union version" -msgstr "如果冲突,使用联合版本" - #: builtin/merge-file.c diff.c msgid "<algorithm>" msgstr "<算法>" @@ -10352,11 +10457,6 @@ msgstr "未知的策略选项:-X%s" msgid "malformed input line: '%s'." msgstr "格式错误的输入行:'%s'。" -#: builtin/merge-tree.c -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "合并无法继续;得到不干净的结果 %d" - #: builtin/merge.c msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<选项>] [<提交>...]" @@ -10512,7 +10612,7 @@ msgstr "不能写入索引。" msgid "Not handling anything other than two heads merge." msgstr "未处理两个头合并之外的任何操作。" -#: builtin/merge.c +#: builtin/merge.c builtin/sparse-checkout.c #, c-format msgid "unable to write %s" msgstr "不能写 %s" @@ -10803,6 +10903,10 @@ msgstr "在计算多包位图时打包以供重用" msgid "write multi-pack bitmap" msgstr "写入多包位图" +#: builtin/multi-pack-index.c +msgid "write a new incremental MIDX" +msgstr "写入一个新的增量 MIDX" + #: builtin/multi-pack-index.c msgid "write multi-pack index containing only given indexes" msgstr "写入只包括给定索引的多包索引" @@ -10973,11 +11077,11 @@ msgstr "git notes [--ref <注解引用>] [list [<对象>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <注解引用>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<分段符>] [--[no-]stripspace] [-m <说明> | -F <文件> | (-c | -C) <" -"对象>] [<对象>]" +"对象>] [<对象>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" @@ -10987,11 +11091,11 @@ msgstr "git notes [--ref <注解引用>] copy [-f] <源对象> <目标对象>" msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <注解引用>] append [--allow-empty] [--[no-]separator|--" "separator=<分段符>] [--[no-]stripspace] [-m <说明> | -F <文件> | (-c | -C) <" -"对象>] [<对象>]" +"对象>] [<对象>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" @@ -11142,6 +11246,10 @@ msgstr "注解内容到一个文件中" msgid "reuse and edit specified note object" msgstr "重用和编辑指定的注解对象" +#: builtin/notes.c +msgid "edit note message in editor" +msgstr "在编辑器中编辑注释说明" + #: builtin/notes.c msgid "reuse specified note object" msgstr "重用指定的注解对象" @@ -11364,6 +11472,15 @@ msgid "" "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" msgstr "git pack-objects [<选项>] <前缀名称> [< <引用列表> | < <对象列表>]" +#: builtin/pack-objects.c +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "无效的 --name-hash-version 选项:%d" + +#: builtin/pack-objects.c +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "当前,--write-bitmap-index 要求 --name-hash-version=1" + #: builtin/pack-objects.c #, c-format msgid "" @@ -11755,6 +11872,10 @@ msgstr "处理丢失的对象" msgid "do not pack objects in promisor packfiles" msgstr "不要打包 promisor 包文件中的对象" +#: builtin/pack-objects.c +msgid "implies --missing=allow-any" +msgstr "暗含 --missing=allow-any" + #: builtin/pack-objects.c msgid "respect islands during delta compression" msgstr "在增量压缩时参考数据岛" @@ -11765,7 +11886,11 @@ msgstr "协议" #: builtin/pack-objects.c msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" -msgstr "使用此协议排除任何已配置的 uploadpack.blobpackfileuri" +msgstr "排除掉采用该协议的 uploadpack.blobpackfileuri 配置项" + +#: builtin/pack-objects.c +msgid "use the specified name-hash function to group similar objects" +msgstr "使用指定的名称哈希函数对相似的对象进行分组" #: builtin/pack-objects.c #, c-format @@ -12192,8 +12317,8 @@ msgid "" "upstream, see 'push.autoSetupRemote' in 'git help config'.\n" msgstr "" "\n" -"为了让没有追踪上游的分支自动配置,参见 'git help config' 中的 push." -"autoSetupRemote。\n" +"为了让没有追踪上游的分支自动配置,参见 'git help config' 中的 " +"push.autoSetupRemote。\n" #: builtin/push.c #, c-format @@ -13202,8 +13327,12 @@ msgid "invalid ref format: %s" msgstr "无效的引用格式:%s" #: builtin/refs.c -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<格式> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<格式> [--no-reflog] [--dry-run]" + +#: builtin/refs.c +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" #: builtin/refs.c msgid "specify the reference format to convert to" @@ -13213,6 +13342,10 @@ msgstr "指定要转换的引用格式" msgid "perform a non-destructive dry-run" msgstr "进行非破坏性的试运行(dry-run)" +#: builtin/refs.c +msgid "drop reflogs entirely during the migration" +msgstr "在迁移期间丢弃引用日志" + #: builtin/refs.c msgid "missing --ref-format=<format>" msgstr "缺少 --ref-format=<格式>" @@ -13222,6 +13355,14 @@ msgstr "缺少 --ref-format=<格式>" msgid "repository already uses '%s' format" msgstr "仓库已使用 '%s' 格式" +#: builtin/refs.c +msgid "enable strict checking" +msgstr "启用严格的检查" + +#: builtin/refs.c +msgid "'git refs verify' takes no arguments" +msgstr "'git refs verify' 不接受任何参数" + #: builtin/remote.c msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" @@ -13627,6 +13768,33 @@ msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " 为 'git push' 配置的本地引用%s:" msgstr[1] " 为 'git push' 配置的本地引用%s:" +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "'%s/HEAD' 未改变并指向 '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' 已从 '%s' 更改,现在指向 '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "'%s/HEAD' 现已创建并指向 '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "'%s/HEAD' 在 '%s' 处分离并且现在指向 '%s'\n" + +#: builtin/remote.c +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "'%s/HEAD' 曾指向 '%s'(不是远程分支),但现在指向 '%s'\n" + #: builtin/remote.c msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "根据远程设置 refs/remotes/<名称>/HEAD" @@ -13655,7 +13823,7 @@ msgstr "不是一个有效引用:%s" #: builtin/remote.c #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "不能设置 %s" # 译者:注意保持前导空格 @@ -13750,8 +13918,14 @@ msgid "be verbose; must be placed before a subcommand" msgstr "冗长输出;必须置于子命令之前" #: builtin/repack.c -msgid "git repack [<options>]" -msgstr "git repack [<选项>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<包名>]\n" +"[--write-midx] [--name-hash-version=<n>]" #: builtin/repack.c msgid "" @@ -13843,6 +14017,11 @@ msgstr "向 git-pack-objects 传递参数 --no-reuse-delta" msgid "pass --no-reuse-object to git-pack-objects" msgstr "向 git-pack-objects 传递参数 --no-reuse-object" +#: builtin/repack.c +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "指定要使用的名称哈希算法,以实现按照路径对相似对象分组" + #: builtin/repack.c msgid "do not run git-update-server-info" msgstr "不运行 git-update-server-info" @@ -13907,10 +14086,6 @@ msgstr "使用因子 <n> 查找几何级数" msgid "write a multi-pack index of the resulting packs" msgstr "写入结果包的多包索引" -#: builtin/repack.c -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 "储存被过滤的对象的包的前缀" @@ -14183,10 +14358,6 @@ msgstr "只能为 -l 提供一个模式" 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 "提供的所有正向版本必须为引用" @@ -14996,12 +15167,12 @@ msgid "failed to look up reference" msgstr "无法找到引用" #: builtin/show-ref.c -msgid "only show tags (can be combined with branches)" -msgstr "仅显示标签(可与分支组合使用)" +msgid "only show tags (can be combined with --branches)" +msgstr "仅显示标签(可与 --branches 组合使用)" #: builtin/show-ref.c -msgid "only show branches (can be combined with tags)" -msgstr "仅显示分支(可以和标签组合使用)" +msgid "only show branches (can be combined with --tags)" +msgstr "仅显示分支(可与 --tags 组合使用)" #: builtin/show-ref.c msgid "check for reference existence without resolving" @@ -15063,6 +15234,11 @@ msgstr "无法删除目录 '%s'" msgid "failed to create directory for sparse-checkout file" msgstr "无法为稀疏检出文件创建目录" +#: builtin/sparse-checkout.c +#, c-format +msgid "unable to fdopen %s" +msgstr "不能 fdopen %s" + #: builtin/sparse-checkout.c msgid "failed to initialize worktree config" msgstr "无法初始化工作树配置" @@ -15612,8 +15788,8 @@ msgstr "不能从 '%s' 创建哈希对象" #: builtin/submodule--helper.c #, c-format -msgid "unexpected mode %o\n" -msgstr "意外的模式 %o\n" +msgid "unexpected mode %o" +msgstr "意外的模式 %o" #: builtin/submodule--helper.c msgid "use the commit stored in the index instead of the submodule HEAD" @@ -16988,6 +17164,10 @@ msgstr "设置跟踪模式(参见 git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "尝试为新分支名匹配一个远程跟踪分支" +#: builtin/worktree.c +msgid "use relative paths for worktrees" +msgstr "对工作区使用相对路径" + #: builtin/worktree.c diff.c parse-options.c #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" @@ -17324,6 +17504,30 @@ msgstr "不能创建 '%s'" msgid "index-pack died" msgstr "index-pack 终止" +#: cache-tree.c +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "目录 '%s' 存在于索引中,但不是稀疏的" + +#: cache-tree.c unpack-trees.c +msgid "corrupted cache-tree has entries not present in index" +msgstr "损坏的缓存树包含索引中不存在的条目" + +#: cache-tree.c +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "标志位为 0x%2$x 的 %1$s 不应位于缓存树中" + +#: cache-tree.c +#, c-format +msgid "bad subtree '%.*s'" +msgstr "损坏的子树 '%.*s'" + +#: cache-tree.c +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "路径 %.*s 的缓存树不匹配。预期为 %s,实际为 %s" + #: chunk-format.c msgid "terminating chunk id appears earlier than expected" msgstr "终止块 ID 比预期更早出现" @@ -17381,6 +17585,10 @@ msgstr "将一个 GNU Arch 仓库导入到 Git" msgid "Create an archive of files from a named tree" msgstr "基于一个指定的树创建文件存档" +#: command-list.h +msgid "Download missing objects in a partial clone" +msgstr "下载部分克隆中缺失的对象" + #: command-list.h msgid "Use binary search to find the commit that introduced a bug" msgstr "通过二分查找定位引入 bug 的提交" @@ -18289,7 +18497,7 @@ msgstr "无法写入正确数量的基础图形 ID" msgid "unable to create temporary graph layer" msgstr "无法创建临时图层" -#: commit-graph.c +#: commit-graph.c midx-write.c #, c-format msgid "unable to adjust shared permissions for '%s'" msgstr "无法为 '%s' 调整共享权限" @@ -18431,15 +18639,15 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "对 <GIT_DIR>/info/grafts 的支持已过时,并将在\n" "未来的Git版本中被移除。\n" "\n" "请使用 \"git replace --convert-graft-file\" 将\n" -"grafts 转换为替换引用。\n" +"(提交)移植转换为替换引用。\n" "\n" -"设置 \"git config advice.graftFileDeprecated false\"\n" +"运行 \"git config set advice.graftFileDeprecated false\"\n" "可关闭本消息" #: commit.c @@ -18763,8 +18971,8 @@ msgid "" "remote URLs cannot be configured in file directly or indirectly included by " "includeIf.hasconfig:remote.*.url" msgstr "" -"远程 URL 不能在文件中配置,不管直接地还是通过 includeIf.hasconfig:remote.*." -"url 间接地包含。" +"远程 URL 不能在文件中配置,不管直接地还是通过 " +"includeIf.hasconfig:remote.*.url 间接地包含。" #: config.c #, c-format @@ -19439,6 +19647,21 @@ msgstr "URL 没有 scheme:%s" msgid "credential url cannot be parsed: %s" msgstr "不能解析凭据 URL:%s" +#: daemon.c +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "无效的超时值 '%s',应为非负整数" + +#: daemon.c +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "无效的初始超时值 '%s',应为非负整数" + +#: daemon.c +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "无效的最大连接数 '%s',应为一个整数" + #: date.c msgid "in the future" msgstr "在将来" @@ -19638,7 +19861,7 @@ msgstr "color-moved-ws:allow-indentation-change 不能与其它空白字符模 msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "配置变量 'diff.submodule' 未知的取值:'%s'" -#: diff.c transport.c +#: diff.c merge-recursive.c transport.c #, c-format msgid "unknown value for config '%s': %s" msgstr "配置 '%s' 未知的取值:%s" @@ -19746,6 +19969,14 @@ msgstr "%s 的参数无效" msgid "invalid regex given to -I: '%s'" msgstr "选项 -I 的正则表达式无效:'%s'" +#: diff.c +msgid "-G requires a non-empty argument" +msgstr "-G 需要一个非空参数" + +#: diff.c +msgid "-S requires a non-empty argument" +msgstr "-S 需要一个非空参数" + #: diff.c #, c-format msgid "failed to parse --submodule option parameter: '%s'" @@ -20305,6 +20536,20 @@ msgstr "错误的 git 名字空间路径 \"%s\"" msgid "too many args to run %s" msgstr "执行 %s 的参数太多" +#: fetch-pack.c +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"您正在尝试获取 %s,它位于提交图文件中,但不在对象数据库中。\n" +"这可能是由于仓库损坏造成的。\n" +"如果您尝试通过重新获取丢失的对象来修复此仓库损坏,请对丢失的对象使用 'git " +"fetch --refetch'。" + #: fetch-pack.c msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack:应为 shallow 列表" @@ -21016,10 +21261,10 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" "因为没有将钩子 '%s' 设置为可执行,钩子被忽略。您可以通过\n" -"配置 `git config advice.ignoredHook false` 来关闭这条警告。" +"配置 `git config set advice.ignoredHook false` 来关闭这条警告。" #: http-fetch.c msgid "not a git repository" @@ -21039,18 +21284,10 @@ msgstr "http.postBuffer 为负值,默认为 %d" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "不支持委托控制,因为 cURL < 7.22.0" -#: http.c -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "不支持公钥文件锁定,因为 cURL < 7.39.0" - #: http.c msgid "Unknown value for http.proactiveauth" msgstr "http.proactiveauth 为未知取值" -#: http.c -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "不支持 CURLSSLOPT_NO_REVOKE,因为 cURL < 7.44.0" - #: http.c #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" @@ -21117,6 +21354,7 @@ msgstr "" "\n" "来设置您账号的缺省身份标识。\n" "如果仅在本仓库设置身份标识,则省略 --global 参数。\n" +"\n" #: ident.c msgid "no email was given and auto-detection is disabled" @@ -21237,6 +21475,10 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "不能创建 '%s.lock':%s" +#: log-tree.c +msgid "unable to create temporary object directory" +msgstr "无法创建临时对象目录" + #: loose.c #, c-format msgid "could not write loose object index %s" @@ -21244,8 +21486,8 @@ msgstr "不能写入松散对象索引 %s" #: loose.c #, c-format -msgid "failed to write loose object index %s\n" -msgstr "无法写入松散对象索引 %s\n" +msgid "failed to write loose object index %s" +msgstr "无法写入松散对象索引 %s" #: ls-refs.c #, c-format @@ -21265,6 +21507,11 @@ msgstr "检测到被引用的 CRLF" msgid "unable to format message: %s" msgstr "无法格式化消息:%s" +#: merge-ll.c +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "无效的标记大小 '%s',应为一个整数" + #: merge-ort.c merge-recursive.c #, c-format msgid "Failed to merge submodule %s (not checked out)" @@ -21878,6 +22125,20 @@ msgstr "不能载入包" msgid "could not open index for %s" msgstr "不能打开 %s 的索引" +#: midx-write.c +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "无法将 '%s' 链接至 '%s'" + +#: midx-write.c midx.c +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "无法清理位于 %s 的多包索引" + +#: midx-write.c +msgid "cannot write incremental MIDX with bitmap" +msgstr "无法使用位图写入增量 MIDX" + #: midx-write.c msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "忽略已存在的多包索引,校验码不匹配" @@ -21914,14 +22175,30 @@ msgstr "没有要索引的包文件。" msgid "refusing to write multi-pack .bitmap without any objects" msgstr "拒绝写入没有任何对象的多包位图" +#: midx-write.c +msgid "unable to create temporary MIDX layer" +msgstr "无法创建临时 MIDX 层" + #: midx-write.c msgid "could not write multi-pack bitmap" msgstr "无法写入多包位图" +#: midx-write.c +msgid "unable to open multi-pack-index chain file" +msgstr "无法打开多包索引链文件" + +#: midx-write.c +msgid "unable to rename new multi-pack-index layer" +msgstr "无法重命名新的多包索引层" + #: midx-write.c msgid "could not write multi-pack-index" msgstr "无法写入多包索引" +#: midx-write.c +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "增量多包索引中的包不能过期" + #: midx-write.c msgid "Counting referenced objects" msgstr "正在对引用对象计数" @@ -21930,6 +22207,10 @@ msgstr "正在对引用对象计数" msgid "Finding and deleting unreferenced packfiles" msgstr "正在查找和删除未引用的包文件" +#: midx-write.c +msgid "cannot repack an incremental multi-pack-index" +msgstr "无法重新打包增量多包索引" + #: midx-write.c msgid "could not start pack-objects" msgstr "不能开始 pack-objects" @@ -22001,6 +22282,33 @@ msgstr "多包索引包名块过短" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "多包索引包名无序:'%s' 在 '%s' 之前" +#: midx.c +msgid "multi-pack-index chain file too small" +msgstr "多包索引链文件太小" + +#: midx.c +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "基线的 MIDX 中包的数量过高:%<PRIuMAX>" + +#: midx.c +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "基线的 MIDX 中对象的数量过高:%<PRIuMAX>" + +#: midx.c +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "无效的多包索引链:第 '%s' 行不是哈希值" + +#: midx.c +msgid "unable to find all multi-pack index files" +msgstr "无法找到所有的多包索引文件" + +#: midx.c +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "无效的 MIDX 对象位置,MIDX 可能已损坏" + #: midx.c #, c-format msgid "bad pack-int-id: %u (%u total packs)" @@ -22023,11 +22331,6 @@ msgstr "多包索引存储一个64位偏移,但是 off_t 太小" msgid "multi-pack-index large offset out of bounds" msgstr "多包索引大偏移区越界" -#: midx.c -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "无法清理位于 %s 的多包索引" - #: midx.c msgid "multi-pack-index file exists, but failed to parse" msgstr "多包索引文件存在,但无法解析" @@ -22179,7 +22482,7 @@ msgstr "无法读取替代文件" #: object-file.c msgid "unable to move new alternates file into place" -msgstr "无法将新的替代文件移动到位" +msgstr "无法将新的备用文件移动到位" #: object-file.c #, c-format @@ -22285,11 +22588,26 @@ msgstr "打包对象 %s(保存在 %s)已损坏" msgid "missing mapping of %s to %s" msgstr "缺少 %s 到 %s 的映射" +#: object-file.c +#, c-format +msgid "unable to open %s" +msgstr "不能打开 %s" + +#: object-file.c +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "文件 '%s' 和 '%s' 的内容不同" + #: object-file.c #, c-format msgid "unable to write file %s" msgstr "无法写文件 %s" +#: object-file.c +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "无法写入反复消失的文件 %s" + #: object-file.c #, c-format msgid "unable to set permission to '%s'" @@ -22391,11 +22709,6 @@ msgstr "%s:不支持的文件类型" msgid "%s is not a valid '%s' object" msgstr "%s 不是一个有效的 '%s' 对象" -#: object-file.c -#, c-format -msgid "unable to open %s" -msgstr "不能打开 %s" - #: object-file.c #, c-format msgid "hash mismatch for %s (expected %s)" @@ -22511,7 +22824,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Git 通常不会创建一个以40个十六进制字符结尾的引用,因为当您只提供40\n" "个十六进制字符时将被忽略。这些引用可能被错误地创建。例如:\n" @@ -22519,7 +22832,7 @@ msgstr "" " git switch -c $br $(git rev-parse ...)\n" "\n" "当 \"$br\" 某种原因空白时,一个40位十六进制的引用将被创建。请检查这些\n" -"引用,可能需要删除它们。运行 \"git config advice.objectNameWarning\n" +"引用,可能需要删除它们。运行 \"git config set advice.objectNameWarning\n" "false\" 命令关闭本消息通知。" #: object-name.c @@ -22714,15 +23027,6 @@ 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" -msgstr "首选包 (%s) 无效" - #: pack-bitmap.c msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "损坏的位图查询表:三元组位置超出索引" @@ -22986,6 +23290,55 @@ msgstr "未知开关 `%c'" msgid "unknown non-ascii option in string: `%s'" msgstr "字符串中未知的非 ascii 字符选项:`%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid " <%s>" +msgstr " <%s>" + #: parse-options.c msgid "..." msgstr "..." @@ -23089,6 +23442,25 @@ msgstr "对于 '%2$s' 的错误的布尔环境取值 '%1$s'" msgid "failed to parse %s" msgstr "无法解析 %s" +#: path-walk.c +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "无法遍历树 %s 的子节点:未找到" + +#: path-walk.c +#, c-format +msgid "failed to find object %s" +msgstr "无法找到对象 %s" + +#: path-walk.c +#, c-format +msgid "failed to find tag %s" +msgstr "无法找到标签 %s" + +#: path-walk.c +msgid "failed to setup revision walk" +msgstr "无法设置版本遍历" + #: path.c #, c-format msgid "Could not make %s writable by group" @@ -23270,6 +23642,26 @@ msgstr "promisor 远程名称不能以 '/' 开始:%s" msgid "could not fetch %s from promisor remote" msgstr "无法从承诺者远程获取 %s" +#: promisor-remote.c +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "已知远程名称为 '%s',但 url 为 '%s' 而不是 '%s'" + +#: promisor-remote.c +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "配置项 '%2$s' 为未知的取值 '%1$s'" + +#: promisor-remote.c +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "远程信息中的未知元素 '%s'" + +#: promisor-remote.c +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "未找到已接受的承诺者远程 '%s'" + #: protocol-caps.c msgid "object-info: expected flush after arguments" msgstr "object-info:在参数之后应有一个 flush" @@ -23842,6 +24234,11 @@ msgstr "元素 %%(align) 需要一个正数的宽度" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "期望的格式:%%(ahead-behind:<提交号>)" +#: ref-filter.c +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "期望的格式:%%(is-base:<提交号>)" + #: ref-filter.c #, c-format msgid "malformed field name: %.*s" @@ -24053,8 +24450,19 @@ msgid "log for %s is empty" msgstr "%s 的日志为空" #: refs.c -msgid "refusing to force and skip creation of reflog" -msgstr "拒绝既强制又跳过创建引用日志" +#, c-format +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "拒绝为伪引用 '%s' 更新引用日志" + +#: refs.c +#, c-format +msgid "refusing to update pseudoref '%s'" +msgstr "拒绝更新伪引用 '%s'" + +#: refs.c +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "拒绝使用错误名称 '%s' 更新引用日志" #: refs.c #, c-format @@ -24062,9 +24470,8 @@ msgid "refusing to update ref with bad name '%s'" msgstr "拒绝更新有错误名称 '%s' 的引用" #: refs.c -#, c-format -msgid "refusing to update pseudoref '%s'" -msgstr "拒绝更新伪引用 '%s'" +msgid "refusing to force and skip creation of reflog" +msgstr "拒绝强制跳过创建引用日志" #: refs.c #, c-format @@ -24125,6 +24532,20 @@ msgid "" "cannot lock ref '%s': expected symref with target '%s': but is a regular ref" msgstr "无法锁定引用 '%s':预期目标为 '%s' 的符号引用:但是是普通引用" +#: refs/files-backend.c +#, c-format +msgid "cannot read ref file '%s'" +msgstr "无法读取引用文件 '%s'" + +#: refs/files-backend.c +#, c-format +msgid "cannot open directory %s" +msgstr "无法打开目录 %s" + +#: refs/files-backend.c +msgid "Checking references consistency" +msgstr "正在检查引用一致性" + #: refs/reftable-backend.c #, c-format msgid "refname is dangerous: %s" @@ -24208,6 +24629,16 @@ msgstr "引用名 %s 是一个符号引用,不支持复制" msgid "invalid refspec '%s'" msgstr "无效的引用规格:'%s'" +#: refspec.c +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "模式 '%s' 没有 '*'" + +#: refspec.c +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "替换 '%s' 没有 '*'" + #: remote-curl.c #, c-format msgid "invalid quoting in push-option value: '%s'" @@ -24359,6 +24790,28 @@ msgstr "remote-curl:尝试没有本地仓库下获取" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl:未知的来自 git 的命令 '%s'" +#: remote.c +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"正在从 \"%s/%s\" 读取远程内容,该内容被提名删除。\n" +"\n" +"如果你仍然在使用 \"remotes/\" 目录,建议迁移为基于配置远程的方式:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"如果你无法迁移,请发送电子邮件至 <git@vger.kernel.org> 告知我们你\n" +"仍然需要使用它的原因。" + #: remote.c #, c-format msgid "config remote shorthand cannot begin with '/': %s" @@ -24372,6 +24825,11 @@ msgstr "提供了一个以上的 receivepack,使用第一个" msgid "more than one uploadpack given, using the first" msgstr "提供了一个以上的 uploadpack,使用第一个" +#: remote.c +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "已忽略无法识别的 followRemoteHEAD 值 '%s'" + #: remote.c #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" @@ -24397,16 +24855,6 @@ msgstr "%s 通常跟踪 %s,而非 %s" msgid "%s tracks both %s and %s" msgstr "%s 同时跟踪 %s 和 %s" -#: remote.c -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "模式的键 '%s' 没有 '*'" - -#: remote.c -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "模式的值 '%s' 没有 '*'" - #: remote.c #, c-format msgid "src refspec %s does not match any" @@ -24894,13 +25342,17 @@ msgstr "只下载要检出的分支的元信息" msgid "create repository within 'src' directory" msgstr "在 'src' 目录中创建仓库" +#: scalar.c +msgid "specify if tags should be fetched during clone" +msgstr "如若应在克隆期间获取标签则指定" + #: scalar.c msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<登记>]" +"\t[--[no-]src] [--[no-]tags] <url> [<登记>]" #: scalar.c #, c-format @@ -24922,6 +25374,11 @@ msgstr "无法获取 '%s' 的默认分支" msgid "could not configure remote in '%s'" msgstr "无法在 '%s' 中配置远程" +#: scalar.c +#, c-format +msgid "could not disable tags in '%s'" +msgstr "无法禁用 '%s' 中的标签" + #: scalar.c #, c-format msgid "could not configure '%s'" @@ -26190,6 +26647,11 @@ msgstr "无法返回当前工作目录" msgid "failed to stat '%*s%s%s'" msgstr "无法获取 '%*s%s%s' 状态(stat)" +#: setup.c +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' 不是绝对路径" + #: setup.c #, c-format msgid "" @@ -26661,6 +27123,34 @@ msgstr "在每次迭代前清除缓存树" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "缓存树中无效化的条目数量(默认 0)" +#: t/helper/test-path-walk.c +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <选项> -- <版本选项>" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of blob objects" +msgstr "切换是否包含数据对象" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of commit objects" +msgstr "切换是否包含提交对象" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tag objects" +msgstr "切换是否包含标签对象" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tree objects" +msgstr "切换是否包含树对象" + +#: t/helper/test-path-walk.c +msgid "toggle pruning of uninteresting paths" +msgstr "切换对无趣路径的修剪" + +#: t/helper/test-path-walk.c +msgid "read a pattern list over stdin" +msgstr "从标准输入读取模式列表" + #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -26670,6 +27160,10 @@ msgstr "提交 %s 没有标记为可达" msgid "too many commits marked reachable" msgstr "太多提交标记为可达" +#: t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "不能确定多包索引的首选包" + #: t/helper/test-serve-v2.c msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<选项>]" @@ -26750,6 +27244,30 @@ msgstr "令牌" msgid "command token to send to the server" msgstr "发送到服务器的命令令牌" +#: t/unit-tests/unit-test.c +msgid "unit-test [<options>]" +msgstr "unit-test [<选项>]" + +#: t/unit-tests/unit-test.c +msgid "immediately exit upon the first failed test" +msgstr "第一次测试失败后立即退出" + +#: t/unit-tests/unit-test.c +msgid "suite[::test]" +msgstr "suite[::测试用例]" + +#: t/unit-tests/unit-test.c +msgid "run only test suite or individual test <suite[::test]>" +msgstr "只运行测试套件或单独的测试 <测试套件[::测试用例]>" + +#: t/unit-tests/unit-test.c +msgid "suite" +msgstr "测试套件" + +#: t/unit-tests/unit-test.c +msgid "exclude test suite <suite>" +msgstr "排除测试套件 <测试套件>" + #: trailer.c #, c-format msgid "running trailer command '%s' failed" @@ -27380,6 +27898,11 @@ msgstr "错误:" msgid "warning: " msgstr "警告:" +#: version.c +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() 失败,错误为 '%s'(%d)\n" + #: walker.c msgid "Fetching objects" msgstr "正在获取对象" @@ -27420,6 +27943,10 @@ msgstr ".git 文件损坏" msgid ".git file incorrect" msgstr ".git 文件不正确" +#: worktree.c +msgid ".git file absolute/relative path mismatch" +msgstr ".git 文件绝对/相对路径不匹配" + #: worktree.c msgid "not a valid path" msgstr "不是一个有效的路径" @@ -27440,6 +27967,10 @@ msgstr "无法定位仓库,.git 文件损坏" msgid "gitdir unreadable" msgstr "gitdir 不可读" +#: worktree.c +msgid "gitdir absolute/relative path mismatch" +msgstr "gitdir 绝对/相对路径不匹配" + #: worktree.c msgid "gitdir incorrect" msgstr "gitdir 不正确" @@ -27484,6 +28015,14 @@ msgstr "无法在 '%2$s' 中取消设置 %1$s" msgid "failed to set extensions.worktreeConfig setting" msgstr "无法设置 extensions.worktreeConfig" +#: worktree.c +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "无法升级仓库格式以支持相对工作区" + +#: worktree.c +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "无法设定 extensions.relativeWorktrees 的设置" + #: wrapper.c #, c-format msgid "could not setenv '%s'" @@ -28200,6 +28739,10 @@ msgstr "'%s.final' 包含编辑的邮件。\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases 和其它选项不兼容\n" +#: git-send-email.perl +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases 和 --translate-aliases 是互斥的\n" + #: git-send-email.perl msgid "" "fatal: found configuration options for 'sendmail'\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index abf7157a99e44e..aa74d6537accf4 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -30,8 +30,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-19 15:00+0800\n" -"PO-Revision-Date: 2024-07-24 08:21+0000\n" +"POT-Creation-Date: 2025-03-09 10:39+0800\n" +"PO-Revision-Date: 2025-03-09 10:52+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" @@ -40,7 +40,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.6.2\n" +"X-Generator: Poedit 3.5\n" "X-ZhConverter: 繁化姬 dict-f4bc617e-r910 @ 2019/11/16 20:23:12 | https://" "zhconvert.org\n" @@ -663,7 +663,7 @@ msgid "" "/ - search for a hunk matching the given regex\n" "s - split the current hunk into smaller hunks\n" "e - manually edit the current hunk\n" -"p - print the current hunk\n" +"p - print the current hunk, 'P' to use the pager\n" "? - print help\n" msgstr "" "j - 維持此區塊未決定狀態,檢視下一個未決定區塊\n" @@ -674,7 +674,7 @@ msgstr "" "/ - 尋找符合提供之常規表示式的區塊\n" "s - 分割目前區塊為更小的區塊\n" "e - 手動編輯目前區塊\n" -"p - 輸出目前區塊\n" +"p - 輸出目前區塊,「P」分頁顯示\n" "? - 顯示說明\n" #: add-patch.c @@ -764,10 +764,10 @@ msgstr "只有二進位檔案更動了。" #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"請使用「git config advice.%s false」停用此訊息" +"請使用「git config set advice.%s false」停用此訊息" #: advice.c #, c-format @@ -941,12 +941,12 @@ msgstr "引數過多" #: apply.c #, c-format msgid "unrecognized whitespace option '%s'" -msgstr "空白字元選項「%s」無法識別" +msgstr "空白字元選項「%s」不認識" #: apply.c #, c-format msgid "unrecognized whitespace ignore option '%s'" -msgstr "空白字元忽略選項「%s」無法識別" +msgstr "空白字元忽略選項「%s」不認識" #: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c #: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c @@ -1081,7 +1081,7 @@ msgstr "二進位修補檔在第 %d 列損壞:%.*s" #: apply.c #, c-format msgid "unrecognized binary patch at line %d" -msgstr "第 %d 列的二進位修補檔無法識別" +msgstr "第 %d 列的二進位修補檔不認識" #: apply.c #, c-format @@ -1487,6 +1487,18 @@ msgstr "亦套用修補檔(與 --stat/--summary/--check 選項同時使用)" msgid "attempt three-way merge, fall back on normal patch if that fails" msgstr "嘗試三方合併,若失敗則回到正常修補模式" +#: apply.c builtin/merge-file.c +msgid "for conflicts, use our version" +msgstr "如果衝突,使用我們的版本" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use their version" +msgstr "如果衝突,使用他們的版本" + +#: apply.c builtin/merge-file.c +msgid "for conflicts, use a union version" +msgstr "如果衝突,使用聯合版本" + #: apply.c msgid "build a temporary index based on embedded index information" msgstr "組建以嵌入索引資訊為基礎的暫存索引" @@ -1548,6 +1560,10 @@ msgstr "在所有檔案名稱前加上 <root>" msgid "don't return error for empty patches" msgstr "遇到空白修補檔時,不回傳錯誤" +#: apply.c +msgid "--ours, --theirs, and --union require --3way" +msgstr "--ours、--theirs 和 --union 需要 --3way" + #: archive-tar.c archive-zip.c #, c-format msgid "cannot stream blob %s" @@ -1636,6 +1652,11 @@ msgstr "非有效物件名稱:%s" msgid "not a tree object: %s" msgstr "非樹狀物件:%s" +#: archive.c +#, c-format +msgid "failed to unpack tree object %s" +msgstr "解包 %s 樹狀物件失敗" + #: archive.c #, c-format msgid "File not found: %s" @@ -1752,7 +1773,7 @@ msgstr "「%s」選項需要「%s」" msgid "Unexpected option --output" msgstr "非預期選項 --output" -#: archive.c +#: archive.c t/unit-tests/unit-test.c #, c-format msgid "extra command line parameter '%s'" msgstr "多出命令列參數「%s」" @@ -1823,7 +1844,7 @@ msgid "unable to stat '%s'" msgstr "無法統計「%s」" #: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c -#: builtin/pack-objects.c combine-diff.c rerere.c +#: builtin/pack-objects.c combine-diff.c object-file.c rerere.c #, c-format msgid "unable to read %s" msgstr "無法讀取 %s" @@ -1958,7 +1979,7 @@ msgstr "--contents 和 --reverse 不能混用。" msgid "--reverse and --first-parent together require specified latest commit" msgstr "--reverse 和 --first-parent 共用,需要指定最新的提交" -#: blame.c builtin/commit.c builtin/log.c builtin/merge.c +#: blame.c builtin/bisect.c builtin/commit.c builtin/log.c builtin/merge.c #: builtin/pack-objects.c builtin/shortlog.c midx-write.c pack-bitmap.c #: remote.c sequencer.c submodule.c msgid "revision walk setup failed" @@ -2035,12 +2056,10 @@ 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 @@ -2208,7 +2227,7 @@ msgstr "測試執行" #: builtin/add.c builtin/check-ignore.c builtin/commit.c #: builtin/count-objects.c builtin/fsck.c builtin/log.c builtin/mv.c -#: builtin/read-tree.c +#: builtin/read-tree.c builtin/refs.c msgid "be verbose" msgstr "詳細輸出" @@ -2601,7 +2620,7 @@ msgstr "" #: builtin/am.c builtin/reset.c #, c-format msgid "Could not parse object '%s'." -msgstr "無法解析「%s」物件。" +msgstr "無法解析物件「%s」。" #: builtin/am.c msgid "failed to clean index" @@ -2694,7 +2713,7 @@ msgstr "n" #: builtin/am.c builtin/branch.c builtin/bugreport.c builtin/cat-file.c #: builtin/clone.c builtin/diagnose.c builtin/for-each-ref.c builtin/init-db.c #: builtin/ls-files.c builtin/ls-tree.c builtin/refs.c builtin/replace.c -#: builtin/tag.c builtin/verify-tag.c +#: builtin/submodule--helper.c builtin/tag.c builtin/verify-tag.c msgid "format" msgstr "format" @@ -2822,6 +2841,22 @@ msgstr "git archive:通訊協定錯誤" msgid "git archive: expected a flush" msgstr "git archive:預期收到 flush 封包" +#: builtin/backfill.c +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +#: builtin/backfill.c +msgid "problem loading sparse-checkout" +msgstr "載入稀疏簽出時發生問題" + +#: builtin/backfill.c +msgid "Minimum number of objects to request at a time" +msgstr "一次請求的最小物件數量" + +#: builtin/backfill.c +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "將缺少的物件限制於目前的稀疏簽出" + #: builtin/bisect.c msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" @@ -2853,22 +2888,22 @@ msgstr "git bisect run <cmd> [<arg>...]" #: builtin/bisect.c #, c-format msgid "cannot open file '%s' in mode '%s'" -msgstr "無法以「%2$s」模式開啟「%1$s」檔案" +msgstr "無法以「%2$s」模式開啟檔案「%1$s」" #: builtin/bisect.c #, c-format msgid "could not write to file '%s'" -msgstr "無法寫入「%s」檔案" +msgstr "無法寫入檔案「%s」" #: builtin/bisect.c #, c-format msgid "cannot open file '%s' for reading" -msgstr "無法開啟「%s」檔案進行讀取" +msgstr "無法開啟檔案「%s」來讀取" #: builtin/bisect.c #, c-format msgid "'%s' is not a valid term" -msgstr "「%s」不是有效術語" +msgstr "「%s」不是有效的術語" #: builtin/bisect.c #, c-format @@ -2898,7 +2933,7 @@ msgstr "「%s」不是有效的提交" #, c-format msgid "" "could not check out original HEAD '%s'. Try 'git bisect reset <commit>'." -msgstr "不能簽出原始 HEAD「%s」。請嘗試「git bisect reset <commit>」。" +msgstr "無法簽出原本的 HEAD「%s」。請嘗試「git bisect reset <commit>」。" #: builtin/bisect.c #, c-format @@ -2918,7 +2953,7 @@ msgstr "無法開啟檔案「%s」" #: builtin/bisect.c #, c-format msgid "Invalid command: you're currently in a %s/%s bisect" -msgstr "命令無效:您目前正處於二分搜尋 %s/%s 的狀態" +msgstr "命令無效:您正處於二分搜尋 %s/%s 的狀態" #: builtin/bisect.c #, c-format @@ -2990,10 +3025,6 @@ msgstr "" "傳入「git bisect terms」的 %s 引數無效。\n" "支援的選項有:--term-good|--term-old 和 --term-bad|--term-new。" -#: builtin/bisect.c -msgid "revision walk setup failed\n" -msgstr "修訂版遍歷設定失敗\n" - #: builtin/bisect.c #, c-format msgid "could not open '%s' for appending" @@ -3006,7 +3037,7 @@ msgstr "「 」不是有效術語" #: builtin/bisect.c #, c-format msgid "unrecognized option: '%s'" -msgstr "無法識別選項:「%s」" +msgstr "不認識選項:「%s」" #: builtin/bisect.c #, c-format @@ -3248,7 +3279,7 @@ msgstr "顯示作者信箱而非名稱(預設值:off)" msgid "ignore whitespace differences" msgstr "忽略空白差異" -#: builtin/blame.c builtin/log.c +#: builtin/blame.c builtin/clone.c builtin/log.c msgid "rev" msgstr "rev" @@ -3445,7 +3476,7 @@ msgstr "無法解析格式化字串" #: builtin/branch.c msgid "could not resolve HEAD" -msgstr "無法解析 HEAD 指標" +msgstr "無法解析 HEAD" #: builtin/branch.c #, c-format @@ -3760,11 +3791,6 @@ msgstr "" msgid "git version:\n" msgstr "git 版本:\n" -#: builtin/bugreport.c -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() 失敗,錯誤:「%s」(%d)\n" - #: builtin/bugreport.c msgid "compiler info: " msgstr "編譯器資訊: " @@ -4225,9 +4251,16 @@ msgid "also read contacts from stdin" msgstr "亦從 stdin 讀取聯絡地址" #: builtin/check-mailmap.c -#, c-format -msgid "unable to parse contact: %s" -msgstr "無法解析聯絡地址:%s" +msgid "read additional mailmap entries from file" +msgstr "從檔案讀取其他 mailmap 項目" + +#: builtin/check-mailmap.c +msgid "blob" +msgstr "資料物件" + +#: builtin/check-mailmap.c +msgid "read additional mailmap entries from blob" +msgstr "從 blob 讀取其他 mailmap 項目" #: builtin/check-mailmap.c msgid "no contacts specified" @@ -4634,6 +4667,11 @@ msgstr "路徑不能與切換分支同時使用" msgid "'%s' cannot be used with switching branches" msgstr "「%s」不能與切換分支同時使用" +#: builtin/checkout.c +#, c-format +msgid "'%s' needs the paths to check out" +msgstr "「%s」需要指定要簽出的路徑" + #: builtin/checkout.c #, c-format msgid "'%s' cannot be used with '%s'" @@ -4662,7 +4700,7 @@ msgstr "未知的衝突輸出風格「%s」" msgid "perform a 3-way merge with the new branch" msgstr "和新分支進行三方合併" -#: builtin/checkout.c builtin/log.c parse-options.h +#: builtin/checkout.c builtin/log.c builtin/range-diff.c parse-options.h msgid "style" msgstr "style" @@ -4691,8 +4729,8 @@ msgid "update ignored files (default)" msgstr "更新忽略的檔案(預設值)" #: builtin/checkout.c -msgid "do not check if another worktree is holding the given ref" -msgstr "不檢查其他工作區是否正在佔用指定的引用" +msgid "do not check if another worktree is using this branch" +msgstr "不檢查其他工作區是否正在使用此分支" #: builtin/checkout.c msgid "checkout our version for unmerged files" @@ -4848,7 +4886,7 @@ msgstr "無法移除 %s" #: builtin/clean.c #, c-format msgid "could not lstat %s\n" -msgstr "不能對 %s 進行 lstat\n" +msgstr "無法對 %s 進行 lstat\n" #: builtin/clean.c msgid "Refusing to remove current working directory\n" @@ -4983,8 +5021,112 @@ msgid "clean.requireForce is true and -f not given: refusing to clean" msgstr "clean.requireForce 是 true 且未給定 -f 選項:拒絕清理" #: builtin/clone.c -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<options>] [--] <repo> [<dir>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info: 不能為「%s」新增一個備用:%s\n" + +#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c +#, c-format +msgid "failed to stat '%s'" +msgstr "對「%s」呼叫 stat 失敗" + +#: builtin/clone.c +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s 存在且不是目錄" + +#: builtin/clone.c +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "「%s」是符號連結,故不能使用 --local 複製" + +#: builtin/clone.c +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "無法在「%s」上啟動迭代器" + +#: builtin/clone.c +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "符號連結「%s」已存在,拒絕使用 --local 複製" + +#: builtin/clone.c compat/precompose_utf8.c +#, c-format +msgid "failed to unlink '%s'" +msgstr "無法刪除「%s」" + +#: builtin/clone.c +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "無法檢查位於「%s」的硬連結" + +#: builtin/clone.c +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "硬連結與位於「%s」的來源不同" + +#: builtin/clone.c +#, c-format +msgid "failed to create link '%s'" +msgstr "建立連結「%s」失敗" + +#: builtin/clone.c +#, c-format +msgid "failed to copy file to '%s'" +msgstr "複製檔案至「%s」失敗" + +#: builtin/clone.c refs/files-backend.c +#, c-format +msgid "failed to iterate over '%s'" +msgstr "無法在「%s」上迭代" + +#: builtin/clone.c +#, c-format +msgid "done.\n" +msgstr "完成。\n" + +#: builtin/clone.c +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"複製成功,但是簽出失敗。\n" +"您可以透過「git status」檢查哪些已被簽出,然後使用指令\n" +"「git restore --source=HEAD :/」重試\n" + +#: builtin/clone.c fetch-pack.c +msgid "remote did not send all necessary objects" +msgstr "遠端沒有傳送所有必需的物件" + +#: builtin/clone.c +#, c-format +msgid "unable to update %s" +msgstr "不能更新 %s" + +#: builtin/clone.c +msgid "failed to initialize sparse-checkout" +msgstr "無法初始化稀疏簽出" + +#: builtin/clone.c +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "遠端 HEAD 指向不存在的引用,無法簽出" + +#: builtin/clone.c +msgid "unable to checkout working tree" +msgstr "不能簽出工作區" + +#: builtin/clone.c +msgid "unable to write parameters to config file" +msgstr "無法將參數寫入組態檔案" + +#: builtin/clone.c +msgid "cannot repack to clean up" +msgstr "無法執行 repack 來清理" + +#: builtin/clone.c +msgid "cannot unlink temporary alternates file" +msgstr "無法刪除暫存 alternates 檔案" #: builtin/clone.c msgid "don't clone shallow repository" @@ -5056,6 +5198,10 @@ msgstr "使用 <name> 而不是「origin」追蹤上游" msgid "checkout <branch> instead of the remote's HEAD" msgstr "簽出 <branch> 而不是遠端 HEAD" +#: builtin/clone.c +msgid "clone single revision <rev> and check out" +msgstr "複製單個修訂版 <rev> 並簽出" + #: builtin/clone.c msgid "path to git-upload-pack on the remote" msgstr "遠端 git-upload-pack 路徑" @@ -5072,22 +5218,21 @@ msgstr "建立指定深度的淺層複製" 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" +#: builtin/clone.c builtin/fetch.c builtin/pull.c +msgid "ref" +msgstr "ref" #: builtin/clone.c builtin/fetch.c builtin/pull.c -msgid "deepen history of shallow clone, excluding rev" -msgstr "取得更多淺層複製的過去歷史記錄,除了特定修訂版" +msgid "deepen history of shallow clone, excluding ref" +msgstr "取得更多淺層複製的過往歷史記錄,除了特定修訂版" #: builtin/clone.c builtin/submodule--helper.c msgid "clone only one branch, HEAD or --branch" msgstr "只複製一個分支、HEAD 或 --branch" #: builtin/clone.c -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "不要複製任何標籤,之後取得也不要追蹤這些標籤" +msgid "clone tags, and make later fetches not to follow them" +msgstr "複製標籤,並使後續抓取不要追蹤這些標籤" #: builtin/clone.c msgid "any cloned submodules will be shallow" @@ -5101,7 +5246,7 @@ msgstr "gitdir" msgid "separate git dir from working tree" msgstr "git 目錄和工作區分離" -#: builtin/clone.c builtin/init-db.c +#: builtin/clone.c builtin/init-db.c builtin/submodule--helper.c msgid "specify the reference format to use" msgstr "指定要使用的引用格式" @@ -5144,117 +5289,8 @@ msgid "a URI for downloading bundles before fetching from origin remote" msgstr "在從 origin 遠端抓取前,用來下載套件包的 URI" #: builtin/clone.c -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: 不能為 '%s' 新增一個備用:%s\n" - -#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c -#, c-format -msgid "failed to stat '%s'" -msgstr "對 '%s' 呼叫 stat 失敗" - -#: builtin/clone.c -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s 存在且不是一個目錄" - -#: builtin/clone.c -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "「%s」是個符號連結,故不能使用 --local 複製" - -#: builtin/clone.c -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "無法在 '%s' 上啟動疊代器" - -#: builtin/clone.c -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "「%s」符號連結已存在,拒絕使用 --local 複製" - -#: builtin/clone.c compat/precompose_utf8.c -#, c-format -msgid "failed to unlink '%s'" -msgstr "無法刪除「%s」" - -#: builtin/clone.c -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "無法檢查位於「%s」的硬連結" - -#: builtin/clone.c -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "硬連結與位於 '%s' 的來源不同" - -#: builtin/clone.c -#, c-format -msgid "failed to create link '%s'" -msgstr "建立連結 '%s' 失敗" - -#: builtin/clone.c -#, c-format -msgid "failed to copy file to '%s'" -msgstr "複製檔案至 '%s' 失敗" - -#: builtin/clone.c -#, c-format -msgid "failed to iterate over '%s'" -msgstr "無法在 '%s' 上疊代" - -#: builtin/clone.c -#, c-format -msgid "done.\n" -msgstr "完成。\n" - -#: builtin/clone.c -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"複製成功,但是簽出失敗。\n" -"您可以透過 'git status' 檢查哪些已被簽出,然後使用指令\n" -"'git restore --source=HEAD :/' 重試\n" - -#: builtin/clone.c -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "找不到要複製的遠端分支 %s。" - -#: builtin/clone.c fetch-pack.c -msgid "remote did not send all necessary objects" -msgstr "遠端沒有傳送所有必需的物件" - -#: builtin/clone.c -#, c-format -msgid "unable to update %s" -msgstr "不能更新 %s" - -#: builtin/clone.c -msgid "failed to initialize sparse-checkout" -msgstr "無法初始化稀疏簽出" - -#: builtin/clone.c -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "遠端 HEAD 指向一個不存在的引用,無法簽出" - -#: builtin/clone.c -msgid "unable to checkout working tree" -msgstr "不能簽出工作區" - -#: builtin/clone.c -msgid "unable to write parameters to config file" -msgstr "無法將參數寫入設定檔案" - -#: builtin/clone.c -msgid "cannot repack to clean up" -msgstr "無法執行 repack 來清理" - -#: builtin/clone.c -msgid "cannot unlink temporary alternates file" -msgstr "無法刪除暫存 alternates 檔案" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<options>] [--] <repo> [<dir>]" #: builtin/clone.c msgid "Too many arguments." @@ -5264,7 +5300,8 @@ msgstr "太多參數。" msgid "You must specify a repository to clone." msgstr "您必須指定要複製的版本庫。" -#: builtin/clone.c builtin/init-db.c builtin/refs.c setup.c +#: builtin/clone.c builtin/init-db.c builtin/refs.c builtin/submodule--helper.c +#: setup.c #, c-format msgid "unknown ref storage format '%s'" msgstr "未知的引用儲存格式「%s」" @@ -5297,12 +5334,12 @@ msgstr "工作區 '%s' 已經存在。" #: builtin/clone.c builtin/difftool.c builtin/log.c builtin/worktree.c #, c-format msgid "could not create leading directories of '%s'" -msgstr "不能為 '%s' 建立先導目錄" +msgstr "無法為「%s」建立前導目錄" #: builtin/clone.c #, c-format msgid "could not create work tree dir '%s'" -msgstr "不能建立工作區目錄 '%s'" +msgstr "無法建立工作區目錄「%s」" #: builtin/clone.c #, c-format @@ -5377,7 +5414,12 @@ msgstr "遠端傳輸回報錯誤" #: builtin/clone.c #, c-format msgid "Remote branch %s not found in upstream %s" -msgstr "遠端分支 %s 在上游 %s 未發現" +msgstr "上游 %2$s 上找不到遠端分支 %1$s" + +#: builtin/clone.c +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "上游 %2$s 上找不到遠端修訂版 %1$s" #: builtin/clone.c msgid "You appear to have cloned an empty repository." @@ -5442,7 +5484,8 @@ msgstr "" "[no-]progress]\n" " <split-options>" -#: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c +#: builtin/commit-graph.c builtin/fetch.c builtin/gc.c builtin/log.c +#: builtin/repack.c msgid "dir" msgstr "目錄" @@ -5467,7 +5510,7 @@ msgstr "無法開啟提交圖鏈「%s」" #: builtin/commit-graph.c #, c-format msgid "unrecognized --split argument, %s" -msgstr "無法識別的 --split 參數,%s" +msgstr "不認識的 --split 參數,%s" #: builtin/commit-graph.c #, c-format @@ -5599,10 +5642,21 @@ msgid "git commit-tree: failed to read" msgstr "git commit-tree:讀取失敗" #: builtin/commit.c -msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +#| msgid "" +#| "git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +#| " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" +#| "reword):]<commit>]\n" +#| " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" +#| " [--allow-empty-message] [--no-verify] [-e] [--" +#| "author=<author>]\n" +#| " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" +#| " [-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" +#| " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" +#| " [--] [<pathspec>...]" +msgid "" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -5610,9 +5664,9 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...] [-S[<keyid>]]\n" " [--] [<pathspec>...]" msgstr "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" -"reword):]<commit>)]\n" +"reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\n" " [--date=<date>] [--cleanup=<mode>] [--[no-]status]\n" @@ -5761,12 +5815,12 @@ msgstr "(正從標準輸入中讀取日誌訊息)\n" #: builtin/commit.c msgid "could not read log from standard input" -msgstr "不能從標準輸入中讀取日誌訊息" +msgstr "無法從標準輸入中讀取記錄" #: builtin/commit.c #, c-format msgid "could not read log file '%s'" -msgstr "不能讀取日誌檔案 '%s'" +msgstr "無法讀取日誌檔案「%s」" #: builtin/commit.c #, c-format @@ -5775,11 +5829,11 @@ msgstr "「%s」和「%s:%s」選項不得同時使用" #: builtin/commit.c msgid "could not read SQUASH_MSG" -msgstr "不能讀取 SQUASH_MSG" +msgstr "無法讀取 SQUASH_MSG" #: builtin/commit.c msgid "could not read MERGE_MSG" -msgstr "不能讀取 MERGE_MSG" +msgstr "無法讀取 MERGE_MSG" #: builtin/commit.c bundle.c rerere.c sequencer.c #, c-format @@ -5788,7 +5842,7 @@ msgstr "無法開啟「%s」" #: builtin/commit.c msgid "could not write commit template" -msgstr "不能寫提交範本" +msgstr "無法寫入提交模板" #: builtin/commit.c #, c-format @@ -6164,7 +6218,7 @@ msgstr "允許空的提交說明" #: builtin/commit.c sequencer.c msgid "could not parse HEAD commit" -msgstr "不能解析 HEAD 提交" +msgstr "無法解析 HEAD 提交" #: builtin/commit.c #, c-format @@ -6173,12 +6227,12 @@ msgstr "損壞的 MERGE_HEAD 檔案(%s)" #: builtin/commit.c msgid "could not read MERGE_MODE" -msgstr "不能讀取 MERGE_MODE" +msgstr "無法讀取 MERGE_MODE" #: builtin/commit.c #, c-format msgid "could not read commit message: %s" -msgstr "不能讀取提交說明:%s" +msgstr "無法讀取提交說明:%s" #: builtin/commit.c #, c-format @@ -6211,11 +6265,10 @@ msgstr "git config list [<檔案選項>] [<顯示選項>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " -"<name>" +"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" msgstr "" -"git config get [<檔案選項>] [<顯示選項>] [--includes] [--all] [--regexp=<常規" -"表示式>] [--value=<值>] [--fixed-value] [--default=<預設值>] <名稱>" +"git config get [<檔案選項>] [<顯示選項>] [--includes] [--all] [--regexp] [--" +"value=<值>] [--fixed-value] [--default=<預設值>] <名稱>" #: builtin/config.c msgid "" @@ -6228,10 +6281,10 @@ msgstr "" #: builtin/config.c msgid "" "git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"<name>" msgstr "" -"git config unset [<檔案選項>] [--all] [--value=<值>] [--fixed-value] <名稱> <" -"值>" +"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"<name>" #: builtin/config.c msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -6249,6 +6302,15 @@ msgstr "git config edit [<檔案選項>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" +#: builtin/config.c +msgid "" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"<name>" +msgstr "" +"git config get [<檔案選項>] [<顯示選項>] [--includes] [--all] [--regexp=<常規" +"表示式>] [--value=<值>] [--fixed-value] [--default=<預設值>] <名稱>" + #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " @@ -6354,7 +6416,7 @@ msgstr "除了顯示組態值,額外顯示其鍵名" #: builtin/config.c #, c-format msgid "unrecognized --type argument, %s" -msgstr "無法識別的 --type 參數,%s" +msgstr "不認識的 --type 參數,%s" #: builtin/config.c msgid "only one type at a time" @@ -6768,12 +6830,8 @@ msgstr "已遍歷 %lu 個提交\n" #: builtin/describe.c #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"發現多於 %i 個標籤,列出最近的 %i 個\n" -"在 %s 放棄搜尋\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "找到 %i 個標籤;在 %s 放棄搜尋\n" #: builtin/describe.c #, c-format @@ -6961,7 +7019,7 @@ msgstr "工作區檔案被留了下來。" #: builtin/difftool.c sequencer.c #, c-format msgid "could not copy '%s' to '%s'" -msgstr "不能複製 '%s' 至 '%s'" +msgstr "無法將「%s」複製到「%s」" #: builtin/difftool.c #, c-format @@ -7259,8 +7317,8 @@ msgstr "" #: builtin/fetch.c #, c-format -msgid "%s did not send all necessary objects\n" -msgstr "%s 未傳送所有必需的物件\n" +msgid "%s did not send all necessary objects" +msgstr "%s 未傳送所有必需的物件" #: builtin/fetch.c #, c-format @@ -7308,8 +7366,8 @@ msgstr "選項「%s」的值「%s」對 %s 無效" #: builtin/fetch.c #, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "選項「%s」被 %s 忽略\n" +msgid "option \"%s\" is ignored for %s" +msgstr "選項「%s」被 %s 忽略" #: builtin/fetch.c object-file.c #, c-format @@ -7321,6 +7379,21 @@ msgstr "%s 不是一個有效的物件" msgid "the object %s does not exist" msgstr "%s 物件不存在" +#: builtin/fetch.c +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"執行「git remote set-head %s %s」來跟進此差異,或者\n" +"如果您不想看到這則訊息,請將「remote.%s.followRemoteHEAD」組態選項\n" +"設定成別的值。更具體些來說,執行\n" +"「git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s」\n" +"會停用這個警告,直到遠端將 HEAD 改為指向其他東西。" + #: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "檢測到多分支,和 --set-upstream 不相容" @@ -7361,12 +7434,12 @@ msgstr "正在取得 %s\n" #: builtin/fetch.c #, c-format msgid "could not fetch %s" -msgstr "不能取得 %s" +msgstr "無法取得 %s" #: builtin/fetch.c #, c-format msgid "could not fetch '%s' (exit code: %d)\n" -msgstr "無法取得 '%s'(離開碼:%d)\n" +msgstr "無法取得「%s」(離開碼:%d)\n" #: builtin/fetch.c msgid "" @@ -7491,6 +7564,10 @@ msgstr "引用映射" msgid "specify fetch refmap" msgstr "指定取得動作的引用映射" +#: builtin/fetch.c builtin/pull.c builtin/rebase.c builtin/replay.c +msgid "revision" +msgstr "revision" + #: builtin/fetch.c builtin/pull.c msgid "report that we have only objects reachable from this object" msgstr "報告我們只擁有從該物件開始可以取得的物件" @@ -7752,18 +7829,18 @@ msgstr "懸空 %s %s" #: builtin/fsck.c msgid "could not create lost-found" -msgstr "不能建立 lost-found" +msgstr "無法建立 lost-found" #: builtin/fsck.c builtin/gc.c builtin/rebase.c rebase-interactive.c rerere.c #: sequencer.c #, c-format msgid "could not write '%s'" -msgstr "不能寫入 '%s'" +msgstr "無法寫入「%s」" #: builtin/fsck.c #, c-format msgid "could not finish '%s'" -msgstr "不能完成 '%s'" +msgstr "無法完成「%s」" #: builtin/fsck.c #, c-format @@ -8033,7 +8110,7 @@ msgstr "無法啟動 fsmonitor 監聽執行緒" #: builtin/fsmonitor--daemon.c msgid "could not start fsmonitor health thread" -msgstr "無法啟動 fsmonitor 健康監聽執行緒" +msgstr "無法啟動 fsmonitor 健康檢查執行緒" #: builtin/fsmonitor--daemon.c msgid "could not initialize listener thread" @@ -8041,7 +8118,7 @@ msgstr "無法初始化監聽執行緒" #: builtin/fsmonitor--daemon.c msgid "could not initialize health thread" -msgstr "無法初始化健康監聽執行緒" +msgstr "無法初始化健康檢查執行緒" #: builtin/fsmonitor--daemon.c #, c-format @@ -8154,6 +8231,10 @@ msgstr "更徹底(增加執行時間)" msgid "enable auto-gc mode" msgstr "啟用自動垃圾回收模式" +#: builtin/gc.c +msgid "perform garbage collection in the background" +msgstr "在背景執行垃圾回收" + #: builtin/gc.c msgid "force running gc even if there may be another gc running" msgstr "強制執行 gc 即使另外一個 gc 正在執行" @@ -8162,6 +8243,10 @@ msgstr "強制執行 gc 即使另外一個 gc 正在執行" msgid "repack all other packs except the largest pack" msgstr "除了最大的包之外,對所有其它包重新打包" +#: builtin/gc.c builtin/repack.c +msgid "pack prefix to store a pack containing pruned objects" +msgstr "將前綴打包並儲存為包含已剪除物件的包" + #: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" @@ -8211,7 +8296,7 @@ msgstr "不允許 --no-schedule" #: builtin/gc.c #, c-format msgid "unrecognized --schedule argument '%s'" -msgstr "無法識別的 --schedule 引數 '%s'" +msgstr "不認識的 --schedule 引數 '%s'" #: builtin/gc.c msgid "failed to write commit-graph" @@ -8270,6 +8355,10 @@ msgstr "不能多次選取 '%s' 作業" msgid "run tasks based on the state of the repository" msgstr "基於版本庫狀態執行作業" +#: builtin/gc.c +msgid "perform maintenance in the background" +msgstr "在背景執行維護" + #: builtin/gc.c msgid "frequency" msgstr "frequency" @@ -8381,7 +8470,7 @@ msgstr "無法執行 systemctl" #: builtin/gc.c #, c-format msgid "unrecognized --scheduler argument '%s'" -msgstr "無法識別的 --scheduler 引數 '%s'" +msgstr "不認識的 --scheduler 引數 '%s'" #: builtin/gc.c msgid "neither systemd timers nor crontab are available" @@ -8393,8 +8482,26 @@ msgid "%s scheduler is not available" msgstr "無法使用 %s 排程器" #: builtin/gc.c -msgid "another process is scheduling background maintenance" -msgstr "其他處理程序正在排定背景維護工作" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"無法建立「%s.lock」:%s。\n" +"\n" +"似乎有另一個排定的 git-maintenance(1) 程序正在此\n" +"版本庫中執行。請確保沒有其他維護程序正在執行,\n" +"然後再試一次。如果仍然失敗,可能是先前的\n" +"git-maintenance(1) 程序在這個版本庫中意外中斷:\n" +"請手動移除檔案以繼續。" + +#: builtin/gc.c +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "無法取得用來進行排定背景維護的鎖" #: builtin/gc.c msgid "git maintenance start [--scheduler=<scheduler>]" @@ -8434,7 +8541,6 @@ msgstr "grep:無法建立執行緒:%s" msgid "invalid number of threads specified (%d) for %s" msgstr "為 %2$s 設定的執行緒數 (%1$d) 無效" -#. #-#-#-#-# grep.c.po #-#-#-#-# #. TRANSLATORS: %s is the configuration #. variable for tweaking threads, currently #. grep.threads @@ -8684,7 +8790,7 @@ msgstr "--open-files-in-pager 僅用於工作區" #: builtin/grep.c msgid "--[no-]exclude-standard cannot be used for tracked contents" -msgstr "--[no-]exclude-standard 不能用於已追蹤內容" +msgstr "--[no-]exclude-standard 無法用於已追蹤內容" #: builtin/grep.c msgid "both --cached and trees are given" @@ -8782,7 +8888,7 @@ msgstr "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>|<doc>]" #: builtin/help.c #, c-format msgid "unrecognized help format '%s'" -msgstr "無法識別的協助格式 '%s'" +msgstr "不認識的協助格式 '%s'" #: builtin/help.c msgid "Failed to start emacsclient." @@ -9114,10 +9220,31 @@ msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "鏈長 = %d: %lu 物件" +#: builtin/index-pack.c +msgid "could not start pack-objects to repack local links" +msgstr "無法啟動 pack-objects 來重新打包本機連結" + +#: builtin/index-pack.c +msgid "failed to feed local object to pack-objects" +msgstr "無法將本機物件喂給 pack-objects" + +#: builtin/index-pack.c +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "index-pack:只預期接受來自 pack-objects 的完整十六進位物件 ID。" + +#: builtin/index-pack.c +msgid "could not finish pack-objects to repack local links" +msgstr "無法結束 pack-objects 來重新封包" + #: builtin/index-pack.c msgid "Cannot come back to cwd" msgstr "無法返回目前工作目錄" +#: builtin/index-pack.c builtin/unpack-objects.c +#, c-format +msgid "bad --pack_header: %s" +msgstr "無效的 --pack_header:%s" + #: builtin/index-pack.c #, c-format msgid "bad %s" @@ -9128,6 +9255,10 @@ msgstr "錯誤選項 %s" msgid "unknown hash algorithm '%s'" msgstr "未知的「%s」雜湊算法" +#: builtin/index-pack.c +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor 不能與封包名稱一起使用" + #: builtin/index-pack.c msgid "--stdin requires a git repository" msgstr "--stdin 需要一個 git 版本庫" @@ -9213,7 +9344,7 @@ msgstr "" #: builtin/interpret-trailers.c wrapper.c #, c-format msgid "could not stat %s" -msgstr "不能對 %s 呼叫 stat" +msgstr "無法 stat %s" #: builtin/interpret-trailers.c #, c-format @@ -9227,21 +9358,21 @@ msgstr "檔案 %s 使用者不可寫" #: builtin/interpret-trailers.c msgid "could not open temporary file" -msgstr "不能開啟暫存檔" +msgstr "無法開啟暫存檔" #: builtin/interpret-trailers.c #, c-format msgid "could not read input file '%s'" -msgstr "不能讀取輸入檔案 '%s'" +msgstr "無法讀取輸入檔案「%s」" #: builtin/interpret-trailers.c builtin/mktag.c imap-send.c msgid "could not read from stdin" -msgstr "不能自標準輸入讀取" +msgstr "無法從標準輸入讀取" #: builtin/interpret-trailers.c #, c-format msgid "could not rename temporary file to %s" -msgstr "不能重新命名暫存檔為 %s" +msgstr "無法將暫存檔重新命名為 %s" #: builtin/interpret-trailers.c msgid "edit files in place" @@ -9345,7 +9476,7 @@ msgstr "追蹤 <開始>,<結束> 範圍中橫列或 <檔案> 中> :<函數名稱 #: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c #, c-format msgid "unrecognized argument: %s" -msgstr "無法識別的引數:%s" +msgstr "不認識的引數:%s" #: builtin/log.c msgid "-L<range>:<file> cannot be used with pathspec" @@ -9356,10 +9487,6 @@ msgstr "-L<範圍>:<檔案> 和 pathspec 不能同時使用" msgid "Final output: %d %s\n" msgstr "最終輸出:%d %s\n" -#: builtin/log.c -msgid "unable to create temporary object directory" -msgstr "無法建立暫存物件目錄" - #: builtin/log.c #, c-format msgid "git show %s: bad file" @@ -9368,7 +9495,7 @@ msgstr "git show %s: 損壞的檔案" #: builtin/log.c #, c-format msgid "could not read object %s" -msgstr "不能讀取物件 %s" +msgstr "無法讀取物件 %s" #: builtin/log.c #, c-format @@ -9435,7 +9562,7 @@ msgstr "無法將 '%s' 解析為一個有效引用" #: builtin/log.c msgid "could not find exact merge base" -msgstr "不能找到準確的合併基礎" +msgstr "找不到準確的合併基礎" #: builtin/log.c msgid "" @@ -9688,7 +9815,7 @@ msgstr "--remerge-diff 無意義" #: builtin/log.c builtin/submodule--helper.c rerere.c submodule.c #, c-format msgid "could not create directory '%s'" -msgstr "不能建立目錄 '%s'" +msgstr "無法建立「%s」目錄" #: builtin/log.c msgid "--interdiff requires --cover-letter or single patch" @@ -9737,7 +9864,7 @@ msgstr "git cherry [-v] [<上游> [<頭> [<限制>]]]" #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" -msgstr "不能找到追蹤的遠端分支,請手動指定 <上游>。\n" +msgstr "無法找到追蹤的遠端分支,請手動指定 <上游>。\n" #: builtin/ls-files.c builtin/ls-tree.c #, c-format @@ -9861,7 +9988,7 @@ msgid "" "--format cannot be used with -s, -o, -k, -t, --resolve-undo, --deduplicate, " "--eol" msgstr "" -"--format 不能和 -s、-o、-k、-t、--resolve-undo、--deduplicate、--eol 一起使用" +"--format 無法和 -s、-o、-k、-t、--resolve-undo、--deduplicate、--eol 一起使用" #: builtin/ls-remote.c msgid "" @@ -10086,18 +10213,6 @@ msgstr "使用基於 diff3 的合併" msgid "use a zealous diff3 based merge" msgstr "使用基於 zealous diff3 的合併" -#: builtin/merge-file.c -msgid "for conflicts, use our version" -msgstr "如果衝突,使用我們的版本" - -#: builtin/merge-file.c -msgid "for conflicts, use their version" -msgstr "如果衝突,使用他們的版本" - -#: builtin/merge-file.c -msgid "for conflicts, use a union version" -msgstr "如果衝突,使用聯合版本" - #: builtin/merge-file.c diff.c msgid "<algorithm>" msgstr "<演算法>" @@ -10135,7 +10250,7 @@ msgstr "未知選項 %s" #: builtin/merge-recursive.c #, c-format msgid "could not parse object '%s'" -msgstr "不能解析物件 '%s'" +msgstr "無法解析物件「%s」" #: builtin/merge-recursive.c #, c-format @@ -10150,7 +10265,7 @@ msgstr "不能處理兩個頭合併之外的任何動作。" #: builtin/merge-recursive.c #, c-format msgid "could not resolve ref '%s'" -msgstr "無法解析引用 '%s'" +msgstr "無法解析引用「%s」" #: builtin/merge-recursive.c #, c-format @@ -10232,11 +10347,6 @@ msgstr "未知的策略選項:-X%s" msgid "malformed input line: '%s'." msgstr "格式錯誤的輸入行:'%s'。" -#: builtin/merge-tree.c -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "無法繼續合併:從 %d 收到的結果不乾淨" - #: builtin/merge.c msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<選項>] [<提交>...]" @@ -10253,7 +10363,7 @@ msgstr "選項 `%s' 需要一個值" #: builtin/merge.c #, c-format msgid "Could not find merge strategy '%s'.\n" -msgstr "不能找到合併策略 '%s'。\n" +msgstr "找不到合併策略「%s」。\n" #: builtin/merge.c #, c-format @@ -10341,7 +10451,7 @@ msgstr "繞過 pre-merge-commit 和 commit-msg 掛鉤" #: builtin/merge.c msgid "could not run stash." -msgstr "不能執行貯存。" +msgstr "無法執行貯存。" #: builtin/merge.c msgid "stash failed" @@ -10393,7 +10503,7 @@ msgstr "不能寫入索引。" msgid "Not handling anything other than two heads merge." msgstr "未處理兩個頭合併之外的任何動作。" -#: builtin/merge.c +#: builtin/merge.c builtin/sparse-checkout.c #, c-format msgid "unable to write %s" msgstr "不能寫 %s" @@ -10401,7 +10511,7 @@ msgstr "不能寫 %s" #: builtin/merge.c #, c-format msgid "Could not read from '%s'" -msgstr "不能從 '%s' 讀取" +msgstr "無法從「%s」進行讀取" #: builtin/merge.c #, c-format @@ -10468,7 +10578,7 @@ msgstr "環境 '%2$s' 中存在壞的取值 '%1$s'" #: builtin/merge.c editor.c read-cache.c wrapper.c #, c-format msgid "could not close '%s'" -msgstr "不能關閉 '%s'" +msgstr "無法關閉「%s」" #: builtin/merge.c #, c-format @@ -10684,6 +10794,10 @@ msgstr "計算多包位圖時要重複使用的包" msgid "write multi-pack bitmap" msgstr "寫入多包位圖" +#: builtin/multi-pack-index.c +msgid "write a new incremental MIDX" +msgstr "寫入新的增量 MIDX" + #: builtin/multi-pack-index.c msgid "write multi-pack index containing only given indexes" msgstr "寫入只包含指定索引的多包索引" @@ -10854,11 +10968,11 @@ msgstr "git notes [--ref <註解引用>] [list [<物件>]]" msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" @@ -10868,11 +10982,11 @@ msgstr "git notes [--ref <註解引用>] copy [-f] <來源物件> <目標物件> msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" @@ -10953,7 +11067,7 @@ msgstr "為下面的物件寫/編輯說明:" #: builtin/notes.c msgid "could not read 'show' output" -msgstr "不能讀取 'show' 的輸出" +msgstr "無法讀取「show」的輸出" #: builtin/notes.c #, c-format @@ -10976,7 +11090,7 @@ msgstr "註解內容被留在 %s 中" #: builtin/notes.c builtin/tag.c #, c-format msgid "could not open or read '%s'" -msgstr "不能開啟或讀取 '%s'" +msgstr "無法開啟或讀取「%s」" #: builtin/notes.c #, c-format @@ -11023,6 +11137,10 @@ msgstr "註解內容到一個檔案中" msgid "reuse and edit specified note object" msgstr "重用和編輯指定的註解物件" +#: builtin/notes.c +msgid "edit note message in editor" +msgstr "在編輯器中編輯備註訊息" + #: builtin/notes.c msgid "reuse specified note object" msgstr "重用指定的註解物件" @@ -11245,6 +11363,15 @@ msgid "" "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" msgstr "git pack-objects [<選項>] <前綴名稱> [< <引用列表> | < <物件列表>]" +#: builtin/pack-objects.c +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "無效的 --name-hash-version 選項:%d" + +#: builtin/pack-objects.c +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "目前 --write-bitmap-index 需要指定 --name-hash-version=1" + #: builtin/pack-objects.c #, c-format msgid "" @@ -11321,7 +11448,7 @@ msgstr "%s 的 delta 基準位移越界" #: builtin/pack-objects.c msgid "Counting objects" -msgstr "物件計數中" +msgstr "正在計算物件數量" #: builtin/pack-objects.c pack-bitmap.c #, c-format @@ -11381,8 +11508,8 @@ msgid "" "value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" "hash> <uri>' (got '%s')" msgstr "" -"uploadpack.blobpackfileuri 的值格式必須為 '<object-hash> <pack-hash> " -"<uri>' (收到 '%s')" +"uploadpack.blobpackfileuri 的值格式必須為「<object-hash> <pack-hash> <uri>」" +"(收到「%s」)" #: builtin/pack-objects.c #, c-format @@ -11636,6 +11763,10 @@ msgstr "處理遺失的物件" msgid "do not pack objects in promisor packfiles" msgstr "不要打包 promisor packfile 中的物件" +#: builtin/pack-objects.c +msgid "implies --missing=allow-any" +msgstr "隱含 --missing=allow-any" + #: builtin/pack-objects.c msgid "respect islands during delta compression" msgstr "在差異壓縮時尊重資料島" @@ -11648,6 +11779,10 @@ msgstr "通訊協定" msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" msgstr "排除任何設定過,使用此通訊協定的 uploadpack.blobpackfileuri" +#: builtin/pack-objects.c +msgid "use the specified name-hash function to group similar objects" +msgstr "使用指定的名稱雜湊函式來為相似物件分組" + #: builtin/pack-objects.c #, c-format msgid "delta chain depth %d is too deep, forcing %d" @@ -11665,7 +11800,7 @@ msgstr "錯誤的打包壓縮級別 %d" #: builtin/pack-objects.c msgid "--max-pack-size cannot be used to build a pack for transfer" -msgstr "不能使用 --max-pack-size 來組建傳輸用的包檔案" +msgstr "不能使用 --max-pack-size 來建構傳輸用的包檔案" #: builtin/pack-objects.c msgid "minimum pack size limit is 1 MiB" @@ -12299,7 +12434,7 @@ msgstr "" #: builtin/push.c msgid "--all can't be combined with refspecs" -msgstr "--all 不能和引用規格同時使用" +msgstr "--all 無法和引用規格同時使用" #: builtin/push.c msgid "--mirror can't be combined with refspecs" @@ -12461,12 +12596,12 @@ msgstr "" #: builtin/rebase.c sequencer.c #, c-format msgid "could not read '%s'." -msgstr "不能讀取 '%s'。" +msgstr "無法讀取「%s」。" #: builtin/rebase.c #, c-format msgid "could not create temporary %s" -msgstr "無法建立暫時的 %s" +msgstr "無法建立暫存用的 %s" #: builtin/rebase.c msgid "could not mark as interactive" @@ -12474,7 +12609,7 @@ msgstr "無法標記為互動式" #: builtin/rebase.c msgid "could not generate todo list" -msgstr "無法生成待辦列表" +msgstr "無法產生待辦列表" #: builtin/rebase.c msgid "a base commit must be provided with --upstream or --onto" @@ -12503,7 +12638,7 @@ msgstr "忽略無效的 allow_rerere_autoupdate:'%s'" #: builtin/rebase.c builtin/rm.c sequencer.c #, c-format msgid "could not remove '%s'" -msgstr "無法刪除 '%s'" +msgstr "無法刪除「%s」" #: builtin/rebase.c #, c-format @@ -12546,7 +12681,7 @@ msgstr "--empty=ask 已棄用。請改用「--empty=stop」。" msgid "" "unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and " "\"stop\"." -msgstr "無法識別空類型「%s」;有效的數值有「drop」、「keep」跟「stop」。" +msgstr "不認識空類型「%s」;有效的數值有「drop」、「keep」跟「stop」。" #: builtin/rebase.c msgid "" @@ -12848,7 +12983,7 @@ msgstr "無效的上游 '%s'" #: builtin/rebase.c msgid "Could not create new root commit" -msgstr "不能建立新的根提交" +msgstr "無法建立新的根提交" #: builtin/rebase.c #, c-format @@ -13087,8 +13222,13 @@ msgid "invalid ref format: %s" msgstr "無效的引用格式:%s" #: builtin/refs.c -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<格式> [--dry-run]" +#| msgid "git refs migrate --ref-format=<format> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" + +#: builtin/refs.c +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" #: builtin/refs.c msgid "specify the reference format to convert to" @@ -13098,6 +13238,10 @@ msgstr "指定要轉換成的引用格式" msgid "perform a non-destructive dry-run" msgstr "進行非破壞性的試執行" +#: builtin/refs.c +msgid "drop reflogs entirely during the migration" +msgstr "在遷移過程中完全拋棄 reflog" + #: builtin/refs.c msgid "missing --ref-format=<format>" msgstr "缺少 --ref-format=<格式>" @@ -13107,6 +13251,14 @@ msgstr "缺少 --ref-format=<格式>" msgid "repository already uses '%s' format" msgstr "版本庫已經使用 '%s' 格式" +#: builtin/refs.c +msgid "enable strict checking" +msgstr "啟用嚴格檢查" + +#: builtin/refs.c +msgid "'git refs verify' takes no arguments" +msgstr "「git refs verify」不接受引數" + #: builtin/remote.c msgid "" "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" @@ -13192,7 +13344,7 @@ msgstr "更新 %s 中" #: builtin/remote.c #, c-format msgid "Could not fetch %s" -msgstr "不能取得 %s" +msgstr "無法取得 %s" #: builtin/remote.c msgid "" @@ -13247,7 +13399,7 @@ msgstr "遠端 %s 已經存在。" #: builtin/remote.c #, c-format msgid "Could not setup master '%s'" -msgstr "無法設定 master '%s'" +msgstr "無法配置 master「%s」" #: builtin/remote.c trailer.c #, c-format @@ -13262,7 +13414,7 @@ msgstr "branch.%s.rebase=%s 未處理。假設成 'true'" #: builtin/remote.c #, c-format msgid "Could not get fetch map for refspec %s" -msgstr "無法得到引用規格 %s 的取得列表" +msgstr "無法取得引用規格 %s 的 fetch 映射" #: builtin/remote.c msgid "(matching)" @@ -13275,12 +13427,12 @@ msgstr "(刪除)" #: builtin/remote.c #, c-format msgid "could not set '%s'" -msgstr "無法設定 '%s'" +msgstr "無法設定「%s」" #: builtin/remote.c config.c #, c-format msgid "could not unset '%s'" -msgstr "不能取消設定 '%s'" +msgstr "無法取消設定「%s」" #: builtin/remote.c #, c-format @@ -13301,7 +13453,7 @@ msgstr "沒有此遠端版本庫:'%s'" #: builtin/remote.c #, c-format msgid "Could not rename config section '%s' to '%s'" -msgstr "不能重新命名設定小節 '%s' 到 '%s'" +msgstr "無法將組態的「%s」區段重新命名為「%s」" #: builtin/remote.c #, c-format @@ -13340,7 +13492,7 @@ msgstr[0] "注意:refs/remotes/ 層級之外的一個分支未被移除。要 #: builtin/remote.c #, c-format msgid "Could not remove config section '%s'" -msgstr "不能移除設定小節 '%s'" +msgstr "無法移除組態的「%s」區段" #: builtin/remote.c #, c-format @@ -13511,6 +13663,33 @@ msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " 為 'git push' 設定的本機引用%s:" +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "「%s/HEAD」沒有變更,指向「%s」\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "「%s/HEAD」已經從「%s」變更,現在指向「%s」\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "「%s/HEAD」現在已經建立並指向「%s」\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "「%s/HEAD」已經在「%s」處分離,現在指向「%s」\n" + +#: builtin/remote.c +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "「%s/HEAD」原本指向「%s」(不是遠端分支),但現在指向「%s」\n" + #: builtin/remote.c msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "根據遠端設定 refs/remotes/<名稱>/HEAD" @@ -13539,8 +13718,8 @@ msgstr "不是一個有效引用:%s" #: builtin/remote.c #, c-format -msgid "Could not setup %s" -msgstr "不能設定 %s" +msgid "Could not set up %s" +msgstr "無法配置 %s" # 譯者:請維持前導空格 #: builtin/remote.c @@ -13634,8 +13813,14 @@ msgid "be verbose; must be placed before a subcommand" msgstr "詳細輸出;必須置於子指令之前" #: builtin/repack.c -msgid "git repack [<options>]" -msgstr "git repack [<選項>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>]" #: builtin/repack.c msgid "" @@ -13659,7 +13844,7 @@ msgstr "repack:期望來自 pack-objects 的完整十六進位物件 ID。" #: builtin/repack.c msgid "could not finish pack-objects to repack promisor objects" -msgstr "無法完成 pack-objects 來重新打包 promisor 物件" +msgstr "無法結束 pack-objects 來重新打包 promisor 物件" #: builtin/repack.c #, c-format @@ -13679,7 +13864,7 @@ msgstr "%s 包太大,以致不能縮合" #: builtin/repack.c #, c-format msgid "could not open tempfile %s for writing" -msgstr "無法開啟 '%s' 暫存檔進行寫入" +msgstr "無法開啟暫存檔 %s 進行寫入" #: builtin/repack.c msgid "could not close refs snapshot tempfile" @@ -13727,6 +13912,11 @@ msgstr "向 git-pack-objects 傳遞參數 --no-reuse-delta" msgid "pass --no-reuse-object to git-pack-objects" msgstr "向 git-pack-objects 傳遞參數 --no-reuse-object" +#: builtin/repack.c +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "指定要用來以路徑為相似物件分組的名稱雜湊版本" + #: builtin/repack.c msgid "do not run git-update-server-info" msgstr "不執行 git-update-server-info" @@ -13789,11 +13979,7 @@ msgstr "尋找因數是 <N> 的等比數列" #: builtin/repack.c msgid "write a multi-pack index of the resulting packs" -msgstr "寫入結果包的多包索引" - -#: builtin/repack.c -msgid "pack prefix to store a pack containing pruned objects" -msgstr "封裝前綴,儲存為包含過時物件的套件包" +msgstr "寫入結果包的多包索引" #: builtin/repack.c msgid "pack prefix to store a pack containing filtered out objects" @@ -13943,7 +14129,7 @@ msgstr "新物件和舊物件相同:'%s'" #: builtin/replace.c #, c-format msgid "could not parse %s as a commit" -msgstr "無法將 %s 解析為一個提交" +msgstr "無法將 %s 解析為提交" #: builtin/replace.c #, c-format @@ -13974,7 +14160,7 @@ msgstr "在取代的提交中簽名將被移除!" #: builtin/replace.c #, c-format msgid "could not write replacement commit for: '%s'" -msgstr "不能為 '%s' 寫取代提交" +msgstr "無法寫入下列項目的替代提交:「%s」" #: builtin/replace.c #, c-format @@ -13992,7 +14178,7 @@ msgid "" "could not convert the following graft(s):\n" "%s" msgstr "" -"不能轉換下列移植:\n" +"無法轉換下列移植:\n" "%s" #: builtin/replace.c @@ -14029,7 +14215,7 @@ msgstr "使用此格式" #: builtin/replace.c msgid "--format cannot be used when not listing" -msgstr "不列出時不能使用 --format" +msgstr "非列出操作不能使用 --format" #: builtin/replace.c msgid "-f only makes sense when writing a replacement" @@ -14067,10 +14253,6 @@ msgstr "只能為 -l 提供一個模式" 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 "提供的所有正向修訂集必須為引用" @@ -14295,11 +14477,11 @@ msgstr "" #: builtin/reset.c #, c-format msgid "Could not reset index file to revision '%s'." -msgstr "不能重設索引檔案至版本 '%s'。" +msgstr "無法將索引檔案重設到修訂版「%s」。" #: builtin/reset.c msgid "Could not write new index file." -msgstr "不能寫入新的索引檔案。" +msgstr "無法寫入新的索引檔案。" #: builtin/rev-list.c #, c-format @@ -14877,12 +15059,12 @@ msgid "failed to look up reference" msgstr "無法查詢引用" #: builtin/show-ref.c -msgid "only show tags (can be combined with branches)" -msgstr "只顯示標籤(可以和分支共用)" +msgid "only show tags (can be combined with --branches)" +msgstr "只顯示標籤(可以和 --branches 共用)" #: builtin/show-ref.c -msgid "only show branches (can be combined with tags)" -msgstr "只顯示分支(可以和標籤共用)" +msgid "only show branches (can be combined with --tags)" +msgstr "只顯示分支(可以和 --tags 共用)" #: builtin/show-ref.c msgid "check for reference existence without resolving" @@ -14944,6 +15126,11 @@ msgstr "無法移除 '%s' 目錄" msgid "failed to create directory for sparse-checkout file" msgstr "無法建立稀疏簽出檔案的目錄" +#: builtin/sparse-checkout.c +#, c-format +msgid "unable to fdopen %s" +msgstr "無法 fdopen %s" + #: builtin/sparse-checkout.c msgid "failed to initialize worktree config" msgstr "無法初始化工作區組態" @@ -15183,7 +15370,7 @@ msgstr "無法在合併過程套用貯存" #: builtin/stash.c #, c-format msgid "could not generate diff %s^!." -msgstr "無法生成差異 %s^!." +msgstr "無法產生差異 %s^!." #: builtin/stash.c msgid "conflicts in index. Try without --index." @@ -15191,7 +15378,7 @@ msgstr "索引中有衝突。請試試看不用 --index。" #: builtin/stash.c msgid "could not save index tree" -msgstr "不能儲存索引樹" +msgstr "無法儲存索引樹" #: builtin/stash.c #, c-format @@ -15367,14 +15554,14 @@ msgstr "期望一個完整的引用名稱,卻得到 %s" #: builtin/submodule--helper.c #, c-format msgid "could not get a repository handle for submodule '%s'" -msgstr "無法獲得子模組 '%s' 的版本庫句柄" +msgstr "無法取得子模組「%s」的版本庫控制代碼" #: builtin/submodule--helper.c #, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " "authoritative upstream." -msgstr "無法找到設定 '%s'。假定這個版本庫是其自身的官方上游。" +msgstr "找不到「%s」組態設定。假定這個版本庫是其自身的官方上游。" #: builtin/submodule--helper.c #, c-format @@ -15453,7 +15640,7 @@ msgstr "在 .gitmodules 中沒有發現路徑 '%s' 的子模組映射" #: builtin/submodule--helper.c #, c-format msgid "could not resolve HEAD ref inside the submodule '%s'" -msgstr "無法解析子模組 '%s' 的 HEAD 引用" +msgstr "無法解析子模組「%s」的 HEAD 引用" #: builtin/submodule--helper.c #, c-format @@ -15492,12 +15679,12 @@ msgstr "%s" #: builtin/submodule--helper.c #, c-format msgid "couldn't hash object from '%s'" -msgstr "無法雜湊來自 '%s' 的物件" +msgstr "無法雜湊來自「%s」的物件" #: builtin/submodule--helper.c #, c-format -msgid "unexpected mode %o\n" -msgstr "非預期的模式 %o\n" +msgid "unexpected mode %o" +msgstr "非預期的模式 %o" #: builtin/submodule--helper.c msgid "use the commit stored in the index instead of the submodule HEAD" @@ -15521,7 +15708,7 @@ msgstr "git submodule summary [<options>] [<commit>] [--] [<path>]" #: builtin/submodule--helper.c msgid "could not fetch a revision for HEAD" -msgstr "無法取得 HEAD 的版本" +msgstr "無法取得 HEAD 的修訂版" #: builtin/submodule--helper.c #, c-format @@ -15569,12 +15756,12 @@ msgstr "已清除目錄 '%s'\n" #: builtin/submodule--helper.c #, c-format msgid "Could not remove submodule work tree '%s'\n" -msgstr "無法移除子模組工作區 '%s'\n" +msgstr "無法移除子模組工作區「%s」\n" #: builtin/submodule--helper.c #, c-format msgid "could not create empty submodule directory %s" -msgstr "不能建立空的子模組目錄 %s" +msgstr "無法建立空的子模組目錄 %s" #: builtin/submodule--helper.c #, c-format @@ -15614,7 +15801,7 @@ msgstr "" #: builtin/submodule--helper.c #, c-format msgid "could not get a repository handle for gitdir '%s'" -msgstr "無法取得 gitdir「%s」的版本庫控點" +msgstr "無法取得 gitdir「%s」的版本庫控制代碼" #: builtin/submodule--helper.c #, c-format @@ -15649,7 +15836,7 @@ msgstr "無法複製 '%s' 到子模組路徑 '%s'" #: builtin/submodule--helper.c #, c-format msgid "could not get submodule directory for '%s'" -msgstr "無法得到 '%s' 的子模組目錄" +msgstr "無法取得「%s」的子模組目錄" #: builtin/submodule--helper.c msgid "alternative anchor for relative paths" @@ -16778,7 +16965,7 @@ msgstr "無法取消「%2$s」中「%1$s」的設定" #: builtin/worktree.c #, c-format msgid "could not create directory of '%s'" -msgstr "不能建立目錄 '%s'" +msgstr "無法建立「%s」的目錄" #: builtin/worktree.c msgid "initializing" @@ -16869,6 +17056,10 @@ msgstr "設定追蹤模式(參見 git-branch(1))" msgid "try to match the new branch name with a remote-tracking branch" msgstr "嘗試為新分支名符合一個遠端追蹤分支" +#: builtin/worktree.c +msgid "use relative paths for worktrees" +msgstr "對工作區使用相對路徑" + #: builtin/worktree.c diff.c parse-options.c #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" @@ -16939,7 +17130,7 @@ msgstr "'%s' 是一個主工作區" #: builtin/worktree.c #, c-format msgid "could not figure out destination name from '%s'" -msgstr "無法從 '%s' 算出目的地名稱" +msgstr "無法從「%s」得出目的地名稱" #: builtin/worktree.c #, c-format @@ -17069,7 +17260,7 @@ msgstr "無法儲存最大的建立權杖" #: bundle-uri.c #, c-format msgid "unrecognized bundle mode from URI '%s'" -msgstr "無法識別從 URI「%s」取回的套件包模式" +msgstr "不認識從 URI「%s」取回的套件包模式" #: bundle-uri.c #, c-format @@ -17110,7 +17301,7 @@ msgstr "bundle-uri: 列有空鍵或空值" #: bundle.c #, c-format msgid "unrecognized bundle hash algorithm: %s" -msgstr "無法識別的套件包雜湊演算法:%s" +msgstr "不認識的套件包雜湊演算法:%s" #: bundle.c #, c-format @@ -17125,7 +17316,7 @@ msgstr "「%s」不像是一個 v2 或 v3 版本的套件包檔案" #: bundle.c #, c-format msgid "unrecognized header: %s%s (%d)" -msgstr "無法識別的標頭:%s%s (%d)" +msgstr "不認識的標頭:%s%s (%d)" #: bundle.c msgid "Repository lacks these prerequisite commits:" @@ -17203,6 +17394,30 @@ msgstr "無法建立「%s」" msgid "index-pack died" msgstr "index-pack 終止" +#: cache-tree.c +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "「%s」目錄已經在索引裡面,但不在稀疏簽出當中。" + +#: cache-tree.c unpack-trees.c +msgid "corrupted cache-tree has entries not present in index" +msgstr "損壞的快取樹有不在索引中的項目" + +#: cache-tree.c +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "有 0x%2$x 標記的 %1$s 不應該在快取樹當中" + +#: cache-tree.c +#, c-format +msgid "bad subtree '%.*s'" +msgstr "「%.*s」子樹損壞" + +#: cache-tree.c +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "%.*s 路徑的快取樹不符。預期是 %s,卻得到 %s" + #: chunk-format.c msgid "terminating chunk id appears earlier than expected" msgstr "終止區塊 ID 比預期還早出現" @@ -17260,6 +17475,10 @@ msgstr "將一個 GNU Arch 版本庫匯入到 Git" msgid "Create an archive of files from a named tree" msgstr "基於命名過的樹建立檔案封存" +#: command-list.h +msgid "Download missing objects in a partial clone" +msgstr "在部分複製中下載缺少的物件" + #: command-list.h msgid "Use binary search to find the commit that introduced a bug" msgstr "透過二分搜尋定位引入 bug 的提交" @@ -18167,7 +18386,7 @@ msgstr "無法寫入正確數量的基礎圖 ID" msgid "unable to create temporary graph layer" msgstr "無法建立暫時性圖層" -#: commit-graph.c +#: commit-graph.c midx-write.c #, c-format msgid "unable to adjust shared permissions for '%s'" msgstr "無法調整「%s」的共用權限" @@ -18215,8 +18434,8 @@ msgstr "嘗試寫入提交圖,但「core.commitGraph」已停用" #: commit-graph.c #, c-format msgid "" -"attempting to write a commit-graph, but 'commitGraph." -"changedPathsVersion' (%d) is not supported" +"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " +"(%d) is not supported" msgstr "嘗試寫入提交圖,但不支援「commitGraph.changedPathsVersion」(%d)" #: commit-graph.c @@ -18291,7 +18510,7 @@ msgstr "正在驗證提交圖中的提交" #: commit-reach.c sequencer.c #, c-format msgid "could not parse commit %s" -msgstr "不能解析提交 %s" +msgstr "無法解析提交 %s" #: commit.c #, c-format @@ -18307,7 +18526,7 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "對 <GIT_DIR>/info/grafts 的支援已棄用,並將在\n" "未來的 Git 版本中被移除。\n" @@ -18315,8 +18534,8 @@ msgstr "" "請使用「git replace --convert-graft-file」將\n" "grafts 轉換為取代引用。\n" "\n" -"設定「git config advice.graftFileDeprecated false」\n" -"可以將本訊息關閉" +"設定「git config set advice.graftFileDeprecated false」\n" +"可以關閉此訊息" #: commit.c #, c-format @@ -18624,7 +18843,7 @@ msgstr "" #: config.c #, c-format msgid "could not expand include path '%s'" -msgstr "無法展開包含路徑 '%s'" +msgstr "無法展開包含路徑「%s」" #: config.c msgid "relative config includes must come from files" @@ -18923,7 +19142,7 @@ msgstr "不允許多列備註:「%s」" #: config.c #, c-format msgid "could not lock config file %s" -msgstr "不能鎖定設定檔案 %s" +msgstr "無法鎖定組態檔案 %s" #: config.c #, c-format @@ -18953,12 +19172,12 @@ msgstr "對 %s 呼叫 chmod 失敗" #: config.c #, c-format msgid "could not write config file %s" -msgstr "不能寫入設定檔案 %s" +msgstr "無法寫入組態檔案 %s" #: config.c #, c-format msgid "could not set '%s' to '%s'" -msgstr "不能設定 '%s' 為 '%s'" +msgstr "無法將「%s」設為「%s」" #: config.c #, c-format @@ -19157,7 +19376,7 @@ msgstr "無法 fork" #: connected.c msgid "Could not run 'git rev-list'" -msgstr "不能執行 'git rev-list'" +msgstr "無法執行「git rev-list」" #: connected.c msgid "failed write to rev-list" @@ -19314,6 +19533,21 @@ msgstr "URL 沒有 Scheme:%s" msgid "credential url cannot be parsed: %s" msgstr "無法解析憑證 URL:%s" +#: daemon.c +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "無效的 timeout「%s」,預期為非負整數" + +#: daemon.c +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "無效的 init-timeout「%s」,應為非負整數" + +#: daemon.c +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "無效的 max-connections「%s」,應為整數" + #: date.c msgid "in the future" msgstr "在將來" @@ -19410,7 +19644,7 @@ msgstr "無法封存不存在的路徑「%s」" #: diagnose.c dir.c #, c-format msgid "could not open directory '%s'" -msgstr "不能開啟目錄 '%s'" +msgstr "無法開啟目錄「%s」" #: diagnose.c #, c-format @@ -19504,7 +19738,7 @@ msgstr "color-moved-ws:allow-indentation-change 不能與其它空白字元模 msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "設定變數 'diff.submodule' 未知的取值:'%s'" -#: diff.c transport.c +#: diff.c merge-recursive.c transport.c #, c-format msgid "unknown value for config '%s': %s" msgstr "設定 '%s' 的取值未知:%s" @@ -19612,6 +19846,14 @@ msgstr "%s 的參數無效" msgid "invalid regex given to -I: '%s'" msgstr "傳入 -I 的常規表示式無效:「%s」" +#: diff.c +msgid "-G requires a non-empty argument" +msgstr "-G 需要非空白引數" + +#: diff.c +msgid "-S requires a non-empty argument" +msgstr "-S 需要非空白引數" + #: diff.c #, c-format msgid "failed to parse --submodule option parameter: '%s'" @@ -20085,12 +20327,12 @@ msgstr "路徑規格 '%s' 未符合任何 git 已知檔案" #: dir.c #, c-format msgid "unrecognized pattern: '%s'" -msgstr "無法識別樣式:「%s」" +msgstr "不認識樣式:「%s」" #: dir.c #, c-format msgid "unrecognized negative pattern: '%s'" -msgstr "無法識別反向模式:「%s」" +msgstr "不認識反向模式:「%s」" #: dir.c #, c-format @@ -20130,12 +20372,12 @@ msgstr "版本庫 %s 中的索引檔案損壞" #: dir.c #, c-format msgid "could not create directories for %s" -msgstr "不能為 %s 建立目錄" +msgstr "無法建立 %s 的目錄" #: dir.c #, c-format msgid "could not migrate git directory from '%s' to '%s'" -msgstr "不能從 '%s' 遷移 git 目錄到 '%s'" +msgstr "無法從「%s」遷移 git 目錄到「%s」" #: editor.c #, c-format @@ -20145,12 +20387,12 @@ msgstr "提示:等待您的編輯器關閉檔案...%c" #: editor.c sequencer.c wrapper.c #, c-format msgid "could not write to '%s'" -msgstr "不能寫入 '%s'" +msgstr "無法寫入「%s」" #: editor.c #, c-format msgid "could not edit '%s'" -msgstr "無法編輯 '%s'" +msgstr "無法編輯「%s」" #: entry.c msgid "Filtering content" @@ -20159,7 +20401,7 @@ msgstr "過濾內容" #: entry.c #, c-format msgid "could not stat file '%s'" -msgstr "不能對檔案 '%s' 呼叫 stat" +msgstr "無法 stat 檔案「%s」" #: environment.c #, c-format @@ -20171,6 +20413,23 @@ msgstr "錯誤的 git 名字空間路徑 \"%s\"" msgid "too many args to run %s" msgstr "執行 %s 的參數太多" +#: fetch-pack.c +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"你正在嘗試取得 %s。這個物件在提交圖檔案中,\n" +"但不在物件資料庫中。\n" +"\n" +"這可能是由於儲存庫損壞所致。\n" +"\n" +"如果你想透過重新擷取遺失的物件來修復儲存庫損壞,\n" +"請使用「git fetch --refetch」並指定遺失的物件。" + #: fetch-pack.c msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack:應為 shallow 列表" @@ -20599,7 +20858,7 @@ msgstr "執行指令 '%s' 失敗:%s\n" #: gpg-interface.c msgid "could not create temporary file" -msgstr "不能建立暫存檔" +msgstr "無法建立暫存檔" #: gpg-interface.c #, c-format @@ -20877,10 +21136,10 @@ msgstr[0] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" -"因為沒有將掛鉤 '%s' 設定為可執行,掛鉤被忽略。您可以透過\n" -"設定 `git config advice.ignoredHook false` 來關閉這條警告。" +"因為沒有將掛鉤「%s」設定為可執行,因此忽略這個掛鉤。\n" +"您可以透過設定「git config set advice.ignoredHook false」來關閉這則警告。" #: http-fetch.c msgid "not a git repository" @@ -20900,18 +21159,10 @@ msgstr "http.postBuffer 為負值,預設為 %d" msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "不支援委託控制,因為 cURL < 7.22.0" -#: http.c -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "不支援公鑰檔案鎖定,因為 cURL < 7.39.0" - #: http.c msgid "Unknown value for http.proactiveauth" msgstr "http.proactiveauth 的值未知" -#: http.c -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "不支援 CURLSSLOPT_NO_REVOKE,因為 cURL < 7.44.0" - #: http.c #, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" @@ -20920,12 +21171,12 @@ msgstr "不支援的 SSL 後端 '%s'。支援的 SSL 後端:" #: http.c #, c-format msgid "Could not set SSL backend to '%s': cURL was built without SSL backends" -msgstr "無法將 SSL 後端設定為 '%s':組建 cURL 時未加入 SSL 後端" +msgstr "無法將 SSL 後端設定為「%s」:組建 cURL 時未加入 SSL 後端" #: http.c #, c-format msgid "Could not set SSL backend to '%s': already set" -msgstr "無法將 SSL 後端設定為 '%s':已經設定" +msgstr "無法將 SSL 後端設定為「%s」:已經設定" #: http.c msgid "refusing to read cookies from http.cookiefile '-'" @@ -21041,7 +21292,7 @@ msgstr "不能混用多種過濾規格" #: list-objects-filter-options.c msgid "unable to upgrade repository format to support partial clone" -msgstr "無法升級版本庫格式,以致不支援部分複製" +msgstr "無法升級版本庫格式,以支援部分複製" #: list-objects-filter-options.h msgid "args" @@ -21100,6 +21351,10 @@ msgstr "" msgid "Unable to create '%s.lock': %s" msgstr "不能建立 '%s.lock':%s" +#: log-tree.c +msgid "unable to create temporary object directory" +msgstr "無法建立暫存物件目錄" + #: loose.c #, c-format msgid "could not write loose object index %s" @@ -21107,8 +21362,8 @@ msgstr "無法寫入鬆散物件索引 %s" #: loose.c #, c-format -msgid "failed to write loose object index %s\n" -msgstr "寫入鬆散物件索引 %s 失敗\n" +msgid "failed to write loose object index %s" +msgstr "寫入鬆散物件索引 %s 失敗" #: ls-refs.c #, c-format @@ -21128,6 +21383,11 @@ msgstr "偵測到由可列印字元 (quoted) 所組成的 CRLF" msgid "unable to format message: %s" msgstr "無法格式化訊息:%s" +#: merge-ll.c +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "無效的 marker-size「%s」,應為整數" + #: merge-ort.c merge-recursive.c #, c-format msgid "Failed to merge submodule %s (not checked out)" @@ -21699,7 +21959,7 @@ msgstr "合併未返回提交" #: merge-recursive.c #, c-format msgid "Could not parse object '%s'" -msgstr "不能解析物件 '%s'" +msgstr "無法解析物件「%s」" #: merge.c msgid "failed to read the cache" @@ -21743,6 +22003,20 @@ msgstr "無法載入包" msgid "could not open index for %s" msgstr "無法開啟 %s 的索引" +#: midx-write.c +#, c-format +msgid "unable to link '%s' to '%s'" +msgstr "無法將「%s」link 至「%s」" + +#: midx-write.c midx.c +#, c-format +msgid "failed to clear multi-pack-index at %s" +msgstr "清理位於 %s 的多包索引失敗" + +#: midx-write.c +msgid "cannot write incremental MIDX with bitmap" +msgstr "無法寫入有位圖的增量 MIDX" + #: midx-write.c msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "忽略現有的多包索引:總和檢查碼不符" @@ -21779,29 +22053,49 @@ msgstr "沒有要索引的 pack 檔案。" msgid "refusing to write multi-pack .bitmap without any objects" msgstr "拒絕寫入無任何物件的多包 .bitmap" +#: midx-write.c +msgid "unable to create temporary MIDX layer" +msgstr "無法建立暫時的 MIDX 層" + #: midx-write.c msgid "could not write multi-pack bitmap" msgstr "無法寫入多包位圖" +#: midx-write.c +msgid "unable to open multi-pack-index chain file" +msgstr "無法開啟多封裝索引鏈檔案" + +#: midx-write.c +msgid "unable to rename new multi-pack-index layer" +msgstr "無法更改新多封裝索引層的名稱" + #: midx-write.c msgid "could not write multi-pack-index" msgstr "無法寫入多包索引" +#: midx-write.c +msgid "cannot expire packs from an incremental multi-pack-index" +msgstr "無法將一個增量多封裝索引的套件設為過期" + #: midx-write.c msgid "Counting referenced objects" -msgstr "正在計算引用物件" +msgstr "正在計算引用物件數量" #: midx-write.c msgid "Finding and deleting unreferenced packfiles" msgstr "正在尋找並刪除沒有引用的 packfile" +#: midx-write.c +msgid "cannot repack an incremental multi-pack-index" +msgstr "無法重新封裝增量的多封裝索引" + #: midx-write.c msgid "could not start pack-objects" -msgstr "不能開始 pack-objects" +msgstr "無法啟動 pack-objects" #: midx-write.c msgid "could not finish pack-objects" -msgstr "不能結束 pack-objects" +msgstr "無法結束 pack-objects" #: midx.c msgid "multi-pack-index OID fanout is of the wrong size" @@ -21866,6 +22160,33 @@ msgstr "多包索引的封裝名稱區塊過短" msgid "multi-pack-index pack names out of order: '%s' before '%s'" msgstr "多包索引包名無序:'%s' 在 '%s' 之前" +#: midx.c +msgid "multi-pack-index chain file too small" +msgstr "多封裝索引鏈檔案過小" + +#: midx.c +#, c-format +msgid "pack count in base MIDX too high: %<PRIuMAX>" +msgstr "基礎 MIDX 的封裝計數太高:%<PRIuMAX>" + +#: midx.c +#, c-format +msgid "object count in base MIDX too high: %<PRIuMAX>" +msgstr "基礎 MIDX 的物件計數太高:%<PRIuMAX>" + +#: midx.c +#, c-format +msgid "invalid multi-pack-index chain: line '%s' not a hash" +msgstr "無法的多封裝索引鏈:「%s」列不是雜湊值" + +#: midx.c +msgid "unable to find all multi-pack index files" +msgstr "找不到所有的多封裝索引檔案" + +#: midx.c +msgid "invalid MIDX object position, MIDX is likely corrupt" +msgstr "無效的 MIDX 物件位置,MIDX 大概有問題" + #: midx.c #, c-format msgid "bad pack-int-id: %u (%u total packs)" @@ -21888,11 +22209,6 @@ msgstr "多包索引儲存一個64位位移,但是 off_t 太小" msgid "multi-pack-index large offset out of bounds" msgstr "多包索引的最大偏移超出邊界" -#: midx.c -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "清理位於 %s 的多包索引失敗" - #: midx.c msgid "multi-pack-index file exists, but failed to parse" msgstr "有 multi-pack-index 檔案,但無法解析" @@ -22150,11 +22466,26 @@ msgstr "打包物件 %s(儲存在 %s)已損壞" msgid "missing mapping of %s to %s" msgstr "缺少 %s 到 %s 的映射" +#: object-file.c +#, c-format +msgid "unable to open %s" +msgstr "不能開啟 %s" + +#: object-file.c +#, c-format +msgid "files '%s' and '%s' differ in contents" +msgstr "「%s」和「%s」檔案內容不同" + #: object-file.c #, c-format msgid "unable to write file %s" msgstr "無法寫檔案 %s" +#: object-file.c +#, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "無法寫入重複消失的檔案 %s" + #: object-file.c #, c-format msgid "unable to set permission to '%s'" @@ -22256,11 +22587,6 @@ msgstr "%s:不支援的檔案類型" msgid "%s is not a valid '%s' object" msgstr "%s 不是一個有效的 '%s' 物件" -#: object-file.c -#, c-format -msgid "unable to open %s" -msgstr "不能開啟 %s" - #: object-file.c #, c-format msgid "hash mismatch for %s (expected %s)" @@ -22376,17 +22702,17 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" -"Git 通常不會建立以 40 個十六進位字元結尾的引用,\n" -"因為當您只提供 40 個十六進位字元時,其將被忽略。\n" -"這些引用可能被意外建立。例如:\n" +"Git 通常不會建立以 40 個十六進位字元結尾的參照,\n" +"因為在指定 40 個十六進位字元時會被忽略。\n" +"這些參照可能是意外建立的。例如,\n" "\n" " git switch -c $br $(git rev-parse ...)\n" "\n" -"當「$br」因為某些原因空白時,會建立出 40 位十六進位的引用。\n" -"請檢查這些引用,並視需要刪除。執行\n" -"「git config advice.objectNameWarning false」命令以關閉本訊息通知" +"其中「$br」不知何故為空白,導致建立了一個 40 個\n" +"十六進位字元的參照。請檢查這些參照,必要時刪除它們。\n" +"若要關閉此訊息,請執行「git config set advice.objectNameWarning false」" #: object-name.c #, c-format @@ -22580,15 +22906,6 @@ 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" -msgstr "偏好的封包 (%s) 無效" - #: pack-bitmap.c msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "位圖查詢表損壞:三元組位置超出索引" @@ -22661,7 +22978,7 @@ msgstr "偽合併索引超出範圍(%<PRIu32> >= %<PRIuMAX>)" #: pack-bitmap.c #, c-format msgid "could not find '%s' in pack '%s' at offset %<PRIuMAX>" -msgstr "在「%2$s」封包,位移 %3$<PRIuMAX> 的地方找不到「%1$s」" +msgstr "無法在「%2$s」封包,位移 %3$<PRIuMAX> 的地方找到「%1$s」" #: pack-bitmap.c #, c-format @@ -22852,6 +23169,55 @@ msgstr "未知開關 `%c'" msgid "unknown non-ascii option in string: `%s'" msgstr "字串中未知的非 ascii 字元選項:`%s'" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid " <%s>" +msgstr " <%s>" + #: parse-options.c msgid "..." msgstr "..." @@ -22955,10 +23321,29 @@ msgstr "「%2$s」的「%1$s」布林環境值無效" msgid "failed to parse %s" msgstr "解析 %s 失敗" +#: path-walk.c +#, c-format +msgid "failed to walk children of tree %s: not found" +msgstr "無法走訪樹 %s 的子代:找不到" + +#: path-walk.c +#, c-format +msgid "failed to find object %s" +msgstr "找不到物件 %s" + +#: path-walk.c +#, c-format +msgid "failed to find tag %s" +msgstr "找不到標籤 %s" + +#: path-walk.c +msgid "failed to setup revision walk" +msgstr "無法設置修訂版走訪" + #: path.c #, c-format msgid "Could not make %s writable by group" -msgstr "不能設定 %s 為組可寫" +msgstr "無法設定 %s 為群組可寫" #: pathspec.c msgid "Escape character '\\' not allowed as last character in attr value" @@ -23136,6 +23521,26 @@ msgstr "promisor 遠端名稱不能以 '/' 開始:%s" msgid "could not fetch %s from promisor remote" msgstr "無法從承諾者遠端抓取 %s" +#: promisor-remote.c +#, c-format +msgid "known remote named '%s' but with url '%s' instead of '%s'" +msgstr "已知有遠端名為「%s」,但其 URL 為「%s」而非「%s」" + +#: promisor-remote.c +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "「%2$s」組態選項的值「%1$s」未知" + +#: promisor-remote.c +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "遠端資訊的元素「%s」未知" + +#: promisor-remote.c +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "找不到接受的承諾者遠端「%s」" + #: protocol-caps.c msgid "object-info: expected flush after arguments" msgstr "object-info:引數後預期要有 flush" @@ -23212,16 +23617,16 @@ msgstr "無法讀取提交 %s 的延伸偽合併表" #: range-diff.c msgid "could not start `log`" -msgstr "不能啟動 `log`" +msgstr "無法啟動「log」" #: range-diff.c msgid "could not read `log` output" -msgstr "不能讀取 `log` 的輸出" +msgstr "無法讀取「log」的輸出" #: range-diff.c sequencer.c #, c-format msgid "could not parse commit '%s'" -msgstr "不能解析提交 '%s'" +msgstr "無法解析提交「%s」" #: range-diff.c #, c-format @@ -23233,7 +23638,7 @@ msgstr "無法解析第一行「log」輸出:開頭不是「commit」:「%s #: range-diff.c #, c-format msgid "could not parse git header '%.*s'" -msgstr "無法解析 git 頭 '%.*s'" +msgstr "無法解析 git 標頭「%.*s」" #: range-diff.c msgid "failed to generate diff" @@ -23242,7 +23647,7 @@ msgstr "生成 diff 失敗" #: range-diff.c #, c-format msgid "could not parse log for '%s'" -msgstr "不能解析 '%s' 的日誌" +msgstr "無法解析「%s」的日誌" #: reachable.c #, c-format @@ -23396,7 +23801,7 @@ msgstr "無法加入 load_index_extensions 執行緒:%s" #: read-cache.c #, c-format msgid "could not freshen shared index '%s'" -msgstr "無法重新整理共享索引 '%s'" +msgstr "無法更新共享索引「%s」" #: read-cache.c #, c-format @@ -23454,7 +23859,7 @@ msgstr "" #, c-format msgid "" "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring." -msgstr "選項 rebase.missingCommitsCheck 的值 %s 無法識別。已忽略。" +msgstr "選項 rebase.missingCommitsCheck 的值 %s 不認識。已忽略。" #: rebase-interactive.c msgid "" @@ -23556,7 +23961,7 @@ msgstr "" #: rebase-interactive.c #, c-format msgid "could not write '%s'." -msgstr "不能寫入 '%s'。" +msgstr "無法寫入「%s」。" #: rebase-interactive.c #, c-format @@ -23615,7 +24020,7 @@ msgstr "%%(%.*s) 不取引數" #: ref-filter.c #, c-format msgid "unrecognized %%(%.*s) argument: %s" -msgstr "無法識別的 %%(%.*s) 引數:%s" +msgstr "不認識的 %%(%.*s) 引數:%s" #: ref-filter.c #, c-format @@ -23625,7 +24030,7 @@ msgstr "期望的格式:%%(color:<顏色>)" #: ref-filter.c #, c-format msgid "unrecognized color: %%(color:%s)" -msgstr "無法識別的顏色:%%(color:%s)" +msgstr "不認識的顏色:%%(color:%s)" #: ref-filter.c #, c-format @@ -23685,17 +24090,17 @@ msgstr "期望的格式:%%(align:<寬度>,<位置>)" #: ref-filter.c #, c-format msgid "unrecognized position:%s" -msgstr "無法識別的位置:%s" +msgstr "不認識的位置:%s" #: ref-filter.c #, c-format msgid "unrecognized width:%s" -msgstr "無法識別的寬度:%s" +msgstr "不認識的寬度:%s" #: ref-filter.c #, c-format msgid "unrecognized %%(%s) argument: %s" -msgstr "無法識別的 %%(%s) 參數:%s" +msgstr "不認識的 %%(%s) 參數:%s" #: ref-filter.c #, c-format @@ -23707,6 +24112,11 @@ msgstr "元素 %%(align) 需要一個正數的寬度" msgid "expected format: %%(ahead-behind:<committish>)" msgstr "預期格式:%%(ahead-behind:<committish>)" +#: ref-filter.c +#, c-format +msgid "expected format: %%(is-base:<committish>)" +msgstr "預期格式:%%(is-base:<committish>)" + #: ref-filter.c #, c-format msgid "malformed field name: %.*s" @@ -23761,7 +24171,7 @@ msgstr "本命令拒絕 atom %%(%.*s)" #: ref-filter.c #, c-format msgid "--format=%.*s cannot be used with --python, --shell, --tcl" -msgstr "--format=%.*s 不能和 --python、--shell、--tcl 一起使用" +msgstr "--format=%.*s 無法和 --python、--shell、--tcl 一起使用" #: ref-filter.c msgid "failed to run 'describe'" @@ -23919,8 +24329,19 @@ msgid "log for %s is empty" msgstr "%s 的日誌為空" #: refs.c -msgid "refusing to force and skip creation of reflog" -msgstr "拒絕強制並略過建立引用日誌" +#, c-format +msgid "refusing to update reflog for pseudoref '%s'" +msgstr "拒絕更新偽引用「%s」 的 reflog" + +#: refs.c +#, c-format +msgid "refusing to update pseudoref '%s'" +msgstr "拒絕更新偽引用「%s」" + +#: refs.c +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "拒絕更新有錯誤名稱「%s」的 reflog" #: refs.c #, c-format @@ -23928,9 +24349,8 @@ msgid "refusing to update ref with bad name '%s'" msgstr "拒絕更新有錯誤名稱 '%s' 的引用" #: refs.c -#, c-format -msgid "refusing to update pseudoref '%s'" -msgstr "拒絕更新偽引用「%s」" +msgid "refusing to force and skip creation of reflog" +msgstr "拒絕強制並略過建立引用日誌" #: refs.c #, c-format @@ -23991,6 +24411,20 @@ msgid "" "cannot lock ref '%s': expected symref with target '%s': but is a regular ref" msgstr "無法鎖定引用「%s」:預期是指向「%s」的符號引用,但這個是一般引用" +#: refs/files-backend.c +#, c-format +msgid "cannot read ref file '%s'" +msgstr "無法寫入參照檔案「%s」" + +#: refs/files-backend.c +#, c-format +msgid "cannot open directory %s" +msgstr "無法開啟 %s 目錄" + +#: refs/files-backend.c +msgid "Checking references consistency" +msgstr "正在檢查引用一致性" + #: refs/reftable-backend.c #, c-format msgid "refname is dangerous: %s" @@ -24074,6 +24508,16 @@ msgstr "引用名稱 %s 是符號引用,不支援複製" msgid "invalid refspec '%s'" msgstr "無效的引用規格:「%s」" +#: refspec.c +#, c-format +msgid "pattern '%s' has no '*'" +msgstr "符合模式「%s」中沒有「*」" + +#: refspec.c +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "取代文字「%s」中沒有「*」" + #: remote-curl.c #, c-format msgid "invalid quoting in push-option value: '%s'" @@ -24225,6 +24669,28 @@ msgstr "remote-curl:嘗試沒有本機版本庫下取得" msgid "remote-curl: unknown command '%s' from git" msgstr "remote-curl:未知的來自 git 的指令 '%s'" +#: remote.c +#, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"正在自「%s/%s」讀取遠端,該路徑已被標記為即將移除。\n" +"\n" +"如果您仍在使用「remotes/」目錄,建議您遷移至基於組態的遠端:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"如果您無法遷移,請告訴我們您為何仍需使用此功能,\n" +"請寄信至 <git@vger.kernel.org>。" + #: remote.c #, c-format msgid "config remote shorthand cannot begin with '/': %s" @@ -24238,10 +24704,15 @@ msgstr "提供了一個以上的 receivepack,使用第一個" msgid "more than one uploadpack given, using the first" msgstr "提供了一個以上的 uploadpack,使用第一個" +#: remote.c +#, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "已經忽略不認識的「%s」數值" + #: remote.c #, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" -msgstr "數值 transfer.credentialsInUrl 無法識別:「%s」" +msgstr "數值 transfer.credentialsInUrl 不認識:「%s」" #: remote.c #, c-format @@ -24263,16 +24734,6 @@ msgstr "%s 通常追蹤 %s,而非 %s" msgid "%s tracks both %s and %s" msgstr "%s 同時追蹤 %s 和 %s" -#: remote.c -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "模式的鍵 '%s' 沒有 '*'" - -#: remote.c -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "模式的值 '%s' 沒有 '*'" - #: remote.c #, c-format msgid "src refspec %s does not match any" @@ -24530,7 +24991,7 @@ msgstr "寫入 '%s' (%s) 時發生錯誤" #: rerere.c #, c-format msgid "could not parse conflict hunks in '%s'" -msgstr "不能解析 '%s' 中的衝突區塊" +msgstr "無法解析「%s」中的衝突區塊" #: rerere.c #, c-format @@ -24597,7 +25058,7 @@ msgstr "如果可能,重用衝突解決更新索引" #: reset.c msgid "could not determine HEAD revision" -msgstr "不能確定 HEAD 版本" +msgstr "無法確定 HEAD 修訂版" #: reset.c sequencer.c #, c-format @@ -24759,13 +25220,17 @@ msgstr "只下載會簽出的分支中介資料" msgid "create repository within 'src' directory" msgstr "在「src」目錄建立版本庫" +#: scalar.c +msgid "specify if tags should be fetched during clone" +msgstr "指定是否要在複製階段抓取標籤" + #: scalar.c msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" #: scalar.c #, c-format @@ -24787,6 +25252,11 @@ msgstr "無法取得「%s」的預設分支" msgid "could not configure remote in '%s'" msgstr "無法設定「%s」中的遠端" +#: scalar.c +#, c-format +msgid "could not disable tags in '%s'" +msgstr "無法停用「%s」的標籤" + #: scalar.c #, c-format msgid "could not configure '%s'" @@ -24974,7 +25444,7 @@ msgstr "無效的提交說明清理模式 '%s'" #: sequencer.c #, c-format msgid "could not delete '%s'" -msgstr "無法刪除 '%s'" +msgstr "無法刪除「%s」" #: sequencer.c msgid "revert" @@ -25049,12 +25519,12 @@ msgstr "" #: sequencer.c #, c-format msgid "could not lock '%s'" -msgstr "不能鎖定 '%s'" +msgstr "無法鎖定「%s」" #: sequencer.c #, c-format msgid "could not write eol to '%s'" -msgstr "不能將換行符號寫入 '%s'" +msgstr "無法將換行符號寫入「%s」" #: sequencer.c #, c-format @@ -25084,7 +25554,7 @@ msgstr "不能更新快取樹" #: sequencer.c msgid "could not resolve HEAD commit" -msgstr "不能解析 HEAD 提交" +msgstr "無法解析 HEAD 提交" #: sequencer.c #, c-format @@ -25211,7 +25681,7 @@ msgstr "無法找到新建立的提交" #: sequencer.c msgid "could not parse newly created commit" -msgstr "不能解析新建立的提交" +msgstr "無法解析新建立的提交" #: sequencer.c msgid "unable to resolve HEAD after creating commit" @@ -25228,7 +25698,7 @@ msgstr " (根提交)" #: sequencer.c msgid "could not parse HEAD" -msgstr "不能解析 HEAD" +msgstr "無法解析 HEAD" #: sequencer.c #, c-format @@ -25256,12 +25726,12 @@ msgstr "作者資訊損壞:缺少日期資訊" #: sequencer.c #, c-format msgid "could not update %s" -msgstr "不能更新 %s" +msgstr "無法更新 %s" #: sequencer.c #, c-format msgid "could not parse parent commit %s" -msgstr "不能解析父提交 %s" +msgstr "無法解析父提交 %s" #: sequencer.c #, c-format @@ -25302,16 +25772,16 @@ msgstr "需要一個 HEAD 來修復" #: sequencer.c msgid "could not read HEAD" -msgstr "不能讀取 HEAD" +msgstr "無法讀取 HEAD" #: sequencer.c msgid "could not read HEAD's commit message" -msgstr "不能讀取 HEAD 的提交說明" +msgstr "無法讀取 HEAD 的提交說明" #: sequencer.c #, c-format msgid "could not read commit message of %s" -msgstr "不能讀取 %s 的提交說明" +msgstr "無法讀取 %s 的提交說明" #: sequencer.c msgid "your index file is unmerged." @@ -25346,12 +25816,12 @@ msgstr "%s:不能解析父提交 %s" #: sequencer.c #, c-format msgid "could not revert %s... %s" -msgstr "不能還原 %s... %s" +msgstr "無法還原 %s... %s" #: sequencer.c #, c-format msgid "could not apply %s... %s" -msgstr "不能套用 %s... %s" +msgstr "無法套用 %s... %s" #: sequencer.c #, c-format @@ -25444,7 +25914,7 @@ msgstr "缺少 %s 的參數" #: sequencer.c #, c-format msgid "could not parse '%s'" -msgstr "無法解析 '%s'" +msgstr "無法解析「%s」" #: sequencer.c #, c-format @@ -25519,7 +25989,7 @@ msgstr "嘗試 \"git cherry-pick (--continue | %s--abort | --quit)\"" #: sequencer.c #, c-format msgid "could not create sequencer directory '%s'" -msgstr "不能建立序列目錄 '%s'" +msgstr "無法建立序列目錄「%s」" #: sequencer.c msgid "no cherry-pick or revert in progress" @@ -25606,12 +26076,12 @@ msgstr "" #: sequencer.c #, c-format msgid "Could not apply %s... %.*s" -msgstr "不能套用 %s... %.*s" +msgstr "無法套用 %s... %.*s" #: sequencer.c #, c-format msgid "Could not merge %.*s" -msgstr "不能合併 %.*s" +msgstr "無法合併 %.*s" #: sequencer.c #, c-format @@ -25663,7 +26133,7 @@ msgstr "非法的標籤名稱:'%.*s'" #: sequencer.c #, c-format msgid "could not resolve '%s'" -msgstr "無法解析 '%s'" +msgstr "無法解析「%s」" #: sequencer.c msgid "writing fake root commit" @@ -25694,12 +26164,12 @@ msgstr "章魚合並不能在一個新的根提交上執行" #: sequencer.c #, c-format msgid "could not get commit message of '%s'" -msgstr "不能取得 '%s' 的提交說明" +msgstr "無法取得「%s」的提交說明" #: sequencer.c #, c-format msgid "could not even attempt to merge '%.*s'" -msgstr "甚至不能嘗試合併 '%.*s'" +msgstr "甚至無法嘗試合併「%.*s」" #: sequencer.c msgid "merge: Unable to write new index file" @@ -25741,7 +26211,7 @@ msgstr "意外的 stash 回應:'%s'" #: sequencer.c #, c-format msgid "Could not create directory for '%s'" -msgstr "不能為 '%s' 建立目錄" +msgstr "無法建立「%s」的目錄" #: sequencer.c #, c-format @@ -25787,7 +26257,7 @@ msgstr "autostash 引用是符號引用" #: sequencer.c msgid "could not detach HEAD" -msgstr "不能分離開頭指標" +msgstr "無法分離開頭指標" #: sequencer.c #, c-format @@ -25814,7 +26284,7 @@ msgstr "" "無法執行待辦指令\n" "\n" " %.*s\n" -"已被重新安排,在繼續之前編輯指令,請先編輯待辦列表:\n" +"已經重新安排。若要在繼續之前編輯指令,請先編輯待辦列表:\n" "\n" " git rebase --edit-todo\n" " git rebase --continue\n" @@ -25836,16 +26306,16 @@ msgstr "未知指令 %d" #: sequencer.c msgid "could not read orig-head" -msgstr "不能讀取 orig-head" +msgstr "無法讀取 orig-head" #: sequencer.c msgid "could not read 'onto'" -msgstr "不能讀取 'onto'" +msgstr "無法讀取「onto」" #: sequencer.c #, c-format msgid "could not update HEAD to %s" -msgstr "不能更新 HEAD 為 %s" +msgstr "無法將 HEAD 更新到 %s" #: sequencer.c #, c-format @@ -25882,15 +26352,15 @@ msgstr "" #: sequencer.c #, c-format msgid "could not write file: '%s'" -msgstr "不能寫入檔案:'%s'" +msgstr "無法寫入檔案:「%s」" #: sequencer.c msgid "could not remove CHERRY_PICK_HEAD" -msgstr "不能刪除 CHERRY_PICK_HEAD" +msgstr "無法刪除 CHERRY_PICK_HEAD" #: sequencer.c msgid "could not commit staged changes." -msgstr "不能提交暫存的修改。" +msgstr "無法提交暫存的修改。" #: sequencer.c #, c-format @@ -26059,6 +26529,11 @@ msgstr "無法返回目前工作目錄" msgid "failed to stat '%*s%s%s'" msgstr "取得 '%*s%s%s' 狀態(stat)失敗" +#: setup.c +#, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory「%s」不是絕對路徑" + #: setup.c #, c-format msgid "" @@ -26305,7 +26780,7 @@ msgstr "忽略可能被解析為命令列選項的 '%s':%s" #: submodule-config.c #, c-format msgid "Could not update .gitmodules entry %s" -msgstr "不能更新 .gitmodules 條目 %s" +msgstr "無法更新 .gitmodules 條目 %s" #: submodule.c msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" @@ -26357,7 +26832,7 @@ msgstr "子模組條目 '%s'(%s)是一個 %s,不是一個提交" msgid "" "Could not run 'git rev-list <commits> --not --remotes -n 1' command in " "submodule %s" -msgstr "無法在 %s 子模組執行 'git rev-list <提交> --not --remotes -n 1' 命令" +msgstr "無法在 %s 子模組執行「git rev-list <提交> --not --remotes -n 1」命令" #: submodule.c #, c-format @@ -26411,7 +26886,7 @@ msgstr "無法將 '%s' 識別為一個 git 版本庫" #: submodule.c #, c-format msgid "Could not run 'git status --porcelain=2' in submodule %s" -msgstr "無法在 %s 子模組執行 'git status --porcelain=2'" +msgstr "無法在 %s 子模組執行「git status --porcelain=2」" #: submodule.c #, c-format @@ -26421,17 +26896,17 @@ msgstr "%s 子模組執行 'git status --porcelain=2' 失敗" #: submodule.c #, c-format msgid "could not start 'git status' in submodule '%s'" -msgstr "無法在子模組 '%s' 中啟動 'git status'" +msgstr "無法在子模組「%s」中啟動「git status」" #: submodule.c #, c-format msgid "could not run 'git status' in submodule '%s'" -msgstr "無法在子模組 '%s' 中執行 'git status'" +msgstr "無法在子模組「%s」中執行「git status」" #: submodule.c #, c-format msgid "Could not unset core.worktree setting in submodule '%s'" -msgstr "無法在子模組 '%s' 中取消 core.worktree 的設定" +msgstr "無法在子模組「%s」中取消 core.worktree 的設定" #: submodule.c #, c-format @@ -26476,7 +26951,7 @@ msgstr "不支援對有多個工作區的子模組 '%s' 執行 relocate_gitdir" #: submodule.c #, c-format msgid "could not lookup name for submodule '%s'" -msgstr "不能查詢子模組 '%s' 的名稱" +msgstr "無法查詢子模組「%s」的名稱" #: submodule.c #, c-format @@ -26528,6 +27003,34 @@ msgstr "每次迭代前清除快取樹狀物件" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "在快取樹狀物件中,要使失效的項目數量(預設值為 0)" +#: t/helper/test-path-walk.c +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <options> -- <revision-options>" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of blob objects" +msgstr "切換是否包含資料物件" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of commit objects" +msgstr "切換是否包含提交物件" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tag objects" +msgstr "切換是否包含標籤物件" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tree objects" +msgstr "切換是否包含樹狀物件" + +#: t/helper/test-path-walk.c +msgid "toggle pruning of uninteresting paths" +msgstr "切換是否剪除不重要路徑" + +#: t/helper/test-path-walk.c +msgid "read a pattern list over stdin" +msgstr "從標準輸入讀取模式清單" + #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -26537,6 +27040,10 @@ msgstr "提交 %s 沒有標記為可以取得" msgid "too many commits marked reachable" msgstr "太多提交標記為可以取得" +#: t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "無法確定 MIDX 偏好的封裝" + #: t/helper/test-serve-v2.c msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<選項>]" @@ -26617,6 +27124,30 @@ msgstr "代符" msgid "command token to send to the server" msgstr "要傳送至伺服器的命令代符" +#: t/unit-tests/unit-test.c +msgid "unit-test [<options>]" +msgstr "unit-test [<options>]" + +#: t/unit-tests/unit-test.c +msgid "immediately exit upon the first failed test" +msgstr "一旦有測試失敗就立刻退出" + +#: t/unit-tests/unit-test.c +msgid "suite[::test]" +msgstr "suite[::test]" + +#: t/unit-tests/unit-test.c +msgid "run only test suite or individual test <suite[::test]>" +msgstr "只執行測試套件或單獨的測試 <suite[::test]>" + +#: t/unit-tests/unit-test.c +msgid "suite" +msgstr "suite" + +#: t/unit-tests/unit-test.c +msgid "exclude test suite <suite>" +msgstr "排除測試套件 <suite>" + #: trailer.c #, c-format msgid "running trailer command '%s' failed" @@ -26668,7 +27199,7 @@ msgstr "%s 也鎖定了 %s" #: transport-helper.c msgid "couldn't run fast-import" -msgstr "不能執行 fast-import" +msgstr "無法執行 fast-import" #: transport-helper.c msgid "error while running fast-import" @@ -26849,7 +27380,7 @@ msgstr "伺服器不支援「等待完成」(wait-for-done) 功能" #: transport.c msgid "could not parse transport.color.* config" -msgstr "不能解析 transport.color.* 設定" +msgstr "無法解析 transport.color.* 組態" #: transport.c msgid "support for protocol v2 not implemented yet" @@ -27247,6 +27778,11 @@ msgstr "錯誤: " msgid "warning: " msgstr "警告: " +#: version.c +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() 失敗,錯誤:「%s」(%d)\n" + #: walker.c msgid "Fetching objects" msgstr "正在抓取物件" @@ -27287,6 +27823,10 @@ msgstr ".git 檔案損毀" msgid ".git file incorrect" msgstr ".git 檔案不正確" +#: worktree.c +msgid ".git file absolute/relative path mismatch" +msgstr ".git 檔案的絕對或相對路徑不一致" + #: worktree.c msgid "not a valid path" msgstr "非有效路徑" @@ -27307,6 +27847,10 @@ msgstr "無法定位版本庫;.git 檔案損壞" msgid "gitdir unreadable" msgstr "無法讀取 gitdir" +#: worktree.c +msgid "gitdir absolute/relative path mismatch" +msgstr "gitdir 的絕對或相對路徑不一致" + #: worktree.c msgid "gitdir incorrect" msgstr "不正確的 gitdir" @@ -27351,10 +27895,18 @@ msgstr "無法取消在「%2$s」設定的 %1$s" msgid "failed to set extensions.worktreeConfig setting" msgstr "無法設定 extensions.worktreeConfig 設定" +#: worktree.c +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "無法升級版本庫格式,以支援相對路徑工作區" + +#: worktree.c +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "無法設定 extensions.relativeWorktrees 設定" + #: wrapper.c #, c-format msgid "could not setenv '%s'" -msgstr "無法 setenv '%s'" +msgstr "無法 setenv「%s」" #: wrapper.c #, c-format @@ -27364,7 +27916,7 @@ msgstr "不能建立 '%s'" #: wrapper.c #, c-format msgid "could not open '%s' for reading and writing" -msgstr "無法開啟 '%s' 進行讀寫" +msgstr "無法開啟「%s」進行讀寫" #: wrapper.c #, c-format @@ -28067,6 +28619,10 @@ msgstr "'%s.final' 包含編輯的信件。\n" msgid "--dump-aliases incompatible with other options\n" msgstr "--dump-aliases 和其它選項不相容\n" +#: git-send-email.perl +msgid "--dump-aliases and --translate-aliases are mutually exclusive\n" +msgstr "--dump-aliases 和 --translate-aliases 互斥\n" + #: git-send-email.perl msgid "" "fatal: found configuration options for 'sendmail'\n" @@ -28413,6 +28969,49 @@ msgstr "略過 %s 含備份後綴 '%s'。\n" msgid "Do you really want to send %s? [y|N]: " msgstr "您真的要傳送 %s?[y|N]: " +#, c-format +#~ msgid "Could not find remote branch %s to clone." +#~ msgstr "找不到要複製的遠端分支 %s。" + +#, c-format +#~ msgid "merging cannot continue; got unclean result of %d" +#~ msgstr "無法繼續合併:從 %d 收到的結果不乾淨" + +#~ msgid "git repack [<options>]" +#~ msgstr "git repack [<選項>]" + +#~ msgid "--onto and --advance are incompatible" +#~ msgstr "--onto 和 --advance 不相容" + +#, c-format +#~ msgid "key '%s' of pattern had no '*'" +#~ msgstr "模式的鍵 '%s' 沒有 '*'" + +#, c-format +#~ msgid "preferred pack (%s) is invalid" +#~ msgstr "偏好的封包 (%s) 無效" + +#, c-format +#~ msgid "" +#~ "more than %i tags found; listed %i most recent\n" +#~ "gave up search at %s\n" +#~ msgstr "" +#~ "發現多於 %i 個標籤,列出最近的 %i 個\n" +#~ "在 %s 放棄搜尋\n" + +#~ msgid "Public key pinning not supported with cURL < 7.39.0" +#~ msgstr "不支援公鑰檔案鎖定,因為 cURL < 7.39.0" + +#~ msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" +#~ msgstr "不支援 CURLSSLOPT_NO_REVOKE,因為 cURL < 7.44.0" + +#~ msgid "revision walk setup failed\n" +#~ msgstr "修訂版遍歷設定失敗\n" + +#, c-format +#~ msgid "unable to parse contact: %s" +#~ msgstr "無法解析聯絡地址:%s" + #~ msgid "" #~ "the add.interactive.useBuiltin setting has been removed!\n" #~ "See its entry in 'git help config' for details." @@ -28433,10 +29032,6 @@ msgstr "您真的要傳送 %s?[y|N]: " #~ msgid "no URLs configured for remote '%s'" #~ msgstr "沒有給遠端版本庫 '%s' 設定 URL" -#, c-format -#~ msgid "unable to copy '%s' to '%s'" -#~ msgstr "無法複製 '%s' 至 '%s'" - #, c-format #~ msgid "remote '%s' has no configured URL" #~ msgstr "“%s” 遠端未設定 URL" diff --git a/preload-index.c b/preload-index.c index 7926eb09a695f7..40ab2abafb8de5 100644 --- a/preload-index.c +++ b/preload-index.c @@ -3,6 +3,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "pathspec.h" @@ -131,7 +132,9 @@ void preload_index(struct index_state *index, memset(&pd, 0, sizeof(pd)); if (refresh_flags & REFRESH_PROGRESS && isatty(2)) { - pd.progress = start_delayed_progress(_("Refreshing index"), index->cache_nr); + pd.progress = start_delayed_progress(the_repository, + _("Refreshing index"), + index->cache_nr); pthread_mutex_init(&pd.mutex, NULL); } diff --git a/pretty.c b/pretty.c index 6403e268900b88..0bc8ad8a9a8bc1 100644 --- a/pretty.c +++ b/pretty.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -2032,6 +2033,7 @@ void repo_format_commit_message(struct repository *r, free(context.commit_encoding); repo_unuse_commit_buffer(r, commit, context.message); + signature_check_clear(&context.signature_check); } static void pp_header(struct pretty_print_context *pp, diff --git a/prio-queue.c b/prio-queue.c index 450775a3749208..ec33ac27db1c06 100644 --- a/prio-queue.c +++ b/prio-queue.c @@ -1,26 +1,29 @@ #include "git-compat-util.h" #include "prio-queue.h" -static inline int compare(struct prio_queue *queue, int i, int j) +static inline int compare(struct prio_queue *queue, size_t i, size_t j) { int cmp = queue->compare(queue->array[i].data, queue->array[j].data, queue->cb_data); if (!cmp) - cmp = queue->array[i].ctr - queue->array[j].ctr; + cmp = (queue->array[i].ctr > queue->array[j].ctr) - + (queue->array[i].ctr < queue->array[j].ctr); return cmp; } -static inline void swap(struct prio_queue *queue, int i, int j) +static inline void swap(struct prio_queue *queue, size_t i, size_t j) { SWAP(queue->array[i], queue->array[j]); } void prio_queue_reverse(struct prio_queue *queue) { - int i, j; + size_t i, j; if (queue->compare) BUG("prio_queue_reverse() on non-LIFO queue"); + if (!queue->nr) + return; for (i = 0; i < (j = (queue->nr - 1) - i); i++) swap(queue, i, j); } @@ -35,7 +38,7 @@ void clear_prio_queue(struct prio_queue *queue) void prio_queue_put(struct prio_queue *queue, void *thing) { - int ix, parent; + size_t ix, parent; /* Append at the end */ ALLOC_GROW(queue->array, queue->nr + 1, queue->alloc); @@ -58,7 +61,7 @@ void prio_queue_put(struct prio_queue *queue, void *thing) void *prio_queue_get(struct prio_queue *queue) { void *result; - int ix, child; + size_t ix, child; if (!queue->nr) return NULL; diff --git a/prio-queue.h b/prio-queue.h index 4f9a37e6bee5b5..38d032636d4cf9 100644 --- a/prio-queue.h +++ b/prio-queue.h @@ -22,15 +22,15 @@ typedef int (*prio_queue_compare_fn)(const void *one, const void *two, void *cb_data); struct prio_queue_entry { - unsigned ctr; + size_t ctr; void *data; }; struct prio_queue { prio_queue_compare_fn compare; - unsigned insertion_ctr; + size_t insertion_ctr; void *cb_data; - int alloc, nr; + size_t alloc, nr; struct prio_queue_entry *array; }; diff --git a/progress.c b/progress.c index 0d44c18edc0c52..8d5ae70f3a9ec7 100644 --- a/progress.c +++ b/progress.c @@ -9,7 +9,7 @@ */ #define GIT_TEST_PROGRESS_ONLY -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "pager.h" @@ -36,6 +36,7 @@ struct throughput { }; struct progress { + struct repository *repo; const char *title; uint64_t last_value; uint64_t total; @@ -253,10 +254,12 @@ void display_progress(struct progress *progress, uint64_t n) display(progress, n, NULL); } -static struct progress *start_progress_delay(const char *title, uint64_t total, +static struct progress *start_progress_delay(struct repository *r, + const char *title, uint64_t total, unsigned delay, unsigned sparse) { struct progress *progress = xmalloc(sizeof(*progress)); + progress->repo = r; progress->title = title; progress->total = total; progress->last_value = -1; @@ -269,7 +272,7 @@ static struct progress *start_progress_delay(const char *title, uint64_t total, progress->title_len = utf8_strwidth(title); progress->split = 0; set_progress_signal(); - trace2_region_enter("progress", title, the_repository); + trace2_region_enter("progress", title, r); return progress; } @@ -283,14 +286,16 @@ static int get_default_delay(void) return delay_in_secs; } -struct progress *start_delayed_progress(const char *title, uint64_t total) +struct progress *start_delayed_progress(struct repository *r, + const char *title, uint64_t total) { - return start_progress_delay(title, total, get_default_delay(), 0); + return start_progress_delay(r, title, total, get_default_delay(), 0); } -struct progress *start_progress(const char *title, uint64_t total) +struct progress *start_progress(struct repository *r, + const char *title, uint64_t total) { - return start_progress_delay(title, total, 0, 0); + return start_progress_delay(r, title, total, 0, 0); } /* @@ -302,15 +307,17 @@ struct progress *start_progress(const char *title, uint64_t total) * When "sparse" is set, stop_progress() will automatically force the done * message to show 100%. */ -struct progress *start_sparse_progress(const char *title, uint64_t total) +struct progress *start_sparse_progress(struct repository *r, + const char *title, uint64_t total) { - return start_progress_delay(title, total, 0, 1); + return start_progress_delay(r, title, total, 0, 1); } -struct progress *start_delayed_sparse_progress(const char *title, +struct progress *start_delayed_sparse_progress(struct repository *r, + const char *title, uint64_t total) { - return start_progress_delay(title, total, get_default_delay(), 1); + return start_progress_delay(r, title, total, get_default_delay(), 1); } static void finish_if_sparse(struct progress *progress) @@ -340,14 +347,14 @@ static void force_last_update(struct progress *progress, const char *msg) static void log_trace2(struct progress *progress) { - trace2_data_intmax("progress", the_repository, "total_objects", + trace2_data_intmax("progress", progress->repo, "total_objects", progress->total); if (progress->throughput) - trace2_data_intmax("progress", the_repository, "total_bytes", + trace2_data_intmax("progress", progress->repo, "total_bytes", progress->throughput->curr_total); - trace2_region_leave("progress", progress->title, the_repository); + trace2_region_leave("progress", progress->title, progress->repo); } void stop_progress_msg(struct progress **p_progress, const char *msg) diff --git a/progress.h b/progress.h index 3a945637c81c22..ed068c7bab845b 100644 --- a/progress.h +++ b/progress.h @@ -3,6 +3,7 @@ #include "gettext.h" struct progress; +struct repository; #ifdef GIT_TEST_PROGRESS_ONLY @@ -14,10 +15,14 @@ void progress_test_force_update(void); void display_throughput(struct progress *progress, uint64_t total); void display_progress(struct progress *progress, uint64_t n); -struct progress *start_progress(const char *title, uint64_t total); -struct progress *start_sparse_progress(const char *title, uint64_t total); -struct progress *start_delayed_progress(const char *title, uint64_t total); -struct progress *start_delayed_sparse_progress(const char *title, +struct progress *start_progress(struct repository *r, + const char *title, uint64_t total); +struct progress *start_sparse_progress(struct repository *r, + const char *title, uint64_t total); +struct progress *start_delayed_progress(struct repository *r, + const char *title, uint64_t total); +struct progress *start_delayed_sparse_progress(struct repository *r, + const char *title, uint64_t total); void stop_progress_msg(struct progress **p_progress, const char *msg); static inline void stop_progress(struct progress **p_progress) diff --git a/promisor-remote.c b/promisor-remote.c index 317e1b127fede4..6a0a61382f40c0 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -11,6 +11,8 @@ #include "strvec.h" #include "packfile.h" #include "environment.h" +#include "url.h" +#include "version.h" struct promisor_remote_config { struct promisor_remote *promisors; @@ -154,6 +156,7 @@ static int promisor_remote_config(const char *var, const char *value, if (!r) return 0; + FREE_AND_NULL(r->partial_clone_filter); return git_config_string(&r->partial_clone_filter, var, value); } @@ -189,6 +192,7 @@ void promisor_remote_clear(struct promisor_remote_config *config) { while (config->promisors) { struct promisor_remote *r = config->promisors; + free(r->partial_clone_filter); config->promisors = config->promisors->next; free(r); } @@ -219,6 +223,18 @@ int repo_has_promisor_remote(struct repository *r) return !!repo_promisor_remote_find(r, NULL); } +int repo_has_accepted_promisor_remote(struct repository *r) +{ + struct promisor_remote *p; + + promisor_remote_init(r); + + for (p = r->promisor_remote_config->promisors; p; p = p->next) + if (p->accepted) + return 1; + return 0; +} + static int remove_fetched_oids(struct repository *repo, struct object_id **oids, int oid_nr, int to_free) @@ -281,7 +297,7 @@ void promisor_remote_get_direct(struct repository *repo, } for (i = 0; i < remaining_nr; i++) { - if (is_promisor_object(&remaining_oids[i])) + if (is_promisor_object(repo, &remaining_oids[i])) die(_("could not fetch %s from promisor remote"), oid_to_hex(&remaining_oids[i])); } @@ -290,3 +306,231 @@ void promisor_remote_get_direct(struct repository *repo, if (to_free) free(remaining_oids); } + +static int allow_unsanitized(char ch) +{ + if (ch == ',' || ch == ';' || ch == '%') + return 0; + return ch > 32 && ch < 127; +} + +static void promisor_info_vecs(struct repository *repo, + struct strvec *names, + struct strvec *urls) +{ + struct promisor_remote *r; + + promisor_remote_init(repo); + + for (r = repo->promisor_remote_config->promisors; r; r = r->next) { + char *url; + char *url_key = xstrfmt("remote.%s.url", r->name); + + strvec_push(names, r->name); + strvec_push(urls, git_config_get_string(url_key, &url) ? NULL : url); + + free(url); + free(url_key); + } +} + +char *promisor_remote_info(struct repository *repo) +{ + struct strbuf sb = STRBUF_INIT; + int advertise_promisors = 0; + struct strvec names = STRVEC_INIT; + struct strvec urls = STRVEC_INIT; + + git_config_get_bool("promisor.advertise", &advertise_promisors); + + if (!advertise_promisors) + return NULL; + + promisor_info_vecs(repo, &names, &urls); + + if (!names.nr) + return NULL; + + for (size_t i = 0; i < names.nr; i++) { + if (i) + strbuf_addch(&sb, ';'); + strbuf_addstr(&sb, "name="); + strbuf_addstr_urlencode(&sb, names.v[i], allow_unsanitized); + if (urls.v[i]) { + strbuf_addstr(&sb, ",url="); + strbuf_addstr_urlencode(&sb, urls.v[i], allow_unsanitized); + } + } + + strvec_clear(&names); + strvec_clear(&urls); + + return strbuf_detach(&sb, NULL); +} + +/* + * Find first index of 'nicks' where there is 'nick'. 'nick' is + * compared case insensitively to the strings in 'nicks'. If not found + * 'nicks->nr' is returned. + */ +static size_t remote_nick_find(struct strvec *nicks, const char *nick) +{ + for (size_t i = 0; i < nicks->nr; i++) + if (!strcasecmp(nicks->v[i], nick)) + return i; + return nicks->nr; +} + +enum accept_promisor { + ACCEPT_NONE = 0, + ACCEPT_KNOWN_URL, + ACCEPT_KNOWN_NAME, + ACCEPT_ALL +}; + +static int should_accept_remote(enum accept_promisor accept, + const char *remote_name, const char *remote_url, + struct strvec *names, struct strvec *urls) +{ + size_t i; + + if (accept == ACCEPT_ALL) + return 1; + + i = remote_nick_find(names, remote_name); + + if (i >= names->nr) + /* We don't know about that remote */ + return 0; + + if (accept == ACCEPT_KNOWN_NAME) + return 1; + + if (accept != ACCEPT_KNOWN_URL) + BUG("Unhandled 'enum accept_promisor' value '%d'", accept); + + if (!strcmp(urls->v[i], remote_url)) + return 1; + + warning(_("known remote named '%s' but with url '%s' instead of '%s'"), + remote_name, urls->v[i], remote_url); + + return 0; +} + +static void filter_promisor_remote(struct repository *repo, + struct strvec *accepted, + const char *info) +{ + struct strbuf **remotes; + const char *accept_str; + enum accept_promisor accept = ACCEPT_NONE; + struct strvec names = STRVEC_INIT; + struct strvec urls = STRVEC_INIT; + + if (!git_config_get_string_tmp("promisor.acceptfromserver", &accept_str)) { + if (!*accept_str || !strcasecmp("None", accept_str)) + accept = ACCEPT_NONE; + else if (!strcasecmp("KnownUrl", accept_str)) + accept = ACCEPT_KNOWN_URL; + else if (!strcasecmp("KnownName", accept_str)) + accept = ACCEPT_KNOWN_NAME; + else if (!strcasecmp("All", accept_str)) + accept = ACCEPT_ALL; + else + warning(_("unknown '%s' value for '%s' config option"), + accept_str, "promisor.acceptfromserver"); + } + + if (accept == ACCEPT_NONE) + return; + + if (accept != ACCEPT_ALL) + promisor_info_vecs(repo, &names, &urls); + + /* Parse remote info received */ + + remotes = strbuf_split_str(info, ';', 0); + + for (size_t i = 0; remotes[i]; i++) { + struct strbuf **elems; + const char *remote_name = NULL; + const char *remote_url = NULL; + char *decoded_name = NULL; + char *decoded_url = NULL; + + strbuf_strip_suffix(remotes[i], ";"); + elems = strbuf_split(remotes[i], ','); + + for (size_t j = 0; elems[j]; j++) { + int res; + strbuf_strip_suffix(elems[j], ","); + res = skip_prefix(elems[j]->buf, "name=", &remote_name) || + skip_prefix(elems[j]->buf, "url=", &remote_url); + if (!res) + warning(_("unknown element '%s' from remote info"), + elems[j]->buf); + } + + if (remote_name) + decoded_name = url_percent_decode(remote_name); + if (remote_url) + decoded_url = url_percent_decode(remote_url); + + if (decoded_name && should_accept_remote(accept, decoded_name, decoded_url, &names, &urls)) + strvec_push(accepted, decoded_name); + + strbuf_list_free(elems); + free(decoded_name); + free(decoded_url); + } + + strvec_clear(&names); + strvec_clear(&urls); + strbuf_list_free(remotes); +} + +char *promisor_remote_reply(const char *info) +{ + struct strvec accepted = STRVEC_INIT; + struct strbuf reply = STRBUF_INIT; + + filter_promisor_remote(the_repository, &accepted, info); + + if (!accepted.nr) + return NULL; + + for (size_t i = 0; i < accepted.nr; i++) { + if (i) + strbuf_addch(&reply, ';'); + strbuf_addstr_urlencode(&reply, accepted.v[i], allow_unsanitized); + } + + strvec_clear(&accepted); + + return strbuf_detach(&reply, NULL); +} + +void mark_promisor_remotes_as_accepted(struct repository *r, const char *remotes) +{ + struct strbuf **accepted_remotes = strbuf_split_str(remotes, ';', 0); + + for (size_t i = 0; accepted_remotes[i]; i++) { + struct promisor_remote *p; + char *decoded_remote; + + strbuf_strip_suffix(accepted_remotes[i], ";"); + decoded_remote = url_percent_decode(accepted_remotes[i]->buf); + + p = repo_promisor_remote_find(r, decoded_remote); + if (p) + p->accepted = 1; + else + warning(_("accepted promisor remote '%s' not found"), + decoded_remote); + + free(decoded_remote); + } + + strbuf_list_free(accepted_remotes); +} diff --git a/promisor-remote.h b/promisor-remote.h index 88cb599c391aea..263d331a551b6c 100644 --- a/promisor-remote.h +++ b/promisor-remote.h @@ -9,11 +9,13 @@ struct object_id; * Promisor remote linked list * * Information in its fields come from remote.XXX config entries or - * from extensions.partialclone. + * from extensions.partialclone, except for 'accepted' which comes + * from protocol v2 capabilities exchange. */ struct promisor_remote { struct promisor_remote *next; char *partial_clone_filter; + unsigned int accepted : 1; const char name[FLEX_ARRAY]; }; @@ -32,4 +34,37 @@ void promisor_remote_get_direct(struct repository *repo, const struct object_id *oids, int oid_nr); +/* + * Prepare a "promisor-remote" advertisement by a server. + * Check the value of "promisor.advertise" and maybe the configured + * promisor remotes, if any, to prepare information to send in an + * advertisement. + * Return value is NULL if no promisor remote advertisement should be + * made. Otherwise it contains the names and urls of the advertised + * promisor remotes separated by ';'. See gitprotocol-v2(5). + */ +char *promisor_remote_info(struct repository *repo); + +/* + * Prepare a reply to a "promisor-remote" advertisement from a server. + * Check the value of "promisor.acceptfromserver" and maybe the + * configured promisor remotes, if any, to prepare the reply. + * Return value is NULL if no promisor remote from the server + * is accepted. Otherwise it contains the names of the accepted promisor + * remotes separated by ';'. See gitprotocol-v2(5). + */ +char *promisor_remote_reply(const char *info); + +/* + * Set the 'accepted' flag for some promisor remotes. Useful on the + * server side when some promisor remotes have been accepted by the + * client. + */ +void mark_promisor_remotes_as_accepted(struct repository *repo, const char *remotes); + +/* + * Has any promisor remote been accepted by the client? + */ +int repo_has_accepted_promisor_remote(struct repository *r); + #endif /* PROMISOR_REMOTE_H */ diff --git a/prune-packed.c b/prune-packed.c index 2bb99c29dfb3c0..7dad2fc0c169cf 100644 --- a/prune-packed.c +++ b/prune-packed.c @@ -24,7 +24,7 @@ static int prune_object(const struct object_id *oid, const char *path, { int *opts = data; - if (!has_object_pack(oid)) + if (!has_object_pack(the_repository, oid)) return 0; if (*opts & PRUNE_PACKED_DRY_RUN) @@ -37,7 +37,8 @@ static int prune_object(const struct object_id *oid, const char *path, void prune_packed_objects(int opts) { if (opts & PRUNE_PACKED_VERBOSE) - progress = start_delayed_progress(_("Removing duplicate objects"), 256); + progress = start_delayed_progress(the_repository, + _("Removing duplicate objects"), 256); for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), prune_object, NULL, prune_subdir, &opts); diff --git a/pseudo-merge.c b/pseudo-merge.c index 10ebd9a4e9639b..893b763fe45490 100644 --- a/pseudo-merge.c +++ b/pseudo-merge.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "pseudo-merge.h" @@ -87,7 +88,7 @@ static void pseudo_merge_group_init(struct pseudo_merge_group *group) { memset(group, 0, sizeof(struct pseudo_merge_group)); - strmap_init_with_options(&group->matches, NULL, 0); + strmap_init_with_options(&group->matches, NULL, 1); group->decay = DEFAULT_PSEUDO_MERGE_DECAY; group->max_merges = DEFAULT_PSEUDO_MERGE_MAX_MERGES; @@ -97,6 +98,25 @@ static void pseudo_merge_group_init(struct pseudo_merge_group *group) group->stable_size = DEFAULT_PSEUDO_MERGE_STABLE_SIZE; } +void pseudo_merge_group_release(struct pseudo_merge_group *group) +{ + struct hashmap_iter iter; + struct strmap_entry *e; + + regfree(group->pattern); + free(group->pattern); + + strmap_for_each_entry(&group->matches, &iter, e) { + struct pseudo_merge_matches *matches = e->value; + free(matches->stable); + free(matches->unstable); + free(matches); + } + strmap_clear(&group->matches, 0); + + free(group->merges); +} + static int pseudo_merge_config(const char *var, const char *value, const struct config_context *ctx, void *cb_data) @@ -256,7 +276,7 @@ static int find_pseudo_merge_group_for_ref(const char *refname, matches = strmap_get(&group->matches, group_name.buf); if (!matches) { matches = xcalloc(1, sizeof(*matches)); - strmap_put(&group->matches, strbuf_detach(&group_name, NULL), + strmap_put(&group->matches, group_name.buf, matches); } @@ -439,7 +459,8 @@ void select_pseudo_merges(struct bitmap_writer *writer) return; if (writer->show_progress) - progress = start_progress("Selecting pseudo-merge commits", + progress = start_progress(the_repository, + "Selecting pseudo-merge commits", writer->pseudo_merge_groups.nr); refs_for_each_ref(get_main_ref_store(the_repository), diff --git a/pseudo-merge.h b/pseudo-merge.h index 4b5febaa63e6fe..c9fbe9d3129583 100644 --- a/pseudo-merge.h +++ b/pseudo-merge.h @@ -51,6 +51,8 @@ struct pseudo_merge_group { timestamp_t stable_threshold; }; +void pseudo_merge_group_release(struct pseudo_merge_group *group); + struct pseudo_merge_matches { struct commit **stable; struct commit **unstable; @@ -99,7 +101,7 @@ void select_pseudo_merges(struct bitmap_writer *writer); /* * Represents a serialized view of a file containing pseudo-merge(s) - * (see Documentation/technical/bitmap-format.txt for a specification + * (see Documentation/technical/bitmap-format.adoc for a specification * of the format). */ struct pseudo_merge_map { diff --git a/quote.c b/quote.c index 3c05194496f65f..b9f6bdc775c468 100644 --- a/quote.c +++ b/quote.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "path.h" #include "quote.h" diff --git a/range-diff.c b/range-diff.c index bbb0952264b817..9501c358a84174 100644 --- a/range-diff.c +++ b/range-diff.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" @@ -38,7 +39,8 @@ struct patch_util { * as struct object_id (will need to be free()d). */ static int read_patches(const char *range, struct string_list *list, - const struct strvec *other_arg) + const struct strvec *other_arg, + unsigned int include_merges) { struct child_process cp = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT, contents = STRBUF_INIT; @@ -49,7 +51,7 @@ static int read_patches(const char *range, struct string_list *list, size_t size; int ret = -1; - strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges", + strvec_pushl(&cp.args, "log", "--no-color", "-p", "--reverse", "--date-order", "--decorate=no", "--no-prefix", "--submodule=short", /* @@ -64,6 +66,8 @@ static int read_patches(const char *range, struct string_list *list, "--pretty=medium", "--show-notes-by-default", NULL); + if (!include_merges) + strvec_push(&cp.args, "--no-merges"); strvec_push(&cp.args, range); if (other_arg) strvec_pushv(&cp.args, other_arg->v); @@ -96,11 +100,14 @@ static int read_patches(const char *range, struct string_list *list, } if (skip_prefix(line, "commit ", &p)) { + char *q; if (util) { string_list_append(list, buf.buf)->util = util; strbuf_reset(&buf); } CALLOC_ARRAY(util, 1); + if (include_merges && (q = strstr(p, " (from "))) + *q = '\0'; if (repo_get_oid(the_repository, p, &util->oid)) { error(_("could not parse commit '%s'"), p); FREE_AND_NULL(util); @@ -480,7 +487,7 @@ static void patch_diff(const char *a, const char *b, diff_flush(diffopt); } -static struct strbuf *output_prefix_cb(struct diff_options *opt UNUSED, void *data) +static const char *output_prefix_cb(struct diff_options *opt UNUSED, void *data) { return data; } @@ -508,7 +515,7 @@ static void output(struct string_list *a, struct string_list *b, opts.flags.suppress_hunk_header_line_count = 1; opts.output_prefix = output_prefix_cb; strbuf_addstr(&indent, " "); - opts.output_prefix_data = &indent; + opts.output_prefix_data = indent.buf; diff_setup_done(&opts); /* @@ -571,13 +578,14 @@ int show_range_diff(const char *range1, const char *range2, struct string_list branch1 = STRING_LIST_INIT_DUP; struct string_list branch2 = STRING_LIST_INIT_DUP; + unsigned int include_merges = range_diff_opts->include_merges; if (range_diff_opts->left_only && range_diff_opts->right_only) res = error(_("options '%s' and '%s' cannot be used together"), "--left-only", "--right-only"); - if (!res && read_patches(range1, &branch1, range_diff_opts->other_arg)) + if (!res && read_patches(range1, &branch1, range_diff_opts->other_arg, include_merges)) res = error(_("could not parse log for '%s'"), range1); - if (!res && read_patches(range2, &branch2, range_diff_opts->other_arg)) + if (!res && read_patches(range2, &branch2, range_diff_opts->other_arg, include_merges)) res = error(_("could not parse log for '%s'"), range2); if (!res) { diff --git a/range-diff.h b/range-diff.h index 2f69f6a434d7d0..cd85000b5a0da0 100644 --- a/range-diff.h +++ b/range-diff.h @@ -16,6 +16,7 @@ struct range_diff_options { int creation_factor; unsigned dual_color:1; unsigned left_only:1, right_only:1; + unsigned include_merges:1; const struct diff_options *diffopt; /* may be NULL */ const struct strvec *other_arg; /* may be NULL */ }; diff --git a/reachable.c b/reachable.c index 3e9b3dd0a46cb4..9ee04c89ec6151 100644 --- a/reachable.c +++ b/reachable.c @@ -65,8 +65,10 @@ static void add_rebase_files(struct rev_info *revs) struct worktree **worktrees = get_worktrees(); for (struct worktree **wt = worktrees; *wt; wt++) { + char *wt_gitdir = get_worktree_git_dir(*wt); + strbuf_reset(&buf); - strbuf_addstr(&buf, get_worktree_git_dir(*wt)); + strbuf_addstr(&buf, wt_gitdir); strbuf_complete(&buf, '/'); len = buf.len; for (size_t i = 0; i < ARRAY_SIZE(path); i++) { @@ -74,6 +76,8 @@ static void add_rebase_files(struct rev_info *revs) strbuf_addstr(&buf, path[i]); add_one_file(buf.buf, revs); } + + free(wt_gitdir); } strbuf_release(&buf); free_worktrees(worktrees); @@ -239,7 +243,7 @@ static int want_recent_object(struct recent_data *data, const struct object_id *oid) { if (data->ignore_in_core_kept_packs && - has_object_kept_pack(oid, IN_CORE_KEEP_PACKS)) + has_object_kept_pack(data->revs->repo, oid, IN_CORE_KEEP_PACKS)) return 0; return 1; } @@ -324,7 +328,7 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, if (ignore_in_core_kept_packs) flags |= FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS; - r = for_each_packed_object(add_recent_packed, &data, flags); + r = for_each_packed_object(revs->repo, add_recent_packed, &data, flags); done: oidset_clear(&data.extra_recent_oids); diff --git a/read-cache-ll.h b/read-cache-ll.h index b5d11d07a86962..71b49d9af48a9d 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -196,7 +196,7 @@ struct index_state { * * If the variable won't be used again, use release_index() to free() * its resources. If it needs to be used again use discard_index(), - * which does the same thing, but will use use index_state_init() at + * which does the same thing, but will use index_state_init() at * the end. The discard_index() will use its own "istate->repo" as the * "r" argument to index_state_init() in that case. */ diff --git a/read-cache.c b/read-cache.c index 764fdfec46582a..e678c13e8f15e2 100644 --- a/read-cache.c +++ b/read-cache.c @@ -5,6 +5,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "bulk-checkin.h" @@ -1522,7 +1523,8 @@ int refresh_index(struct index_state *istate, unsigned int flags, int t2_sum_scan = 0; if (flags & REFRESH_PROGRESS && isatty(2)) - progress = start_delayed_progress(_("Refresh index"), + progress = start_delayed_progress(the_repository, + _("Refresh index"), istate->cache_nr); trace_performance_enter(); @@ -1715,7 +1717,7 @@ int verify_ce_order; static int verify_hdr(const struct cache_header *hdr, unsigned long size) { - git_hash_ctx c; + struct git_hash_ctx c; unsigned char hash[GIT_MAX_RAWSZ]; int hdr_version; unsigned char *start, *end; @@ -1737,8 +1739,8 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size) return 0; the_hash_algo->init_fn(&c); - the_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz); - the_hash_algo->final_fn(hash, &c); + git_hash_update(&c, hdr, size - the_hash_algo->rawsz); + git_hash_final(hash, &c); if (!hasheq(hash, start, the_repository->hash_algo)) return error(_("bad index file sha1 signature")); return 0; @@ -1752,7 +1754,7 @@ static int read_index_extension(struct index_state *istate, istate->cache_tree = cache_tree_read(data, sz); break; case CACHE_EXT_RESOLVE_UNDO: - istate->resolve_undo = resolve_undo_read(data, sz); + istate->resolve_undo = resolve_undo_read(data, sz, the_hash_algo); break; case CACHE_EXT_LINK: if (read_link_extension(istate, data, sz)) @@ -2000,7 +2002,7 @@ static struct index_entry_offset_table *read_ieot_extension(const char *mmap, si static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_table *ieot); static size_t read_eoie_extension(const char *mmap, size_t mmap_size); -static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context, size_t offset); +static void write_eoie_extension(struct strbuf *sb, struct git_hash_ctx *eoie_context, size_t offset); struct load_index_extensions { @@ -2188,6 +2190,7 @@ static unsigned long load_cache_entries_threaded(struct index_state *istate, con if (err) die(_("unable to join load_cache_entries thread: %s"), strerror(err)); mem_pool_combine(istate->ce_mem_pool, p->ce_mem_pool); + free(p->ce_mem_pool); consumed += p->consumed; } @@ -2563,7 +2566,7 @@ int repo_index_has_changes(struct repository *repo, } static int write_index_ext_header(struct hashfile *f, - git_hash_ctx *eoie_f, + struct git_hash_ctx *eoie_f, unsigned int ext, unsigned int sz) { @@ -2573,8 +2576,8 @@ static int write_index_ext_header(struct hashfile *f, if (eoie_f) { ext = htonl(ext); sz = htonl(sz); - the_hash_algo->update_fn(eoie_f, &ext, sizeof(ext)); - the_hash_algo->update_fn(eoie_f, &sz, sizeof(sz)); + git_hash_update(eoie_f, &ext, sizeof(ext)); + git_hash_update(eoie_f, &sz, sizeof(sz)); } return 0; } @@ -2828,7 +2831,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, { uint64_t start = getnanotime(); struct hashfile *f; - git_hash_ctx *eoie_c = NULL; + struct git_hash_ctx *eoie_c = NULL; struct cache_header hdr; int i, err = 0, removed, extended, hdr_version; struct cache_entry **cache = istate->cache; @@ -3030,7 +3033,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, istate->resolve_undo) { strbuf_reset(&sb); - resolve_undo_write(&sb, istate->resolve_undo); + resolve_undo_write(&sb, istate->resolve_undo, the_hash_algo); err = write_index_ext_header(f, eoie_c, CACHE_EXT_RESOLVE_UNDO, sb.len) < 0; hashwrite(f, sb.buf, sb.len); @@ -3124,6 +3127,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, if (f) free_hashfile(f); strbuf_release(&sb); + free(eoie_c); free(ieot); return ret; } @@ -3247,15 +3251,18 @@ static int clean_shared_index_files(const char *current_hex) while ((de = readdir(dir)) != NULL) { const char *sha1_hex; - const char *shared_index_path; + char *shared_index_path; if (!skip_prefix(de->d_name, "sharedindex.", &sha1_hex)) continue; if (!strcmp(sha1_hex, current_hex)) continue; - shared_index_path = git_path("%s", de->d_name); + + shared_index_path = repo_git_path(the_repository, "%s", de->d_name); if (should_delete_shared_index(shared_index_path) > 0 && unlink(shared_index_path)) warning_errno(_("unable to unlink: %s"), shared_index_path); + + free(shared_index_path); } closedir(dir); @@ -3267,6 +3274,7 @@ static int write_shared_index(struct index_state *istate, { struct split_index *si = istate->split_index; int ret, was_full = !istate->sparse_index; + char *path; move_cache_to_base_index(istate); convert_to_sparse(istate, 0); @@ -3282,18 +3290,20 @@ static int write_shared_index(struct index_state *istate, if (ret) return ret; - ret = adjust_shared_perm(get_tempfile_path(*temp)); + ret = adjust_shared_perm(the_repository, get_tempfile_path(*temp)); if (ret) { error(_("cannot fix permission bits on '%s'"), get_tempfile_path(*temp)); return ret; } - ret = rename_tempfile(temp, - git_path("sharedindex.%s", oid_to_hex(&si->base->oid))); + + path = repo_git_path(the_repository, "sharedindex.%s", oid_to_hex(&si->base->oid)); + ret = rename_tempfile(temp, path); if (!ret) { oidcpy(&si->base_oid, &si->base->oid); clean_shared_index_files(oid_to_hex(&si->base->oid)); } + free(path); return ret; } @@ -3333,8 +3343,9 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, int new_shared_index, ret, test_split_index_env; struct split_index *si = istate->split_index; - if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0)) - cache_tree_verify(the_repository, istate); + if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0) && + cache_tree_verify(the_repository, istate) < 0) + return -1; if ((flags & SKIP_IF_UNCHANGED) && !istate->cache_changed) { if (flags & COMMIT_LOCK) @@ -3373,9 +3384,12 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, if (new_shared_index) { struct tempfile *temp; int saved_errno; + char *path; /* Same initial permissions as the main .git/index file */ - temp = mks_tempfile_sm(git_path("sharedindex_XXXXXX"), 0, 0666); + path = repo_git_path(the_repository, "sharedindex_XXXXXX"); + temp = mks_tempfile_sm(path, 0, 0666); + free(path); if (!temp) { ret = do_write_locked_index(istate, lock, flags, ~WRITE_SPLIT_INDEX_EXTENSION); @@ -3396,9 +3410,10 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, /* Freshen the shared index only if the split-index was written */ if (!ret && !new_shared_index && !is_null_oid(&si->base_oid)) { - const char *shared_index = git_path("sharedindex.%s", - oid_to_hex(&si->base_oid)); + char *shared_index = repo_git_path(the_repository, "sharedindex.%s", + oid_to_hex(&si->base_oid)); freshen_shared_index(shared_index, 1); + free(shared_index); } out: @@ -3574,7 +3589,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size) uint32_t extsize; size_t offset, src_offset; unsigned char hash[GIT_MAX_RAWSZ]; - git_hash_ctx c; + struct git_hash_ctx c; /* ensure we have an index big enough to contain an EOIE extension */ if (mmap_size < sizeof(struct cache_header) + EOIE_SIZE_WITH_HEADER + the_hash_algo->rawsz) @@ -3629,12 +3644,12 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size) if (src_offset + 8 + extsize < src_offset) return 0; - the_hash_algo->update_fn(&c, mmap + src_offset, 8); + git_hash_update(&c, mmap + src_offset, 8); src_offset += 8; src_offset += extsize; } - the_hash_algo->final_fn(hash, &c); + git_hash_final(hash, &c); if (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo)) return 0; @@ -3645,7 +3660,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size) return offset; } -static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context, size_t offset) +static void write_eoie_extension(struct strbuf *sb, struct git_hash_ctx *eoie_context, size_t offset) { uint32_t buffer; unsigned char hash[GIT_MAX_RAWSZ]; @@ -3655,7 +3670,7 @@ static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context, strbuf_add(sb, &buffer, sizeof(uint32_t)); /* hash */ - the_hash_algo->final_fn(hash, eoie_context); + git_hash_final(hash, eoie_context); strbuf_add(sb, hash, the_hash_algo->rawsz); } diff --git a/ref-filter.c b/ref-filter.c index dd195007ce1c61..6da8d4c03b62bf 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" @@ -234,6 +235,10 @@ static struct used_atom { enum { S_BARE, S_GRADE, S_SIGNER, S_KEY, S_FINGERPRINT, S_PRI_KEY_FP, S_TRUST_LEVEL } option; } signature; + struct { + char *name; + struct commit *commit; + } base; struct strvec describe_args; struct refname_atom refname; char *head; @@ -890,35 +895,30 @@ static int rest_atom_parser(struct ref_format *format UNUSED, return 0; } -static int ahead_behind_atom_parser(struct ref_format *format, - struct used_atom *atom UNUSED, +static int ahead_behind_atom_parser(struct ref_format *format UNUSED, + struct used_atom *atom, const char *arg, struct strbuf *err) { - struct string_list_item *item; - if (!arg) return strbuf_addf_ret(err, -1, _("expected format: %%(ahead-behind:<committish>)")); - item = string_list_append(&format->bases, arg); - item->util = lookup_commit_reference_by_name(arg); - if (!item->util) + atom->u.base.commit = lookup_commit_reference_by_name(arg); + if (!atom->u.base.commit) die("failed to find '%s'", arg); return 0; } -static int is_base_atom_parser(struct ref_format *format, - struct used_atom *atom UNUSED, +static int is_base_atom_parser(struct ref_format *format UNUSED, + struct used_atom *atom, const char *arg, struct strbuf *err) { - struct string_list_item *item; - if (!arg) return strbuf_addf_ret(err, -1, _("expected format: %%(is-base:<committish>)")); - item = string_list_append(&format->is_base_tips, arg); - item->util = lookup_commit_reference_by_name(arg); - if (!item->util) + atom->u.base.name = xstrdup(arg); + atom->u.base.commit = lookup_commit_reference_by_name(arg); + if (!atom->u.base.commit) die("failed to find '%s'", arg); return 0; @@ -3008,6 +3008,8 @@ void ref_array_clear(struct ref_array *array) free(atom->u.head); else if (atom->atom_type == ATOM_DESCRIBE) strvec_clear(&atom->u.describe_args); + else if (atom->atom_type == ATOM_ISBASE) + free(atom->u.base.name); else if (atom->atom_type == ATOM_TRAILERS || (atom->atom_type == ATOM_CONTENTS && atom->u.contents.option == C_TRAILERS)) { @@ -3040,7 +3042,7 @@ static void reach_filter(struct ref_array *array, struct commit_list **check_reachable, int include_reached) { - int i, old_nr; + size_t i, old_nr; struct commit **to_clear; if (!*check_reachable) @@ -3083,22 +3085,30 @@ static void reach_filter(struct ref_array *array, } void filter_ahead_behind(struct repository *r, - struct ref_format *format, struct ref_array *array) { struct commit **commits; - size_t commits_nr = format->bases.nr + array->nr; + size_t bases_nr, commits_nr; - if (!format->bases.nr || !array->nr) + if (!array->nr) + return; + + for (size_t i = bases_nr = 0; i < used_atom_cnt; i++) { + if (used_atom[i].atom_type == ATOM_AHEADBEHIND) + bases_nr++; + } + if (!bases_nr) return; - ALLOC_ARRAY(commits, commits_nr); - for (size_t i = 0; i < format->bases.nr; i++) - commits[i] = format->bases.items[i].util; + ALLOC_ARRAY(commits, st_add(bases_nr, array->nr)); + for (size_t i = 0, j = 0; i < used_atom_cnt; i++) { + if (used_atom[i].atom_type == ATOM_AHEADBEHIND) + commits[j++] = used_atom[i].u.base.commit; + } - ALLOC_ARRAY(array->counts, st_mult(format->bases.nr, array->nr)); + ALLOC_ARRAY(array->counts, st_mult(bases_nr, array->nr)); - commits_nr = format->bases.nr; + commits_nr = bases_nr; array->counts_nr = 0; for (size_t i = 0; i < array->nr; i++) { const char *name = array->items[i]->refname; @@ -3107,8 +3117,8 @@ void filter_ahead_behind(struct repository *r, if (!commits[commits_nr]) continue; - CALLOC_ARRAY(array->items[i]->counts, format->bases.nr); - for (size_t j = 0; j < format->bases.nr; j++) { + CALLOC_ARRAY(array->items[i]->counts, bases_nr); + for (size_t j = 0; j < bases_nr; j++) { struct ahead_behind_count *count; count = &array->counts[array->counts_nr++]; count->tip_index = commits_nr; @@ -3124,14 +3134,20 @@ void filter_ahead_behind(struct repository *r, } void filter_is_base(struct repository *r, - struct ref_format *format, struct ref_array *array) { struct commit **bases; - size_t bases_nr = 0; + size_t bases_nr = 0, is_base_nr; struct ref_array_item **back_index; - if (!format->is_base_tips.nr || !array->nr) + if (!array->nr) + return; + + for (size_t i = is_base_nr = 0; i < used_atom_cnt; i++) { + if (used_atom[i].atom_type == ATOM_ISBASE) + is_base_nr++; + } + if (!is_base_nr) return; CALLOC_ARRAY(back_index, array->nr); @@ -3141,7 +3157,7 @@ void filter_is_base(struct repository *r, const char *name = array->items[i]->refname; struct commit *c = lookup_commit_reference_by_name_gently(name, 1); - CALLOC_ARRAY(array->items[i]->is_base, format->is_base_tips.nr); + CALLOC_ARRAY(array->items[i]->is_base, is_base_nr); if (!c) continue; @@ -3151,15 +3167,20 @@ void filter_is_base(struct repository *r, bases_nr++; } - for (size_t i = 0; i < format->is_base_tips.nr; i++) { - struct commit *tip = format->is_base_tips.items[i].util; - int base_index = get_branch_base_for_tip(r, tip, bases, bases_nr); + for (size_t i = 0, j = 0; i < used_atom_cnt; i++) { + struct commit *tip; + int base_index; + + if (used_atom[i].atom_type != ATOM_ISBASE) + continue; + tip = used_atom[i].u.base.commit; + base_index = get_branch_base_for_tip(r, tip, bases, bases_nr); if (base_index < 0) continue; /* Store the string for use in output later. */ - back_index[base_index]->is_base[i] = xstrdup(format->is_base_tips.items[i].string); + back_index[base_index]->is_base[j++] = xstrdup(used_atom[i].u.base.name); } free(back_index); @@ -3244,30 +3265,51 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int return ret; } +struct ref_sorting { + struct ref_sorting *next; + int atom; /* index into used_atom array (internal) */ + enum ref_sorting_order sort_flags; +}; + static inline int can_do_iterative_format(struct ref_filter *filter, - struct ref_sorting *sorting, - struct ref_format *format) + struct ref_sorting *sorting) { + /* + * Reference backends sort patterns lexicographically by refname, so if + * the sorting options ask for exactly that we are able to do iterative + * formatting. + * + * Note that we do not have to worry about multiple name patterns, + * either. Those get sorted and deduplicated eventually in + * `refs_for_each_fullref_in_prefixes()`, so we return names in the + * correct ordering here, too. + */ + if (sorting && (sorting->next || + sorting->sort_flags || + used_atom[sorting->atom].atom_type != ATOM_REFNAME)) + return 0; + /* * 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 || - format->is_base_tips.nr); + for (size_t i = 0; i < used_atom_cnt; i++) { + if (used_atom[i].atom_type == ATOM_AHEADBEHIND) + return 0; + if (used_atom[i].atom_type == ATOM_ISBASE) + return 0; + } + return !(filter->reachable_from || filter->unreachable_from); } 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)) { + if (can_do_iterative_format(filter, sorting)) { int save_commit_buffer_orig; struct ref_filter_and_format_cbdata ref_cbdata = { .filter = filter, @@ -3283,8 +3325,8 @@ void filter_and_format_refs(struct ref_filter *filter, unsigned int type, } else { struct ref_array array = { 0 }; filter_refs(&array, filter, type); - filter_ahead_behind(the_repository, format, &array); - filter_is_base(the_repository, format, &array); + filter_ahead_behind(the_repository, &array); + filter_is_base(the_repository, &array); ref_array_sort(sorting, &array); print_formatted_ref_array(&array, format); ref_array_clear(&array); @@ -3316,12 +3358,6 @@ static int memcasecmp(const void *vs1, const void *vs2, size_t n) return 0; } -struct ref_sorting { - struct ref_sorting *next; - int atom; /* index into used_atom array (internal) */ - enum ref_sorting_order sort_flags; -}; - static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b) { struct atom_value *va, *vb; @@ -3624,16 +3660,3 @@ void ref_filter_clear(struct ref_filter *filter) free_commit_list(filter->unreachable_from); ref_filter_init(filter); } - -void ref_format_init(struct ref_format *format) -{ - struct ref_format blank = REF_FORMAT_INIT; - memcpy(format, &blank, sizeof(blank)); -} - -void ref_format_clear(struct ref_format *format) -{ - string_list_clear(&format->bases, 0); - string_list_clear(&format->is_base_tips, 0); - ref_format_init(format); -} diff --git a/ref-filter.h b/ref-filter.h index 754038ab078669..013d4cfa64b310 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -99,12 +99,6 @@ struct ref_format { /* Internal state to ref-filter */ int need_color_reset_at_eol; - /* List of bases for ahead-behind counts. */ - struct string_list bases; - - /* List of bases for is-base indicators. */ - struct string_list is_base_tips; - struct { int max_count; int omit_empty; @@ -117,8 +111,6 @@ struct ref_format { } #define REF_FORMAT_INIT { \ .use_color = -1, \ - .bases = STRING_LIST_INIT_DUP, \ - .is_base_tips = STRING_LIST_INIT_DUP, \ } /* Macros for checking --merged and --no-merged options */ @@ -205,7 +197,6 @@ struct ref_array_item *ref_array_push(struct ref_array *array, * If this is not called, then any ahead-behind atoms will be blank. */ void filter_ahead_behind(struct repository *r, - struct ref_format *format, struct ref_array *array); /* @@ -215,13 +206,9 @@ void filter_ahead_behind(struct repository *r, * If this is not called, then any is-base atoms will be blank. */ void filter_is_base(struct repository *r, - struct ref_format *format, struct ref_array *array); void ref_filter_init(struct ref_filter *filter); void ref_filter_clear(struct ref_filter *filter); -void ref_format_init(struct ref_format *format); -void ref_format_clear(struct ref_format *format); - #endif /* REF_FILTER_H */ diff --git a/reflog.c b/reflog.c index 875ac1aa6620d2..1b5f031f6d787f 100644 --- a/reflog.c +++ b/reflog.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" @@ -210,7 +211,7 @@ static void mark_reachable(struct expire_reflog_policy_cb *cb) cb->mark_list = leftover; } -static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, struct object_id *oid) +static int is_unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, struct object_id *oid) { /* * We may or may not have the commit yet - if not, look it @@ -265,7 +266,7 @@ int should_expire_reflog_ent(struct object_id *ooid, struct object_id *noid, return 1; case UE_NORMAL: case UE_HEAD: - if (unreachable(cb, old_commit, ooid) || unreachable(cb, new_commit, noid)) + if (is_unreachable(cb, old_commit, ooid) || is_unreachable(cb, new_commit, noid)) return 1; break; } diff --git a/refs.c b/refs.c index 5f729ed4124f7f..118465271d7275 100644 --- a/refs.c +++ b/refs.c @@ -3,6 +3,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "advice.h" @@ -30,6 +31,7 @@ #include "date.h" #include "commit.h" #include "wildmatch.h" +#include "ident.h" /* * List of all available backends @@ -318,9 +320,10 @@ int check_refname_format(const char *refname, int flags) return check_or_sanitize_refname(refname, flags, NULL); } -int refs_fsck(struct ref_store *refs, struct fsck_options *o) +int refs_fsck(struct ref_store *refs, struct fsck_options *o, + struct worktree *wt) { - return refs->be->fsck(refs, o); + return refs->be->fsck(refs, o, wt); } void sanitize_refname_component(const char *refname, struct strbuf *out) @@ -697,6 +700,53 @@ static char *substitute_branch_name(struct repository *r, return NULL; } +void copy_branchname(struct strbuf *sb, const char *name, unsigned allowed) +{ + int len = strlen(name); + struct interpret_branch_name_options options = { + .allowed = allowed + }; + int used = repo_interpret_branch_name(the_repository, name, len, sb, + &options); + + if (used < 0) + used = 0; + strbuf_add(sb, name + used, len - used); +} + +int check_branch_ref(struct strbuf *sb, const char *name) +{ + if (startup_info->have_repository) + copy_branchname(sb, name, INTERPRET_BRANCH_LOCAL); + else + strbuf_addstr(sb, name); + + /* + * This splice must be done even if we end up rejecting the + * name; builtin/branch.c::copy_or_rename_branch() still wants + * to see what the name expanded to so that "branch -m" can be + * used as a tool to correct earlier mistakes. + */ + strbuf_splice(sb, 0, 0, "refs/heads/", 11); + + if (*name == '-' || + !strcmp(sb->buf, "refs/heads/HEAD")) + return -1; + + return check_refname_format(sb->buf, 0); +} + +int check_tag_ref(struct strbuf *sb, const char *name) +{ + if (name[0] == '-' || !strcmp(name, "HEAD")) + return -1; + + strbuf_reset(sb); + strbuf_addf(sb, "refs/tags/%s", name); + + return check_refname_format(sb->buf, 0); +} + int repo_dwim_ref(struct repository *r, const char *str, int len, struct object_id *oid, char **ref, int nonfatal_dangling_mark) { @@ -918,7 +968,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg, struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; - transaction = ref_store_transaction_begin(refs, &err); + transaction = ref_store_transaction_begin(refs, 0, &err); if (!transaction || ref_transaction_delete(transaction, refname, old_oid, NULL, flags, msg, &err) || @@ -1116,6 +1166,7 @@ int read_ref_at(struct ref_store *refs, const char *refname, } struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, + unsigned int flags, struct strbuf *err) { struct ref_transaction *tr; @@ -1123,6 +1174,7 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, CALLOC_ARRAY(tr, 1); tr->ref_store = refs; + tr->flags = flags; return tr; } @@ -1148,6 +1200,7 @@ void ref_transaction_free(struct ref_transaction *transaction) for (i = 0; i < transaction->nr; i++) { free(transaction->updates[i]->msg); + free(transaction->updates[i]->committer_info); free((char *)transaction->updates[i]->new_target); free((char *)transaction->updates[i]->old_target); free(transaction->updates[i]); @@ -1162,6 +1215,7 @@ struct ref_update *ref_transaction_add_update( const struct object_id *new_oid, const struct object_id *old_oid, const char *new_target, const char *old_target, + const char *committer_info, const char *msg) { struct ref_update *update; @@ -1186,11 +1240,44 @@ struct ref_update *ref_transaction_add_update( oidcpy(&update->new_oid, new_oid); if ((flags & REF_HAVE_OLD) && old_oid) oidcpy(&update->old_oid, old_oid); + if (!(flags & REF_SKIP_CREATE_REFLOG)) { + update->committer_info = xstrdup_or_null(committer_info); + update->msg = normalize_reflog_message(msg); + } - update->msg = normalize_reflog_message(msg); return update; } +static int transaction_refname_valid(const char *refname, + const struct object_id *new_oid, + unsigned int flags, struct strbuf *err) +{ + if (flags & REF_SKIP_REFNAME_VERIFICATION) + return 1; + + if (is_pseudo_ref(refname)) { + const char *refusal_msg; + if (flags & REF_LOG_ONLY) + refusal_msg = _("refusing to update reflog for pseudoref '%s'"); + else + refusal_msg = _("refusing to update pseudoref '%s'"); + strbuf_addf(err, refusal_msg, refname); + return 0; + } else if ((new_oid && !is_null_oid(new_oid)) ? + check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) : + !refname_is_safe(refname)) { + const char *refusal_msg; + if (flags & REF_LOG_ONLY) + refusal_msg = _("refusing to update reflog with bad name '%s'"); + else + refusal_msg = _("refusing to update ref with bad name '%s'"); + strbuf_addf(err, refusal_msg, refname); + return 0; + } + + return 1; +} + int ref_transaction_update(struct ref_transaction *transaction, const char *refname, const struct object_id *new_oid, @@ -1208,21 +1295,8 @@ int ref_transaction_update(struct ref_transaction *transaction, return -1; } - if (!(flags & REF_SKIP_REFNAME_VERIFICATION) && - ((new_oid && !is_null_oid(new_oid)) ? - check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) : - !refname_is_safe(refname))) { - strbuf_addf(err, _("refusing to update ref with bad name '%s'"), - refname); + if (!transaction_refname_valid(refname, new_oid, flags, err)) return -1; - } - - if (!(flags & REF_SKIP_REFNAME_VERIFICATION) && - is_pseudo_ref(refname)) { - strbuf_addf(err, _("refusing to update pseudoref '%s'"), - refname); - return -1; - } if (flags & ~REF_TRANSACTION_UPDATE_ALLOWED_FLAGS) BUG("illegal flags 0x%x passed to ref_transaction_update()", flags); @@ -1239,7 +1313,53 @@ int ref_transaction_update(struct ref_transaction *transaction, ref_transaction_add_update(transaction, refname, flags, new_oid, old_oid, new_target, - old_target, msg); + old_target, NULL, msg); + + return 0; +} + +/* + * Similar to`ref_transaction_update`, but this function is only for adding + * a reflog update. Supports providing custom committer information. The index + * field can be utiltized to order updates as desired. When not used, the + * updates default to being ordered by refname. + */ +static int ref_transaction_update_reflog(struct ref_transaction *transaction, + const char *refname, + const struct object_id *new_oid, + const struct object_id *old_oid, + const char *committer_info, + unsigned int flags, + const char *msg, + uint64_t index, + struct strbuf *err) +{ + struct ref_update *update; + + assert(err); + + flags |= REF_LOG_ONLY | REF_FORCE_CREATE_REFLOG | REF_NO_DEREF; + + if (!transaction_refname_valid(refname, new_oid, flags, err)) + return -1; + + update = ref_transaction_add_update(transaction, refname, flags, + new_oid, old_oid, NULL, NULL, + committer_info, msg); + /* + * While we do set the old_oid value, we unset the flag to skip + * old_oid verification which only makes sense for refs. + */ + update->flags &= ~REF_HAVE_OLD; + update->index = index; + + /* + * Reference backends may need to know the max index to optimize + * their writes. So we store the max_index on the transaction level. + */ + if (index > transaction->max_index) + transaction->max_index = index; + return 0; } @@ -1309,7 +1429,7 @@ int refs_update_ref(struct ref_store *refs, const char *msg, struct strbuf err = STRBUF_INIT; int ret = 0; - t = ref_store_transaction_begin(refs, &err); + t = ref_store_transaction_begin(refs, 0, &err); if (!t || ref_transaction_update(t, refname, new_oid, old_oid, NULL, NULL, flags, msg, &err) || @@ -1788,7 +1908,7 @@ static int refs_read_special_head(struct ref_store *ref_store, } result = parse_loose_ref_contents(ref_store->repo->hash_algo, content.buf, - oid, referent, type, failure_errno); + oid, referent, type, NULL, failure_errno); done: strbuf_release(&full_path); @@ -2034,7 +2154,7 @@ struct ref_store *repo_get_submodule_ref_store(struct repository *repo, if (!is_nonbare_repository_dir(&submodule_sb)) goto done; - if (submodule_to_gitdir(&submodule_sb, submodule)) + if (submodule_to_gitdir(repo, &submodule_sb, submodule)) goto done; subrepo = xmalloc(sizeof(*subrepo)); @@ -2072,8 +2192,8 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt) if (wt->id) { struct strbuf common_path = STRBUF_INIT; - strbuf_git_common_path(&common_path, wt->repo, - "worktrees/%s", wt->id); + repo_common_path_append(wt->repo, &common_path, + "worktrees/%s", wt->id); refs = ref_store_init(wt->repo, wt->repo->ref_storage_format, common_path.buf, REF_STORE_ALL_CAPS); strbuf_release(&common_path); @@ -2115,20 +2235,54 @@ int peel_iterated_oid(struct repository *r, const struct object_id *base, struct int refs_update_symref(struct ref_store *refs, const char *ref, const char *target, const char *logmsg) +{ + return refs_update_symref_extended(refs, ref, target, logmsg, NULL, 0); +} + +int refs_update_symref_extended(struct ref_store *refs, const char *ref, + const char *target, const char *logmsg, + struct strbuf *referent, int create_only) { struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; - int ret = 0; + int ret = 0, prepret = 0; - transaction = ref_store_transaction_begin(refs, &err); - if (!transaction || - ref_transaction_update(transaction, ref, NULL, NULL, - target, NULL, REF_NO_DEREF, - logmsg, &err) || - ref_transaction_commit(transaction, &err)) { + transaction = ref_store_transaction_begin(refs, 0, &err); + if (!transaction) { + error_return: ret = error("%s", err.buf); + goto cleanup; } + if (create_only) { + if (ref_transaction_create(transaction, ref, NULL, target, + REF_NO_DEREF, logmsg, &err)) + goto error_return; + prepret = ref_transaction_prepare(transaction, &err); + if (prepret && prepret != TRANSACTION_CREATE_EXISTS) + goto error_return; + } else { + if (ref_transaction_update(transaction, ref, NULL, NULL, + target, NULL, REF_NO_DEREF, + logmsg, &err) || + ref_transaction_prepare(transaction, &err)) + goto error_return; + } + + if (referent && refs_read_symbolic_ref(refs, ref, referent) == NOT_A_SYMREF) { + struct object_id oid; + if (!refs_read_ref(refs, ref, &oid)) { + strbuf_addstr(referent, oid_to_hex(&oid)); + ret = NOT_A_SYMREF; + } + } + + if (prepret == TRANSACTION_CREATE_EXISTS) + goto cleanup; + if (ref_transaction_commit(transaction, &err)) + goto error_return; + +cleanup: strbuf_release(&err); if (transaction) ref_transaction_free(transaction); @@ -2185,6 +2339,9 @@ static int run_transaction_hook(struct ref_transaction *transaction, for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; + if (update->flags & REF_LOG_ONLY) + continue; + strbuf_reset(&buf); if (!(update->flags & REF_HAVE_OLD)) @@ -2313,7 +2470,7 @@ int ref_transaction_commit(struct ref_transaction *transaction, } ret = refs->be->transaction_finish(refs, transaction, err); - if (!ret) + if (!ret && !(transaction->flags & REF_TRANSACTION_FLAG_INITIAL)) run_transaction_hook(transaction, "committed"); return ret; } @@ -2322,6 +2479,7 @@ int refs_verify_refname_available(struct ref_store *refs, const char *refname, const struct string_list *extras, const struct string_list *skip, + unsigned int initial_transaction, struct strbuf *err) { const char *slash; @@ -2330,8 +2488,6 @@ int refs_verify_refname_available(struct ref_store *refs, struct strbuf referent = STRBUF_INIT; struct object_id oid; unsigned int type; - struct ref_iterator *iter; - int ok; int ret = -1; /* @@ -2361,7 +2517,8 @@ int refs_verify_refname_available(struct ref_store *refs, if (skip && string_list_has_string(skip, dirname.buf)) continue; - if (!refs_read_raw_ref(refs, dirname.buf, &oid, &referent, + if (!initial_transaction && + !refs_read_raw_ref(refs, dirname.buf, &oid, &referent, &type, &ignore_errno)) { strbuf_addf(err, _("'%s' exists; cannot create '%s'"), dirname.buf, refname); @@ -2386,21 +2543,26 @@ int refs_verify_refname_available(struct ref_store *refs, strbuf_addstr(&dirname, refname + dirname.len); strbuf_addch(&dirname, '/'); - iter = refs_ref_iterator_begin(refs, dirname.buf, NULL, 0, - DO_FOR_EACH_INCLUDE_BROKEN); - while ((ok = ref_iterator_advance(iter)) == ITER_OK) { - if (skip && - string_list_has_string(skip, iter->refname)) - continue; + if (!initial_transaction) { + struct ref_iterator *iter; + int ok; - strbuf_addf(err, _("'%s' exists; cannot create '%s'"), - iter->refname, refname); - ref_iterator_abort(iter); - goto cleanup; - } + iter = refs_ref_iterator_begin(refs, dirname.buf, NULL, 0, + DO_FOR_EACH_INCLUDE_BROKEN); + while ((ok = ref_iterator_advance(iter)) == ITER_OK) { + if (skip && + string_list_has_string(skip, iter->refname)) + continue; + + strbuf_addf(err, _("'%s' exists; cannot create '%s'"), + iter->refname, refname); + ref_iterator_abort(iter); + goto cleanup; + } - if (ok != ITER_DONE) - BUG("error while iterating over references"); + if (ok != ITER_DONE) + BUG("error while iterating over references"); + } extra_refname = find_descendant_ref(dirname.buf, extras, skip); if (extra_refname) @@ -2484,14 +2646,6 @@ int refs_reflog_expire(struct ref_store *refs, cleanup_fn, policy_cb_data); } -int initial_ref_transaction_commit(struct ref_transaction *transaction, - struct strbuf *err) -{ - struct ref_store *refs = transaction->ref_store; - - return refs->be->initial_transaction_commit(refs, transaction, err); -} - void ref_transaction_for_each_queued_update(struct ref_transaction *transaction, ref_transaction_for_each_queued_update_fn cb, void *cb_data) @@ -2527,7 +2681,7 @@ int refs_delete_refs(struct ref_store *refs, const char *logmsg, * individual updates can't fail, so we can pack all of the * updates into a single transaction. */ - transaction = ref_store_transaction_begin(refs, &err); + transaction = ref_store_transaction_begin(refs, 0, &err); if (!transaction) { ret = error("%s", err.buf); goto out; @@ -2625,6 +2779,7 @@ struct migration_data { struct ref_store *old_refs; struct ref_transaction *transaction; struct strbuf *errbuf; + struct strbuf sb; }; static int migrate_one_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, @@ -2657,6 +2812,52 @@ static int migrate_one_ref(const char *refname, const char *referent UNUSED, con return ret; } +struct reflog_migration_data { + uint64_t index; + const char *refname; + struct ref_store *old_refs; + struct ref_transaction *transaction; + struct strbuf *errbuf; + struct strbuf *sb; +}; + +static int migrate_one_reflog_entry(struct object_id *old_oid, + struct object_id *new_oid, + const char *committer, + timestamp_t timestamp, int tz, + const char *msg, void *cb_data) +{ + struct reflog_migration_data *data = cb_data; + const char *date; + int ret; + + date = show_date(timestamp, tz, DATE_MODE(NORMAL)); + strbuf_reset(data->sb); + /* committer contains name and email */ + strbuf_addstr(data->sb, fmt_ident("", committer, WANT_BLANK_IDENT, date, 0)); + + ret = ref_transaction_update_reflog(data->transaction, data->refname, + new_oid, old_oid, data->sb->buf, + REF_HAVE_NEW | REF_HAVE_OLD, msg, + data->index++, data->errbuf); + return ret; +} + +static int migrate_one_reflog(const char *refname, void *cb_data) +{ + struct migration_data *migration_data = cb_data; + struct reflog_migration_data data = { + .refname = refname, + .old_refs = migration_data->old_refs, + .transaction = migration_data->transaction, + .errbuf = migration_data->errbuf, + .sb = &migration_data->sb, + }; + + return refs_for_each_reflog_ent(migration_data->old_refs, refname, + migrate_one_reflog_entry, &data); +} + static int move_files(const char *from_path, const char *to_path, struct strbuf *errbuf) { struct strbuf from_buf = STRBUF_INIT, to_buf = STRBUF_INIT; @@ -2723,13 +2924,6 @@ static int move_files(const char *from_path, const char *to_path, struct strbuf return ret; } -static int count_reflogs(const char *reflog UNUSED, void *payload) -{ - size_t *reflog_count = payload; - (*reflog_count)++; - return 0; -} - static int has_worktrees(void) { struct worktree **worktrees = get_worktrees(); @@ -2754,8 +2948,9 @@ int repo_migrate_ref_storage_format(struct repository *repo, struct ref_store *old_refs = NULL, *new_refs = NULL; struct ref_transaction *transaction = NULL; struct strbuf new_gitdir = STRBUF_INIT; - struct migration_data data; - size_t reflog_count = 0; + struct migration_data data = { + .sb = STRBUF_INIT, + }; int did_migrate_refs = 0; int ret; @@ -2767,21 +2962,6 @@ int repo_migrate_ref_storage_format(struct repository *repo, old_refs = get_main_ref_store(repo); - /* - * We do not have any interfaces that would allow us to write many - * reflog entries. Once we have them we can remove this restriction. - */ - if (refs_for_each_reflog(old_refs, count_reflogs, &reflog_count) < 0) { - strbuf_addstr(errbuf, "cannot count reflogs"); - ret = -1; - goto done; - } - if (reflog_count) { - strbuf_addstr(errbuf, "migrating reflogs is not supported yet"); - ret = -1; - goto done; - } - /* * Worktrees complicate the migration because every worktree has a * separate ref storage. While it should be feasible to implement, this @@ -2807,17 +2987,21 @@ int repo_migrate_ref_storage_format(struct repository *repo, * This operation is safe as we do not yet modify the main * repository. * - * 3. If we're in dry-run mode then we are done and can hand over the + * 3. Enumerate all reflogs and write them into the new ref storage. + * This operation is safe as we do not yet modify the main + * repository. + * + * 4. If we're in dry-run mode then we are done and can hand over the * directory to the caller for inspection. If not, we now start * with the destructive part. * - * 4. Delete the old ref storage from disk. As we have a copy of refs + * 5. Delete the old ref storage from disk. As we have a copy of refs * in the new ref storage it's okay(ish) if we now get interrupted * as there is an equivalent copy of all refs available. * - * 5. Move the new ref storage files into place. + * 6. Move the new ref storage files into place. * - * 6. Change the repository format to the new ref format. + * 7. Change the repository format to the new ref format. */ strbuf_addf(&new_gitdir, "%s/%s", old_refs->gitdir, "ref_migration.XXXXXX"); if (!mkdtemp(new_gitdir.buf)) { @@ -2833,7 +3017,8 @@ int repo_migrate_ref_storage_format(struct repository *repo, if (ret < 0) goto done; - transaction = ref_store_transaction_begin(new_refs, errbuf); + transaction = ref_store_transaction_begin(new_refs, REF_TRANSACTION_FLAG_INITIAL, + errbuf); if (!transaction) goto done; @@ -2858,13 +3043,12 @@ int repo_migrate_ref_storage_format(struct repository *repo, if (ret < 0) goto done; - /* - * TODO: we might want to migrate to `initial_ref_transaction_commit()` - * here, which is more efficient for the files backend because it would - * write new refs into the packed-refs file directly. At this point, - * the files backend doesn't handle pseudo-refs and symrefs correctly - * though, so this requires some more work. - */ + if (!(flags & REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG)) { + ret = refs_for_each_reflog(old_refs, migrate_one_reflog, &data); + if (ret < 0) + goto done; + } + ret = ref_transaction_commit(transaction, errbuf); if (ret < 0) goto done; @@ -2940,6 +3124,7 @@ int repo_migrate_ref_storage_format(struct repository *repo, } ref_transaction_free(transaction); strbuf_release(&new_gitdir); + strbuf_release(&data.sb); return ret; } @@ -2948,4 +3133,3 @@ int ref_update_expects_existing_old_ref(struct ref_update *update) return (update->flags & REF_HAVE_OLD) && (!is_null_oid(&update->old_oid) || update->old_target); } - diff --git a/refs.h b/refs.h index 108dfc93b3428d..8442e89883a6ce 100644 --- a/refs.h +++ b/refs.h @@ -83,6 +83,17 @@ int refs_read_ref_full(struct ref_store *refs, const char *refname, int refs_read_ref(struct ref_store *refs, const char *refname, struct object_id *oid); +#define NOT_A_SYMREF -2 + +/* + * Read the symbolic ref named "refname" and write its immediate referent into + * the provided buffer. Referent is left empty if "refname" is not a symbolic + * ref. It does not resolve the symbolic reference recursively in case the + * target is also a symbolic ref. + * + * Returns 0 on success, -2 if the "refname" is not a symbolic ref, + * -1 otherwise. + */ int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname, struct strbuf *referent); @@ -101,13 +112,16 @@ int refs_read_symbolic_ref(struct ref_store *ref_store, const char *refname, * both "foo" and with "foo/bar/baz" but not with "foo/bar" or * "foo/barbados". * + * If `initial_transaction` is truish, then all collision checks with + * preexisting refs are skipped. + * * extras and skip must be sorted. */ - int refs_verify_refname_available(struct ref_store *refs, const char *refname, const struct string_list *extras, const struct string_list *skip, + unsigned int initial_transaction, struct strbuf *err); int refs_ref_exists(struct ref_store *refs, const char *refname); @@ -180,6 +194,35 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ */ char *repo_default_branch_name(struct repository *r, int quiet); +/* + * Copy "name" to "sb", expanding any special @-marks as handled by + * repo_interpret_branch_name(). The result is a non-qualified branch name + * (so "foo" or "origin/master" instead of "refs/heads/foo" or + * "refs/remotes/origin/master"). + * + * Note that the resulting name may not be a syntactically valid refname. + * + * If "allowed" is non-zero, restrict the set of allowed expansions. See + * repo_interpret_branch_name() for details. + */ +void copy_branchname(struct strbuf *sb, const char *name, + unsigned allowed); + +/* + * Like copy_branchname() above, but confirm that the result is + * syntactically valid to be used as a local branch name in refs/heads/. + * + * The return value is "0" if the result is valid, and "-1" otherwise. + */ +int check_branch_ref(struct strbuf *sb, const char *name); + +/* + * Similar for a tag name in refs/tags/. + * + * The return value is "0" if the result is valid, and "-1" otherwise. + */ +int check_tag_ref(struct strbuf *sb, const char *name); + /* * A ref_transaction represents a collection of reference updates that * should succeed or fail together. @@ -214,11 +257,9 @@ char *repo_default_branch_name(struct repository *r, int quiet); * * Or * - * - Call `initial_ref_transaction_commit()` if the ref database is - * known to be empty and have no other writers (e.g. during - * clone). This is likely to be much faster than - * `ref_transaction_commit()`. `ref_transaction_prepare()` should - * *not* be called before `initial_ref_transaction_commit()`. + * - Call `ref_transaction_begin()` with REF_TRANSACTION_FLAG_INITIAL if the + * ref database is known to be empty and have no other writers (e.g. during + * clone). This is likely to be much faster than without the flag. * * - Then finally, call `ref_transaction_free()` to free the * `ref_transaction` data structure. @@ -234,7 +275,7 @@ char *repo_default_branch_name(struct repository *r, int quiet); * struct strbuf err = STRBUF_INIT; * int ret = 0; * - * transaction = ref_store_transaction_begin(refs, &err); + * transaction = ref_store_transaction_begin(refs, 0, &err); * if (!transaction || * ref_transaction_update(...) || * ref_transaction_create(...) || @@ -536,7 +577,7 @@ int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_dat /* * Return 0 iff refname has the correct format for a refname according - * to the rules described in Documentation/git-check-ref-format.txt. + * to the rules described in Documentation/git-check-ref-format.adoc. * If REFNAME_ALLOW_ONELEVEL is set in flags, then accept one-level * reference names. If REFNAME_REFSPEC_PATTERN is set in flags, then * allow a single "*" wildcard character in the refspec. No leading or @@ -549,7 +590,8 @@ int check_refname_format(const char *refname, int flags); * reflogs are consistent, and non-zero otherwise. The errors will be * written to stderr. */ -int refs_fsck(struct ref_store *refs, struct fsck_options *o); +int refs_fsck(struct ref_store *refs, struct fsck_options *o, + struct worktree *wt); /* * Apply the rules from check_refname_format, but mutate the result until it @@ -573,17 +615,37 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref, int refs_update_symref(struct ref_store *refs, const char *refname, const char *target, const char *logmsg); +int refs_update_symref_extended(struct ref_store *refs, const char *refname, + const char *target, const char *logmsg, + struct strbuf *referent, int create_only); + enum action_on_err { UPDATE_REFS_MSG_ON_ERR, UPDATE_REFS_DIE_ON_ERR, UPDATE_REFS_QUIET_ON_ERR }; +enum ref_transaction_flag { + /* + * The ref transaction is part of the initial creation of the ref store + * and can thus assume that the ref store is completely empty. This + * allows the backend to perform the transaction more efficiently by + * skipping certain checks. + * + * It is a bug to set this flag when there might be other processes + * accessing the repository or if there are existing references that + * might conflict with the ones being created. All old_oid values must + * either be absent or null_oid. + */ + REF_TRANSACTION_FLAG_INITIAL = (1 << 0), +}; + /* * Begin a reference transaction. The reference transaction must * be freed by calling ref_transaction_free(). */ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, + unsigned int flags, struct strbuf *err); /* @@ -758,8 +820,10 @@ int ref_transaction_verify(struct ref_transaction *transaction, /* Naming conflict (for example, the ref names A and A/B conflict). */ #define TRANSACTION_NAME_CONFLICT -1 +/* When only creation was requested, but the ref already exists. */ +#define TRANSACTION_CREATE_EXISTS -2 /* All other errors. */ -#define TRANSACTION_GENERIC_ERROR -2 +#define TRANSACTION_GENERIC_ERROR -3 /* * Perform the preparatory stages of committing `transaction`. Acquire @@ -797,20 +861,6 @@ int ref_transaction_commit(struct ref_transaction *transaction, int ref_transaction_abort(struct ref_transaction *transaction, struct strbuf *err); -/* - * Like ref_transaction_commit(), but optimized for creating - * references when originally initializing a repository (e.g., by "git - * clone"). It writes the new references directly to packed-refs - * without locking the individual references. - * - * It is a bug to call this function when there might be other - * processes accessing the repository or if there are existing - * references that might conflict with the ones being created. All - * old_oid values must either be absent or null_oid. - */ -int initial_ref_transaction_commit(struct ref_transaction *transaction, - struct strbuf *err); - /* * Execute the given callback function for each of the reference updates which * have been queued in the given transaction. `old_oid` and `new_oid` may be @@ -1093,8 +1143,11 @@ int is_pseudo_ref(const char *refname); * - REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN: perform a dry-run migration * without touching the main repository. The result will be written into a * temporary ref storage directory. + * + * - REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG: skip migration of reflogs. */ -#define REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN (1 << 0) +#define REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN (1 << 0) +#define REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG (1 << 1) /* * Migrate the ref storage format used by the repository to the diff --git a/refs/debug.c b/refs/debug.c index 45e2e784a0f8c4..fbc4df08b43ca7 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -83,9 +83,8 @@ static void print_update(int i, const char *refname, static void print_transaction(struct ref_transaction *transaction) { - int i; trace_printf_key(&trace_refs, "transaction {\n"); - for (i = 0; i < transaction->nr; i++) { + for (size_t i = 0; i < transaction->nr; i++) { struct ref_update *u = transaction->updates[i]; print_update(i, u->refname, &u->old_oid, &u->new_oid, u->flags, u->type, u->msg); @@ -118,18 +117,6 @@ static int debug_transaction_abort(struct ref_store *refs, return res; } -static int debug_initial_transaction_commit(struct ref_store *refs, - struct ref_transaction *transaction, - struct strbuf *err) -{ - struct debug_ref_store *drefs = (struct debug_ref_store *)refs; - int res; - transaction->ref_store = drefs->refs; - res = drefs->refs->be->initial_transaction_commit(drefs->refs, - transaction, err); - return res; -} - static int debug_pack_refs(struct ref_store *ref_store, struct pack_refs_opts *opts) { struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; @@ -420,10 +407,11 @@ static int debug_reflog_expire(struct ref_store *ref_store, const char *refname, } static int debug_fsck(struct ref_store *ref_store, - struct fsck_options *o) + struct fsck_options *o, + struct worktree *wt) { struct debug_ref_store *drefs = (struct debug_ref_store *)ref_store; - int res = drefs->refs->be->fsck(drefs->refs, o); + int res = drefs->refs->be->fsck(drefs->refs, o, wt); trace_printf_key(&trace_refs, "fsck: %d\n", res); return res; } @@ -443,7 +431,6 @@ struct ref_storage_be refs_be_debug = { .transaction_prepare = debug_transaction_prepare, .transaction_finish = debug_transaction_finish, .transaction_abort = debug_transaction_abort, - .initial_transaction_commit = debug_initial_transaction_commit, .pack_refs = debug_pack_refs, .rename_ref = debug_rename_ref, diff --git a/refs/files-backend.c b/refs/files-backend.c index 0824c0b8a94690..6c6e67dc1c48ed 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,6 +1,8 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "../git-compat-util.h" +#include "../abspath.h" #include "../config.h" #include "../copy.h" #include "../environment.h" @@ -23,6 +25,7 @@ #include "../dir.h" #include "../chdir-notify.h" #include "../setup.h" +#include "../worktree.h" #include "../wrapper.h" #include "../write-or-die.h" #include "../revision.h" @@ -69,6 +72,7 @@ struct ref_lock { char *ref_name; struct lock_file lk; struct object_id old_oid; + unsigned int count; /* track users of the lock (ref update + reflog updates) */ }; struct files_ref_store { @@ -568,7 +572,7 @@ static int read_ref_internal(struct ref_store *ref_store, const char *refname, buf = sb_contents.buf; ret = parse_loose_ref_contents(ref_store->repo->hash_algo, buf, - oid, referent, type, &myerr); + oid, referent, type, NULL, &myerr); out: if (ret && !myerr) @@ -596,16 +600,15 @@ static int files_read_symbolic_ref(struct ref_store *ref_store, const char *refn unsigned int type; ret = read_ref_internal(ref_store, refname, &oid, referent, &type, &failure_errno, 1); - if (ret) - return ret; - - return !(type & REF_ISSYMREF); + if (!ret && !(type & REF_ISSYMREF)) + return NOT_A_SYMREF; + return ret; } int parse_loose_ref_contents(const struct git_hash_algo *algop, const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, - int *failure_errno) + const char **trailing, int *failure_errno) { const char *p; if (skip_prefix(buf, "ref:", &buf)) { @@ -627,14 +630,21 @@ int parse_loose_ref_contents(const struct git_hash_algo *algop, *failure_errno = EINVAL; return -1; } + + if (trailing) + *trailing = p; + return 0; } static void unlock_ref(struct ref_lock *lock) { - rollback_lock_file(&lock->lk); - free(lock->ref_name); - free(lock); + lock->count--; + if (!lock->count) { + rollback_lock_file(&lock->lk); + free(lock->ref_name); + free(lock); + } } /* @@ -690,6 +700,7 @@ static int lock_raw_ref(struct files_ref_store *refs, *lock_p = CALLOC_ARRAY(lock, 1); lock->ref_name = xstrdup(refname); + lock->count = 1; files_ref_path(refs, &ref_file, refname); retry: @@ -706,7 +717,7 @@ static int lock_raw_ref(struct files_ref_store *refs, * reason to expect this error to be transitory. */ if (refs_verify_refname_available(&refs->base, refname, - extras, NULL, err)) { + extras, NULL, 0, err)) { if (mustexist) { /* * To the user the relevant error is @@ -813,7 +824,7 @@ static int lock_raw_ref(struct files_ref_store *refs, REMOVE_DIR_EMPTY_ONLY)) { if (refs_verify_refname_available( &refs->base, refname, - extras, NULL, err)) { + extras, NULL, 0, err)) { /* * The error message set by * verify_refname_available() is OK. @@ -850,7 +861,7 @@ static int lock_raw_ref(struct files_ref_store *refs, */ if (refs_verify_refname_available( refs->packed_ref_store, refname, - extras, NULL, err)) { + extras, NULL, 0, err)) { ret = TRANSACTION_NAME_CONFLICT; goto error_return; } @@ -1159,10 +1170,11 @@ static struct ref_lock *lock_ref_oid_basic(struct files_ref_store *refs, */ if (is_null_oid(&lock->old_oid) && refs_verify_refname_available(refs->packed_ref_store, refname, - NULL, NULL, err)) + NULL, NULL, 0, err)) goto error_return; lock->ref_name = xstrdup(refname); + lock->count = 1; if (raceproof_create_file(ref_file.buf, create_reflock, &lock->lk)) { unable_to_lock_message(ref_file.buf, errno, err); @@ -1252,13 +1264,13 @@ static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r) if (check_refname_format(r->name, 0)) return; - transaction = ref_store_transaction_begin(&refs->base, &err); + transaction = ref_store_transaction_begin(&refs->base, 0, &err); if (!transaction) goto cleanup; ref_transaction_add_update( transaction, r->name, REF_NO_DEREF | REF_HAVE_NEW | REF_HAVE_OLD | REF_IS_PRUNING, - null_oid(), &r->oid, NULL, NULL, NULL); + null_oid(), &r->oid, NULL, NULL, NULL, NULL); if (ref_transaction_commit(transaction, &err)) goto cleanup; @@ -1396,7 +1408,8 @@ static int files_pack_refs(struct ref_store *ref_store, if (!should_pack_refs(refs, opts)) return 0; - transaction = ref_store_transaction_begin(refs->packed_ref_store, &err); + transaction = ref_store_transaction_begin(refs->packed_ref_store, + 0, &err); if (!transaction) return -1; @@ -1537,7 +1550,7 @@ static int refs_rename_ref_available(struct ref_store *refs, string_list_insert(&skip, old_refname); ok = !refs_verify_refname_available(refs, new_refname, - NULL, &skip, &err); + NULL, &skip, 0, &err); if (!ok) error("%s", err.buf); @@ -1818,7 +1831,7 @@ static int log_ref_setup(struct files_ref_store *refs, } if (*logfd >= 0) - adjust_shared_perm(logfile); + adjust_shared_perm(the_repository, logfile); free(logfile); return 0; @@ -1851,6 +1864,9 @@ static int log_ref_write_fd(int fd, const struct object_id *old_oid, struct strbuf sb = STRBUF_INIT; int ret = 0; + if (!committer) + committer = git_committer_info(0); + strbuf_addf(&sb, "%s %s %s", oid_to_hex(old_oid), oid_to_hex(new_oid), committer); if (msg && *msg) { strbuf_addch(&sb, '\t'); @@ -1864,8 +1880,10 @@ static int log_ref_write_fd(int fd, const struct object_id *old_oid, } static int files_log_ref_write(struct files_ref_store *refs, - const char *refname, const struct object_id *old_oid, - const struct object_id *new_oid, const char *msg, + const char *refname, + const struct object_id *old_oid, + const struct object_id *new_oid, + const char *committer_info, const char *msg, int flags, struct strbuf *err) { int logfd, result; @@ -1882,8 +1900,7 @@ static int files_log_ref_write(struct files_ref_store *refs, if (logfd < 0) return 0; - result = log_ref_write_fd(logfd, old_oid, new_oid, - git_committer_info(0), msg); + result = log_ref_write_fd(logfd, old_oid, new_oid, committer_info, msg); if (result) { struct strbuf sb = STRBUF_INIT; int save_errno = errno; @@ -1967,8 +1984,7 @@ static int commit_ref_update(struct files_ref_store *refs, files_assert_main_repository(refs, "commit_ref_update"); clear_loose_ref_cache(refs); - if (files_log_ref_write(refs, lock->ref_name, - &lock->old_oid, oid, + if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, oid, NULL, logmsg, flags, err)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "cannot update the ref '%s': %s", @@ -2000,9 +2016,9 @@ static int commit_ref_update(struct files_ref_store *refs, if (head_ref && (head_flag & REF_ISSYMREF) && !strcmp(head_ref, lock->ref_name)) { struct strbuf log_err = STRBUF_INIT; - if (files_log_ref_write(refs, "HEAD", - &lock->old_oid, oid, - logmsg, flags, &log_err)) { + if (files_log_ref_write(refs, "HEAD", &lock->old_oid, + oid, NULL, logmsg, flags, + &log_err)) { error("%s", log_err.buf); strbuf_release(&log_err); } @@ -2401,7 +2417,7 @@ static int split_head_update(struct ref_update *update, transaction, "HEAD", update->flags | REF_LOG_ONLY | REF_NO_DEREF, &update->new_oid, &update->old_oid, - NULL, NULL, update->msg); + NULL, NULL, update->committer_info, update->msg); /* * Add "HEAD". This insertion is O(N) in the transaction @@ -2465,7 +2481,8 @@ static int split_symref_update(struct ref_update *update, transaction, referent, new_flags, update->new_target ? NULL : &update->new_oid, update->old_target ? NULL : &update->old_oid, - update->new_target, update->old_target, update->msg); + update->new_target, update->old_target, NULL, + update->msg); new_update->parent_update = update; @@ -2502,14 +2519,18 @@ static int split_symref_update(struct ref_update *update, static int check_old_oid(struct ref_update *update, struct object_id *oid, struct strbuf *err) { + int ret = TRANSACTION_GENERIC_ERROR; + if (!(update->flags & REF_HAVE_OLD) || oideq(oid, &update->old_oid)) return 0; - if (is_null_oid(&update->old_oid)) + if (is_null_oid(&update->old_oid)) { strbuf_addf(err, "cannot lock ref '%s': " "reference already exists", ref_update_original_update_refname(update)); + ret = TRANSACTION_CREATE_EXISTS; + } else if (is_null_oid(oid)) strbuf_addf(err, "cannot lock ref '%s': " "reference is missing but expected %s", @@ -2522,9 +2543,15 @@ static int check_old_oid(struct ref_update *update, struct object_id *oid, oid_to_hex(oid), oid_to_hex(&update->old_oid)); - return -1; + return ret; } +struct files_transaction_backend_data { + struct ref_transaction *packed_transaction; + int packed_refs_locked; + struct strmap ref_locks; +}; + /* * Prepare for carrying out update: * - Lock the reference referred to by update. @@ -2547,11 +2574,14 @@ static int lock_ref_for_update(struct files_ref_store *refs, { struct strbuf referent = STRBUF_INIT; int mustexist = ref_update_expects_existing_old_ref(update); + struct files_transaction_backend_data *backend_data; int ret = 0; struct ref_lock *lock; files_assert_main_repository(refs, "lock_ref_for_update"); + backend_data = transaction->backend_data; + if ((update->flags & REF_HAVE_NEW) && ref_update_has_null_new_value(update)) update->flags |= REF_DELETING; @@ -2562,18 +2592,25 @@ static int lock_ref_for_update(struct files_ref_store *refs, goto out; } - ret = lock_raw_ref(refs, update->refname, mustexist, - affected_refnames, - &lock, &referent, - &update->type, err); - if (ret) { - char *reason; + lock = strmap_get(&backend_data->ref_locks, update->refname); + if (lock) { + lock->count++; + } else { + ret = lock_raw_ref(refs, update->refname, mustexist, + affected_refnames, + &lock, &referent, + &update->type, err); + if (ret) { + char *reason; + + reason = strbuf_detach(err, NULL); + strbuf_addf(err, "cannot lock ref '%s': %s", + ref_update_original_update_refname(update), reason); + free(reason); + goto out; + } - reason = strbuf_detach(err, NULL); - strbuf_addf(err, "cannot lock ref '%s': %s", - ref_update_original_update_refname(update), reason); - free(reason); - goto out; + strmap_put(&backend_data->ref_locks, update->refname, lock); } update->backend_data = lock; @@ -2602,9 +2639,11 @@ static int lock_ref_for_update(struct files_ref_store *refs, ret = TRANSACTION_GENERIC_ERROR; goto out; } - } else if (check_old_oid(update, &lock->old_oid, err)) { - ret = TRANSACTION_GENERIC_ERROR; - goto out; + } else { + ret = check_old_oid(update, &lock->old_oid, err); + if (ret) { + goto out; + } } } else { /* @@ -2635,9 +2674,11 @@ static int lock_ref_for_update(struct files_ref_store *refs, update->old_target); ret = TRANSACTION_GENERIC_ERROR; goto out; - } else if (check_old_oid(update, &lock->old_oid, err)) { - ret = TRANSACTION_GENERIC_ERROR; - goto out; + } else { + ret = check_old_oid(update, &lock->old_oid, err); + if (ret) { + goto out; + } } /* @@ -2720,11 +2761,6 @@ static int lock_ref_for_update(struct files_ref_store *refs, return ret; } -struct files_transaction_backend_data { - struct ref_transaction *packed_transaction; - int packed_refs_locked; -}; - /* * Unlock any references in `transaction` that are still locked, and * mark the transaction closed. @@ -2757,6 +2793,8 @@ static void files_transaction_cleanup(struct files_ref_store *refs, if (backend_data->packed_refs_locked) packed_refs_unlock(refs->packed_ref_store); + strmap_clear(&backend_data->ref_locks, 0); + free(backend_data); } @@ -2780,10 +2818,13 @@ static int files_transaction_prepare(struct ref_store *ref_store, assert(err); + if (transaction->flags & REF_TRANSACTION_FLAG_INITIAL) + goto cleanup; if (!transaction->nr) goto cleanup; CALLOC_ARRAY(backend_data, 1); + strmap_init(&backend_data->ref_locks); transaction->backend_data = backend_data; /* @@ -2796,13 +2837,16 @@ static int files_transaction_prepare(struct ref_store *ref_store, */ for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; - struct string_list_item *item = - string_list_append(&affected_refnames, update->refname); + struct string_list_item *item; if ((update->flags & REF_IS_PRUNING) && !(update->flags & REF_NO_DEREF)) BUG("REF_IS_PRUNING set without REF_NO_DEREF"); + if (update->flags & REF_LOG_ONLY) + continue; + + item = string_list_append(&affected_refnames, update->refname); /* * We store a pointer to update in item->util, but at * the moment we never use the value of this field @@ -2867,7 +2911,8 @@ static int files_transaction_prepare(struct ref_store *ref_store, */ if (!packed_transaction) { packed_transaction = ref_store_transaction_begin( - refs->packed_ref_store, err); + refs->packed_ref_store, + transaction->flags, err); if (!packed_transaction) { ret = TRANSACTION_GENERIC_ERROR; goto cleanup; @@ -2881,7 +2926,7 @@ static int files_transaction_prepare(struct ref_store *ref_store, packed_transaction, update->refname, REF_HAVE_NEW | REF_NO_DEREF, &update->new_oid, NULL, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); } } @@ -2959,7 +3004,8 @@ static int parse_and_write_reflog(struct files_ref_store *refs, } if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, - &update->new_oid, update->msg, update->flags, err)) { + &update->new_oid, update->committer_info, + update->msg, update->flags, err)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "cannot update the ref '%s': %s", @@ -2973,6 +3019,137 @@ static int parse_and_write_reflog(struct files_ref_store *refs, return 0; } +static int ref_present(const char *refname, const char *referent UNUSED, + const struct object_id *oid UNUSED, + int flags UNUSED, + void *cb_data) +{ + struct string_list *affected_refnames = cb_data; + + return string_list_has_string(affected_refnames, refname); +} + +static int files_transaction_finish_initial(struct files_ref_store *refs, + struct ref_transaction *transaction, + struct strbuf *err) +{ + size_t i; + int ret = 0; + struct string_list affected_refnames = STRING_LIST_INIT_NODUP; + struct ref_transaction *packed_transaction = NULL; + struct ref_transaction *loose_transaction = NULL; + + assert(err); + + if (transaction->state != REF_TRANSACTION_PREPARED) + BUG("commit called for transaction that is not prepared"); + + /* Fail if a refname appears more than once in the transaction: */ + for (i = 0; i < transaction->nr; i++) + if (!(transaction->updates[i]->flags & REF_LOG_ONLY)) + string_list_append(&affected_refnames, + transaction->updates[i]->refname); + string_list_sort(&affected_refnames); + if (ref_update_reject_duplicates(&affected_refnames, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + + /* + * It's really undefined to call this function in an active + * repository or when there are existing references: we are + * only locking and changing packed-refs, so (1) any + * simultaneous processes might try to change a reference at + * the same time we do, and (2) any existing loose versions of + * the references that we are setting would have precedence + * over our values. But some remote helpers create the remote + * "HEAD" and "master" branches before calling this function, + * so here we really only check that none of the references + * that we are creating already exists. + */ + if (refs_for_each_rawref(&refs->base, ref_present, + &affected_refnames)) + BUG("initial ref transaction called with existing refs"); + + packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, + transaction->flags, err); + if (!packed_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + + for (i = 0; i < transaction->nr; i++) { + struct ref_update *update = transaction->updates[i]; + + if ((update->flags & REF_HAVE_OLD) && + !is_null_oid(&update->old_oid)) + BUG("initial ref transaction with old_sha1 set"); + + if (refs_verify_refname_available(&refs->base, update->refname, + &affected_refnames, NULL, 1, err)) { + ret = TRANSACTION_NAME_CONFLICT; + goto cleanup; + } + + /* + * packed-refs don't support symbolic refs, root refs and reflogs, + * so we have to queue these references via the loose transaction. + */ + if (update->new_target || + is_root_ref(update->refname) || + (update->flags & REF_LOG_ONLY)) { + if (!loose_transaction) { + loose_transaction = ref_store_transaction_begin(&refs->base, 0, err); + if (!loose_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + } + + if (update->flags & REF_LOG_ONLY) + ref_transaction_add_update(loose_transaction, update->refname, + update->flags, &update->new_oid, + &update->old_oid, NULL, NULL, + update->committer_info, update->msg); + else + ref_transaction_add_update(loose_transaction, update->refname, + update->flags & ~REF_HAVE_OLD, + update->new_target ? NULL : &update->new_oid, NULL, + update->new_target, NULL, update->committer_info, + NULL); + } else { + ref_transaction_add_update(packed_transaction, update->refname, + update->flags & ~REF_HAVE_OLD, + &update->new_oid, &update->old_oid, + NULL, NULL, update->committer_info, NULL); + } + } + + if (packed_refs_lock(refs->packed_ref_store, 0, err) || + ref_transaction_commit(packed_transaction, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + packed_refs_unlock(refs->packed_ref_store); + + if (loose_transaction) { + if (ref_transaction_prepare(loose_transaction, err) || + ref_transaction_commit(loose_transaction, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + } + +cleanup: + if (loose_transaction) + ref_transaction_free(loose_transaction); + if (packed_transaction) + ref_transaction_free(packed_transaction); + transaction->state = REF_TRANSACTION_CLOSED; + string_list_clear(&affected_refnames, 0); + return ret; +} + static int files_transaction_finish(struct ref_store *ref_store, struct ref_transaction *transaction, struct strbuf *err) @@ -2988,6 +3165,8 @@ static int files_transaction_finish(struct ref_store *ref_store, assert(err); + if (transaction->flags & REF_TRANSACTION_FLAG_INITIAL) + return files_transaction_finish_initial(refs, transaction, err); if (!transaction->nr) { transaction->state = REF_TRANSACTION_CLOSED; return 0; @@ -3121,106 +3300,6 @@ static int files_transaction_abort(struct ref_store *ref_store, return 0; } -static int ref_present(const char *refname, const char *referent UNUSED, - const struct object_id *oid UNUSED, - int flags UNUSED, - void *cb_data) -{ - struct string_list *affected_refnames = cb_data; - - return string_list_has_string(affected_refnames, refname); -} - -static int files_initial_transaction_commit(struct ref_store *ref_store, - struct ref_transaction *transaction, - struct strbuf *err) -{ - struct files_ref_store *refs = - files_downcast(ref_store, REF_STORE_WRITE, - "initial_ref_transaction_commit"); - size_t i; - int ret = 0; - struct string_list affected_refnames = STRING_LIST_INIT_NODUP; - struct ref_transaction *packed_transaction = NULL; - - assert(err); - - if (transaction->state != REF_TRANSACTION_OPEN) - BUG("commit called for transaction that is not open"); - - /* Fail if a refname appears more than once in the transaction: */ - for (i = 0; i < transaction->nr; i++) - string_list_append(&affected_refnames, - transaction->updates[i]->refname); - string_list_sort(&affected_refnames); - if (ref_update_reject_duplicates(&affected_refnames, err)) { - ret = TRANSACTION_GENERIC_ERROR; - goto cleanup; - } - - /* - * It's really undefined to call this function in an active - * repository or when there are existing references: we are - * only locking and changing packed-refs, so (1) any - * simultaneous processes might try to change a reference at - * the same time we do, and (2) any existing loose versions of - * the references that we are setting would have precedence - * over our values. But some remote helpers create the remote - * "HEAD" and "master" branches before calling this function, - * so here we really only check that none of the references - * that we are creating already exists. - */ - if (refs_for_each_rawref(&refs->base, ref_present, - &affected_refnames)) - BUG("initial ref transaction called with existing refs"); - - packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, err); - if (!packed_transaction) { - ret = TRANSACTION_GENERIC_ERROR; - goto cleanup; - } - - for (i = 0; i < transaction->nr; i++) { - struct ref_update *update = transaction->updates[i]; - - if ((update->flags & REF_HAVE_OLD) && - !is_null_oid(&update->old_oid)) - BUG("initial ref transaction with old_sha1 set"); - if (refs_verify_refname_available(&refs->base, update->refname, - &affected_refnames, NULL, - err)) { - ret = TRANSACTION_NAME_CONFLICT; - goto cleanup; - } - - /* - * Add a reference creation for this reference to the - * packed-refs transaction: - */ - ref_transaction_add_update(packed_transaction, update->refname, - update->flags & ~REF_HAVE_OLD, - &update->new_oid, &update->old_oid, - NULL, NULL, NULL); - } - - if (packed_refs_lock(refs->packed_ref_store, 0, err)) { - ret = TRANSACTION_GENERIC_ERROR; - goto cleanup; - } - - if (initial_ref_transaction_commit(packed_transaction, err)) { - ret = TRANSACTION_GENERIC_ERROR; - } - - packed_refs_unlock(refs->packed_ref_store); -cleanup: - if (packed_transaction) - ref_transaction_free(packed_transaction); - transaction->state = REF_TRANSACTION_CLOSED; - string_list_clear(&affected_refnames, 0); - return ret; -} - struct expire_reflog_cb { reflog_expiry_should_prune_fn *should_prune_fn; void *policy_cb; @@ -3409,8 +3488,8 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store, * they do not understand the reference format extension. */ strbuf_addf(&sb, "%s/refs", ref_store->gitdir); - safe_create_dir(sb.buf, 1); - adjust_shared_perm(sb.buf); + safe_create_dir(the_repository, sb.buf, 1); + adjust_shared_perm(the_repository, sb.buf); /* * There is no need to create directories for common refs when creating @@ -3422,11 +3501,11 @@ static int files_ref_store_create_on_disk(struct ref_store *ref_store, */ strbuf_reset(&sb); files_ref_path(refs, &sb, "refs/heads"); - safe_create_dir(sb.buf, 1); + safe_create_dir(the_repository, sb.buf, 1); strbuf_reset(&sb); files_ref_path(refs, &sb, "refs/tags"); - safe_create_dir(sb.buf, 1); + safe_create_dir(the_repository, sb.buf, 1); } strbuf_release(&sb); @@ -3501,12 +3580,153 @@ static int files_ref_store_remove_on_disk(struct ref_store *ref_store, */ typedef int (*files_fsck_refs_fn)(struct ref_store *ref_store, struct fsck_options *o, - const char *refs_check_dir, + const char *refname, struct dir_iterator *iter); +static int files_fsck_symref_target(struct fsck_options *o, + struct fsck_ref_report *report, + struct strbuf *referent, + unsigned int symbolic_link) +{ + int is_referent_root; + char orig_last_byte; + size_t orig_len; + int ret = 0; + + orig_len = referent->len; + orig_last_byte = referent->buf[orig_len - 1]; + if (!symbolic_link) + strbuf_rtrim(referent); + + is_referent_root = is_root_ref(referent->buf); + if (!is_referent_root && + !starts_with(referent->buf, "refs/") && + !starts_with(referent->buf, "worktrees/")) { + ret = fsck_report_ref(o, report, + FSCK_MSG_SYMREF_TARGET_IS_NOT_A_REF, + "points to non-ref target '%s'", referent->buf); + + } + + if (!is_referent_root && check_refname_format(referent->buf, 0)) { + ret = fsck_report_ref(o, report, + FSCK_MSG_BAD_REFERENT_NAME, + "points to invalid refname '%s'", referent->buf); + goto out; + } + + if (symbolic_link) + goto out; + + if (referent->len == orig_len || + (referent->len < orig_len && orig_last_byte != '\n')) { + ret = fsck_report_ref(o, report, + FSCK_MSG_REF_MISSING_NEWLINE, + "misses LF at the end"); + } + + if (referent->len != orig_len && referent->len != orig_len - 1) { + ret = fsck_report_ref(o, report, + FSCK_MSG_TRAILING_REF_CONTENT, + "has trailing whitespaces or newlines"); + } + +out: + return ret; +} + +static int files_fsck_refs_content(struct ref_store *ref_store, + struct fsck_options *o, + const char *target_name, + struct dir_iterator *iter) +{ + struct strbuf ref_content = STRBUF_INIT; + struct strbuf abs_gitdir = STRBUF_INIT; + struct strbuf referent = STRBUF_INIT; + struct fsck_ref_report report = { 0 }; + const char *trailing = NULL; + unsigned int type = 0; + int failure_errno = 0; + struct object_id oid; + int ret = 0; + + report.path = target_name; + + if (S_ISLNK(iter->st.st_mode)) { + const char *relative_referent_path = NULL; + + ret = fsck_report_ref(o, &report, + FSCK_MSG_SYMLINK_REF, + "use deprecated symbolic link for symref"); + + strbuf_add_absolute_path(&abs_gitdir, ref_store->repo->gitdir); + strbuf_normalize_path(&abs_gitdir); + if (!is_dir_sep(abs_gitdir.buf[abs_gitdir.len - 1])) + strbuf_addch(&abs_gitdir, '/'); + + strbuf_add_real_path(&ref_content, iter->path.buf); + skip_prefix(ref_content.buf, abs_gitdir.buf, + &relative_referent_path); + + if (relative_referent_path) + strbuf_addstr(&referent, relative_referent_path); + else + strbuf_addbuf(&referent, &ref_content); + + ret |= files_fsck_symref_target(o, &report, &referent, 1); + goto cleanup; + } + + if (strbuf_read_file(&ref_content, iter->path.buf, 0) < 0) { + /* + * Ref file could be removed by another concurrent process. We should + * ignore this error and continue to the next ref. + */ + if (errno == ENOENT) + goto cleanup; + + ret = error_errno(_("cannot read ref file '%s'"), iter->path.buf); + goto cleanup; + } + + if (parse_loose_ref_contents(ref_store->repo->hash_algo, + ref_content.buf, &oid, &referent, + &type, &trailing, &failure_errno)) { + strbuf_rtrim(&ref_content); + ret = fsck_report_ref(o, &report, + FSCK_MSG_BAD_REF_CONTENT, + "%s", ref_content.buf); + goto cleanup; + } + + if (!(type & REF_ISSYMREF)) { + if (!*trailing) { + ret = fsck_report_ref(o, &report, + FSCK_MSG_REF_MISSING_NEWLINE, + "misses LF at the end"); + goto cleanup; + } + if (*trailing != '\n' || *(trailing + 1)) { + ret = fsck_report_ref(o, &report, + FSCK_MSG_TRAILING_REF_CONTENT, + "has trailing garbage: '%s'", trailing); + goto cleanup; + } + } else { + ret = files_fsck_symref_target(o, &report, &referent, 0); + goto cleanup; + } + +cleanup: + strbuf_release(&ref_content); + strbuf_release(&referent); + strbuf_release(&abs_gitdir); + return ret; +} + static int files_fsck_refs_name(struct ref_store *ref_store UNUSED, struct fsck_options *o, - const char *refs_check_dir, + const char *refname, struct dir_iterator *iter) { struct strbuf sb = STRBUF_INIT; @@ -3519,11 +3739,13 @@ static int files_fsck_refs_name(struct ref_store *ref_store UNUSED, if (iter->basename[0] != '.' && ends_with(iter->basename, ".lock")) goto cleanup; - if (check_refname_format(iter->basename, REFNAME_ALLOW_ONELEVEL)) { - struct fsck_ref_report report = { .path = NULL }; + /* + * This works right now because we never check the root refs. + */ + if (check_refname_format(refname, 0)) { + struct fsck_ref_report report = { 0 }; - strbuf_addf(&sb, "%s/%s", refs_check_dir, iter->relative_path); - report.path = sb.buf; + report.path = refname; ret = fsck_report_ref(o, &report, FSCK_MSG_BAD_REF_NAME, "invalid refname format"); @@ -3537,8 +3759,10 @@ static int files_fsck_refs_name(struct ref_store *ref_store UNUSED, static int files_fsck_refs_dir(struct ref_store *ref_store, struct fsck_options *o, const char *refs_check_dir, + struct worktree *wt, files_fsck_refs_fn *fsck_refs_fn) { + struct strbuf refname = STRBUF_INIT; struct strbuf sb = STRBUF_INIT; struct dir_iterator *iter; int iter_status; @@ -3557,11 +3781,18 @@ static int files_fsck_refs_dir(struct ref_store *ref_store, continue; } else if (S_ISREG(iter->st.st_mode) || S_ISLNK(iter->st.st_mode)) { + strbuf_reset(&refname); + + if (!is_main_worktree(wt)) + strbuf_addf(&refname, "worktrees/%s/", wt->id); + strbuf_addf(&refname, "%s/%s", refs_check_dir, + iter->relative_path); + if (o->verbose) - fprintf_ln(stderr, "Checking %s/%s", - refs_check_dir, iter->relative_path); + fprintf_ln(stderr, "Checking %s", refname.buf); + for (size_t i = 0; fsck_refs_fn[i]; i++) { - if (fsck_refs_fn[i](ref_store, o, refs_check_dir, iter)) + if (fsck_refs_fn[i](ref_store, o, refname.buf, iter)) ret = -1; } } else { @@ -3578,30 +3809,34 @@ static int files_fsck_refs_dir(struct ref_store *ref_store, out: strbuf_release(&sb); + strbuf_release(&refname); return ret; } static int files_fsck_refs(struct ref_store *ref_store, - struct fsck_options *o) + struct fsck_options *o, + struct worktree *wt) { files_fsck_refs_fn fsck_refs_fn[]= { files_fsck_refs_name, + files_fsck_refs_content, NULL, }; if (o->verbose) fprintf_ln(stderr, _("Checking references consistency")); - return files_fsck_refs_dir(ref_store, o, "refs", fsck_refs_fn); + return files_fsck_refs_dir(ref_store, o, "refs", wt, fsck_refs_fn); } static int files_fsck(struct ref_store *ref_store, - struct fsck_options *o) + struct fsck_options *o, + struct worktree *wt) { struct files_ref_store *refs = files_downcast(ref_store, REF_STORE_READ, "fsck"); - return files_fsck_refs(ref_store, o) | - refs->packed_ref_store->be->fsck(refs->packed_ref_store, o); + return files_fsck_refs(ref_store, o, wt) | + refs->packed_ref_store->be->fsck(refs->packed_ref_store, o, wt); } struct ref_storage_be refs_be_files = { @@ -3614,7 +3849,6 @@ struct ref_storage_be refs_be_files = { .transaction_prepare = files_transaction_prepare, .transaction_finish = files_transaction_finish, .transaction_abort = files_transaction_abort, - .initial_transaction_commit = files_initial_transaction_commit, .pack_refs = files_pack_refs, .rename_ref = files_rename_ref, diff --git a/refs/iterator.c b/refs/iterator.c index 8e999d81fc638f..d25e568bf0b768 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -3,6 +3,8 @@ * documentation about the design and use of reference iterators. */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "refs.h" #include "refs/refs-internal.h" diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 07c57fd541a503..a7b6f74b6e35f8 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "../git-compat-util.h" #include "../config.h" @@ -13,6 +14,7 @@ #include "../lockfile.h" #include "../chdir-notify.h" #include "../statinfo.h" +#include "../worktree.h" #include "../wrapper.h" #include "../write-or-die.h" #include "../trace2.h" @@ -1730,13 +1732,6 @@ static int packed_transaction_finish(struct ref_store *ref_store, return ret; } -static int packed_initial_transaction_commit(struct ref_store *ref_store UNUSED, - struct ref_transaction *transaction, - struct strbuf *err) -{ - return ref_transaction_commit(transaction, err); -} - static int packed_pack_refs(struct ref_store *ref_store UNUSED, struct pack_refs_opts *pack_opts UNUSED) { @@ -1754,8 +1749,13 @@ static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_s } static int packed_fsck(struct ref_store *ref_store UNUSED, - struct fsck_options *o UNUSED) + struct fsck_options *o UNUSED, + struct worktree *wt) { + + if (!is_main_worktree(wt)) + return 0; + return 0; } @@ -1769,7 +1769,6 @@ struct ref_storage_be refs_be_packed = { .transaction_prepare = packed_transaction_prepare, .transaction_finish = packed_transaction_finish, .transaction_abort = packed_transaction_abort, - .initial_transaction_commit = packed_initial_transaction_commit, .pack_refs = packed_pack_refs, .rename_ref = NULL, diff --git a/refs/ref-cache.c b/refs/ref-cache.c index 35bae7e05dedcd..02f09e4df88f23 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -68,8 +68,9 @@ static void free_ref_entry(struct ref_entry *entry) * trigger the reading of loose refs. */ clear_ref_dir(&entry->u.subdir); + } else { + free(entry->u.value.referent); } - free(entry->u.value.referent); free(entry); } diff --git a/refs/refs-internal.h b/refs/refs-internal.h index 2313c830d8faca..8894b43d1d1a32 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -113,6 +113,14 @@ struct ref_update { void *backend_data; unsigned int type; char *msg; + char *committer_info; + + /* + * The index overrides the default sort algorithm. This is needed + * when migrating reflogs and we want to ensure we carry over the + * same order. + */ + uint64_t index; /* * If this ref_update was split off of a symref update via @@ -154,6 +162,7 @@ struct ref_update *ref_transaction_add_update( const struct object_id *new_oid, const struct object_id *old_oid, const char *new_target, const char *old_target, + const char *committer_info, const char *msg); /* @@ -193,6 +202,8 @@ struct ref_transaction { size_t nr; enum ref_transaction_state state; void *backend_data; + unsigned int flags; + uint64_t max_index; }; /* @@ -653,7 +664,8 @@ typedef int read_symbolic_ref_fn(struct ref_store *ref_store, const char *refnam struct strbuf *referent); typedef int fsck_fn(struct ref_store *ref_store, - struct fsck_options *o); + struct fsck_options *o, + struct worktree *wt); struct ref_storage_be { const char *name; @@ -665,7 +677,6 @@ struct ref_storage_be { ref_transaction_prepare_fn *transaction_prepare; ref_transaction_finish_fn *transaction_finish; ref_transaction_abort_fn *transaction_abort; - ref_transaction_commit_fn *initial_transaction_commit; pack_refs_fn *pack_refs; rename_ref_fn *rename_ref; @@ -673,6 +684,11 @@ struct ref_storage_be { ref_iterator_begin_fn *iterator_begin; read_raw_ref_fn *read_raw_ref; + + /* + * Please refer to `refs_read_symbolic_ref()` for the expected + * behaviour. + */ read_symbolic_ref_fn *read_symbolic_ref; reflog_iterator_begin_fn *reflog_iterator_begin; @@ -715,7 +731,7 @@ struct ref_store { int parse_loose_ref_contents(const struct git_hash_algo *algop, const char *buf, struct object_id *oid, struct strbuf *referent, unsigned int *type, - int *failure_errno); + const char **trailing, int *failure_errno); /* * Fill in the generic part of refs and add it to our collection of diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 3c96fbf66f9e20..771f50df382af3 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -15,6 +15,7 @@ #include "../object.h" #include "../path.h" #include "../refs.h" +#include "../reftable/reftable-basics.h" #include "../reftable/reftable-stack.h" #include "../reftable/reftable-record.h" #include "../reftable/reftable-error.h" @@ -23,6 +24,7 @@ #include "../setup.h" #include "../strmap.h" #include "../trace2.h" +#include "../write-or-die.h" #include "parse.h" #include "refs-internal.h" @@ -32,24 +34,111 @@ */ #define REF_UPDATE_VIA_HEAD (1 << 8) +struct reftable_backend { + struct reftable_stack *stack; + struct reftable_iterator it; +}; + +static void reftable_backend_on_reload(void *payload) +{ + struct reftable_backend *be = payload; + reftable_iterator_destroy(&be->it); +} + +static int reftable_backend_init(struct reftable_backend *be, + const char *path, + const struct reftable_write_options *_opts) +{ + struct reftable_write_options opts = *_opts; + opts.on_reload = reftable_backend_on_reload; + opts.on_reload_payload = be; + return reftable_new_stack(&be->stack, path, &opts); +} + +static void reftable_backend_release(struct reftable_backend *be) +{ + reftable_stack_destroy(be->stack); + be->stack = NULL; + reftable_iterator_destroy(&be->it); +} + +static int reftable_backend_read_ref(struct reftable_backend *be, + const char *refname, + struct object_id *oid, + struct strbuf *referent, + unsigned int *type) +{ + struct reftable_ref_record ref = {0}; + int ret; + + if (!be->it.ops) { + ret = reftable_stack_init_ref_iterator(be->stack, &be->it); + if (ret) + goto done; + } + + ret = reftable_iterator_seek_ref(&be->it, refname); + if (ret) + goto done; + + ret = reftable_iterator_next_ref(&be->it, &ref); + if (ret) + goto done; + + if (strcmp(ref.refname, refname)) { + ret = 1; + 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)) { + unsigned int hash_id; + + switch (reftable_stack_hash_id(be->stack)) { + case REFTABLE_HASH_SHA1: + hash_id = GIT_HASH_SHA1; + break; + case REFTABLE_HASH_SHA256: + hash_id = GIT_HASH_SHA256; + break; + default: + BUG("unhandled hash ID %d", reftable_stack_hash_id(be->stack)); + } + + oidread(oid, reftable_ref_record_val1(&ref), + &hash_algos[hash_id]); + } 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; +} + struct reftable_ref_store { struct ref_store base; /* - * The main stack refers to the common dir and thus contains common + * The main backend refers to the common dir and thus contains common * refs as well as refs of the main repository. */ - struct reftable_stack *main_stack; + struct reftable_backend main_backend; /* - * The worktree stack refers to the gitdir in case the refdb is opened + * The worktree backend 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; + struct reftable_backend worktree_backend; /* - * Map of worktree stacks by their respective worktree names. The map + * Map of worktree backends by their respective worktree names. The map * is populated lazily when we try to resolve `worktrees/$worktree` refs. */ - struct strmap worktree_stacks; + struct strmap worktree_backends; struct reftable_write_options write_options; unsigned int store_flags; @@ -95,21 +184,25 @@ static struct reftable_ref_store *reftable_be_downcast(struct ref_store *ref_sto * 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) +static int backend_for(struct reftable_backend **out, + struct reftable_ref_store *store, + const char *refname, + const char **rewritten_ref, + int reload) { + struct reftable_backend *be; const char *wtname; int wtname_len; - if (!refname) - return store->main_stack; + if (!refname) { + be = &store->main_backend; + goto out; + } 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 @@ -123,40 +216,55 @@ static struct reftable_stack *stack_for(struct reftable_ref_store *store, /* * 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 + * `worktree_backends` and once via `worktree_backend`. 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) { + be = strmap_get(&store->worktree_backends, wtname_buf.buf); + if (!be) { 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); + CALLOC_ARRAY(be, 1); + store->err = reftable_backend_init(be, wt_dir.buf, + &store->write_options); assert(store->err != REFTABLE_API_ERROR); - strmap_put(&store->worktree_stacks, wtname_buf.buf, stack); + + strmap_put(&store->worktree_backends, wtname_buf.buf, be); } strbuf_release(&wt_dir); - return stack; + goto out; } 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; + if (!store->worktree_backend.stack) + be = &store->main_backend; + else + be = &store->worktree_backend; + goto out; case REF_WORKTREE_MAIN: case REF_WORKTREE_SHARED: - return store->main_stack; + be = &store->main_backend; + goto out; default: BUG("unhandled worktree reference type"); } + +out: + if (reload) { + int ret = reftable_stack_reload(be->stack); + if (ret) + return ret; + } + *out = be; + + return 0; } static int should_write_log(struct reftable_ref_store *refs, const char *refname) @@ -205,38 +313,6 @@ static void fill_reftable_log_record(struct reftable_log_record *log, const stru log->value.update.tz_offset = sign * atoi(tz_begin); } -static int read_ref_without_reload(struct reftable_ref_store *refs, - 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), - refs->base.repo->hash_algo); - } 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 int reftable_be_config(const char *var, const char *value, const struct config_context *ctx, void *_opts) @@ -272,6 +348,11 @@ static int reftable_be_config(const char *var, const char *value, return 0; } +static int reftable_be_fsync(int fd) +{ + return fsync_component(FSYNC_COMPONENT_REFERENCE, fd); +} + static struct ref_store *reftable_be_init(struct repository *repo, const char *gitdir, unsigned int store_flags) @@ -285,15 +366,25 @@ static struct ref_store *reftable_be_init(struct repository *repo, umask(mask); base_ref_store_init(&refs->base, repo, gitdir, &refs_be_reftable); - strmap_init(&refs->worktree_stacks); + strmap_init(&refs->worktree_backends); refs->store_flags = store_flags; refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo); - refs->write_options.hash_id = repo->hash_algo->format_id; - refs->write_options.default_permissions = calc_shared_perm(0666 & ~mask); + switch (repo->hash_algo->format_id) { + case GIT_SHA1_FORMAT_ID: + refs->write_options.hash_id = REFTABLE_HASH_SHA1; + break; + case GIT_SHA256_FORMAT_ID: + refs->write_options.hash_id = REFTABLE_HASH_SHA256; + break; + default: + BUG("unknown hash algorithm %d", repo->hash_algo->format_id); + } + refs->write_options.default_permissions = calc_shared_perm(the_repository, 0666 & ~mask); refs->write_options.disable_auto_compact = !git_env_bool("GIT_TEST_REFTABLE_AUTOCOMPACTION", 1); refs->write_options.lock_timeout_ms = 100; + refs->write_options.fsync = reftable_be_fsync; git_config(reftable_be_config, &refs->write_options); @@ -320,8 +411,8 @@ static struct ref_store *reftable_be_init(struct repository *repo, strbuf_realpath(&path, gitdir, 0); } strbuf_addstr(&path, "/reftable"); - refs->err = reftable_new_stack(&refs->main_stack, path.buf, - &refs->write_options); + refs->err = reftable_backend_init(&refs->main_backend, path.buf, + &refs->write_options); if (refs->err) goto done; @@ -337,8 +428,8 @@ static struct ref_store *reftable_be_init(struct repository *repo, strbuf_reset(&path); strbuf_addf(&path, "%s/reftable", gitdir); - refs->err = reftable_new_stack(&refs->worktree_stack, path.buf, - &refs->write_options); + refs->err = reftable_backend_init(&refs->worktree_backend, path.buf, + &refs->write_options); if (refs->err) goto done; } @@ -357,19 +448,17 @@ static void reftable_be_release(struct ref_store *ref_store) struct strmap_entry *entry; struct hashmap_iter iter; - if (refs->main_stack) { - reftable_stack_destroy(refs->main_stack); - refs->main_stack = NULL; - } + if (refs->main_backend.stack) + reftable_backend_release(&refs->main_backend); + if (refs->worktree_backend.stack) + reftable_backend_release(&refs->worktree_backend); - if (refs->worktree_stack) { - reftable_stack_destroy(refs->worktree_stack); - refs->worktree_stack = NULL; + strmap_for_each_entry(&refs->worktree_backends, &iter, entry) { + struct reftable_backend *be = entry->value; + reftable_backend_release(be); + free(be); } - - strmap_for_each_entry(&refs->worktree_stacks, &iter, entry) - reftable_stack_destroy(entry->value); - strmap_clear(&refs->worktree_stacks, 0); + strmap_clear(&refs->worktree_backends, 0); } static int reftable_be_create_on_disk(struct ref_store *ref_store, @@ -381,21 +470,21 @@ static int reftable_be_create_on_disk(struct ref_store *ref_store, struct strbuf sb = STRBUF_INIT; strbuf_addf(&sb, "%s/reftable", refs->base.gitdir); - safe_create_dir(sb.buf, 1); + safe_create_dir(the_repository, 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); + adjust_shared_perm(the_repository, sb.buf); strbuf_reset(&sb); strbuf_addf(&sb, "%s/refs", refs->base.gitdir); - safe_create_dir(sb.buf, 1); + safe_create_dir(the_repository, 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); + adjust_shared_perm(the_repository, sb.buf); strbuf_release(&sb); return 0; @@ -764,7 +853,7 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto 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, + main_iter = ref_iterator_for_stack(refs, refs->main_backend.stack, prefix, exclude_patterns, flags); /* @@ -772,14 +861,14 @@ static struct ref_iterator *reftable_be_iterator_begin(struct ref_store *ref_sto * right now. If we aren't, then we return the common reftable * iterator, only. */ - if (!refs->worktree_stack) + if (!refs->worktree_backend.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, + worktree_iter = ref_iterator_for_stack(refs, refs->worktree_backend.stack, prefix, exclude_patterns, flags); return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, ref_iterator_select, NULL); @@ -794,17 +883,17 @@ static int reftable_be_read_raw_ref(struct ref_store *ref_store, { 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); + struct reftable_backend *be; int ret; if (refs->err < 0) return refs->err; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) return ret; - ret = read_ref_without_reload(refs, stack, refname, oid, referent, type); + ret = reftable_backend_read_ref(be, refname, oid, referent, type); if (ret < 0) return ret; if (ret > 0) { @@ -821,21 +910,22 @@ static int reftable_be_read_symbolic_ref(struct ref_store *ref_store, { 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}; + struct reftable_backend *be; + struct object_id oid; + unsigned int type = 0; int ret; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); 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 = reftable_backend_read_ref(be, refname, &oid, referent, &type); + if (ret) ret = -1; - - reftable_ref_record_release(&ref); + else if (type == REF_ISSYMREF) + ; /* happy */ + else + ret = NOT_A_SYMREF; return ret; } @@ -846,12 +936,13 @@ struct reftable_transaction_update { struct write_transaction_table_arg { struct reftable_ref_store *refs; - struct reftable_stack *stack; + struct reftable_backend *be; struct reftable_addition *addition; struct reftable_transaction_update *updates; size_t updates_nr; size_t updates_alloc; size_t updates_expected; + uint64_t max_index; }; struct reftable_transaction_data { @@ -881,27 +972,37 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out, struct ref_update *update, struct strbuf *err) { - struct reftable_stack *stack = stack_for(refs, update->refname, NULL); struct write_transaction_table_arg *arg = NULL; + struct reftable_backend *be; size_t i; int ret; + /* + * This function gets called in a loop, and we don't want to repeatedly + * reload the stack for every single ref update. Instead, we manually + * reload further down in the case where we haven't yet prepared the + * specific `reftable_backend`. + */ + ret = backend_for(&be, refs, update->refname, NULL, 0); + if (ret) + return 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) + if (tx_data->args[i].be == be) arg = &tx_data->args[i]; if (!arg) { struct reftable_addition *addition; - ret = reftable_stack_reload(stack); + ret = reftable_stack_reload(be->stack); if (ret) return ret; - ret = reftable_stack_new_addition(&addition, stack, + ret = reftable_stack_new_addition(&addition, be->stack, REFTABLE_STACK_NEW_ADDITION_RELOAD); if (ret) { if (ret == REFTABLE_LOCK_ERROR) @@ -913,12 +1014,13 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out, tx_data->args_alloc); arg = &tx_data->args[tx_data->args_nr++]; arg->refs = refs; - arg->stack = stack; + arg->be = be; arg->addition = addition; arg->updates = NULL; arg->updates_nr = 0; arg->updates_alloc = 0; arg->updates_expected = 0; + arg->max_index = 0; } arg->updates_expected++; @@ -968,6 +1070,7 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, 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 reftable_backend *be; struct object_id head_oid; unsigned int head_type = 0; size_t i; @@ -990,8 +1093,9 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, if (ret) goto done; - string_list_append(&affected_refnames, - transaction->updates[i]->refname); + if (!(transaction->updates[i]->flags & REF_LOG_ONLY)) + string_list_append(&affected_refnames, + transaction->updates[i]->refname); } /* @@ -1014,8 +1118,23 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, goto done; } - ret = read_ref_without_reload(refs, stack_for(refs, "HEAD", NULL), "HEAD", - &head_oid, &head_referent, &head_type); + /* + * TODO: it's dubious whether we should reload the stack that "HEAD" + * belongs to or not. In theory, it may happen that we only modify + * stacks which are _not_ part of the "HEAD" stack. In that case we + * wouldn't have prepared any transaction for its stack and would not + * have reloaded it, which may mean that it is stale. + * + * On the other hand, reloading that stack without locking it feels + * wrong, too, as the value of "HEAD" could be modified concurrently at + * any point in time. + */ + ret = backend_for(&be, refs, "HEAD", NULL, 0); + if (ret) + goto done; + + ret = reftable_backend_read_ref(be, "HEAD", &head_oid, + &head_referent, &head_type); if (ret < 0) goto done; ret = 0; @@ -1023,10 +1142,18 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, 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); + /* + * There is no need to reload the respective backends here as + * we have already reloaded them when preparing the transaction + * update. And given that the stacks have been locked there + * shouldn't have been any concurrent modifications of the + * stack. + */ + ret = backend_for(&be, refs, u->refname, &rewritten_ref, 0); + if (ret) + goto done; /* Verify that the new object ID is valid. */ if ((u->flags & REF_HAVE_NEW) && !is_null_oid(&u->new_oid) && @@ -1078,12 +1205,13 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, new_update = ref_transaction_add_update( transaction, "HEAD", u->flags | REF_LOG_ONLY | REF_NO_DEREF, - &u->new_oid, &u->old_oid, NULL, NULL, u->msg); + &u->new_oid, &u->old_oid, NULL, NULL, NULL, + u->msg); string_list_insert(&affected_refnames, new_update->refname); } - ret = read_ref_without_reload(refs, stack, rewritten_ref, - ¤t_oid, &referent, &u->type); + ret = reftable_backend_read_ref(be, rewritten_ref, + ¤t_oid, &referent, &u->type); if (ret < 0) goto done; if (ret > 0 && !ref_update_expects_existing_old_ref(u)) { @@ -1097,7 +1225,9 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, * at a later point. */ ret = refs_verify_refname_available(ref_store, u->refname, - &affected_refnames, NULL, err); + &affected_refnames, NULL, + transaction->flags & REF_TRANSACTION_FLAG_INITIAL, + err); if (ret < 0) goto done; @@ -1159,7 +1289,8 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, transaction, referent.buf, new_flags, u->new_target ? NULL : &u->new_oid, u->old_target ? NULL : &u->old_oid, - u->new_target, u->old_target, u->msg); + u->new_target, u->old_target, + u->committer_info, u->msg); new_update->parent_update = u; @@ -1206,10 +1337,13 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, goto done; } } else if ((u->flags & REF_HAVE_OLD) && !oideq(¤t_oid, &u->old_oid)) { - if (is_null_oid(&u->old_oid)) + ret = TRANSACTION_NAME_CONFLICT; + if (is_null_oid(&u->old_oid)) { strbuf_addf(err, _("cannot lock ref '%s': " "reference already exists"), ref_update_original_update_refname(u)); + ret = TRANSACTION_CREATE_EXISTS; + } else if (is_null_oid(¤t_oid)) strbuf_addf(err, _("cannot lock ref '%s': " "reference is missing but expected %s"), @@ -1221,7 +1355,6 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, ref_update_original_update_refname(u), oid_to_hex(¤t_oid), oid_to_hex(&u->old_oid)); - ret = -1; goto done; } @@ -1277,14 +1410,23 @@ static int reftable_be_transaction_abort(struct ref_store *ref_store UNUSED, 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); + struct reftable_transaction_update *update_a = (struct reftable_transaction_update *)a; + struct reftable_transaction_update *update_b = (struct reftable_transaction_update *)b; + + /* + * If there is an index set, it should take preference (default is 0). + * This ensures that updates with indexes are sorted amongst themselves. + */ + if (update_a->update->index || update_b->update->index) + return update_a->update->index - update_b->update->index; + + return strcmp(update_a->update->refname, update_b->update->refname); } static int write_transaction_table(struct reftable_writer *writer, void *cb_data) { struct write_transaction_table_arg *arg = cb_data; - uint64_t ts = reftable_stack_next_update_index(arg->stack); + uint64_t ts = reftable_stack_next_update_index(arg->be->stack); struct reftable_log_record *logs = NULL; struct ident_split committer_ident = {0}; size_t logs_nr = 0, logs_alloc = 0, i; @@ -1297,7 +1439,14 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data QSORT(arg->updates, arg->updates_nr, transaction_update_cmp); - reftable_writer_set_limits(writer, ts, ts); + /* + * During reflog migration, we add indexes for a single reflog with + * multiple entries. Each entry will contain a different update_index, + * so set the limits accordingly. + */ + ret = reftable_writer_set_limits(writer, ts, ts + arg->max_index); + if (ret < 0) + goto done; for (i = 0; i < arg->updates_nr; i++) { struct reftable_transaction_update *tx_update = &arg->updates[i]; @@ -1320,7 +1469,9 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; - reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->be->stack, &it); + if (ret < 0) + goto done; /* * When deleting refs we also delete all reflog entries @@ -1375,12 +1526,28 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data } if (create_reflog) { + struct ident_split c; + ALLOC_GROW(logs, logs_nr + 1, logs_alloc); log = &logs[logs_nr++]; memset(log, 0, sizeof(*log)); - fill_reftable_log_record(log, &committer_ident); - log->update_index = ts; + if (u->committer_info) { + if (split_ident_line(&c, u->committer_info, + strlen(u->committer_info))) + BUG("failed splitting committer info"); + } else { + c = committer_ident; + } + + fill_reftable_log_record(log, &c); + + /* + * Updates are sorted by the writer. So updates for the same + * refname need to contain different update indices. + */ + log->update_index = ts + u->index; + log->refname = xstrdup(u->refname); memcpy(log->value.update.new_hash, u->new_oid.hash, GIT_MAX_RAWSZ); @@ -1465,6 +1632,8 @@ static int reftable_be_transaction_finish(struct ref_store *ref_store UNUSED, int ret = 0; for (size_t i = 0; i < tx_data->args_nr; i++) { + tx_data->args[i].max_index = transaction->max_index; + ret = reftable_addition_add(tx_data->args[i].addition, write_transaction_table, &tx_data->args[i]); if (ret < 0) @@ -1488,13 +1657,6 @@ static int reftable_be_transaction_finish(struct ref_store *ref_store UNUSED, 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) { @@ -1506,9 +1668,9 @@ static int reftable_be_pack_refs(struct ref_store *ref_store, if (refs->err) return refs->err; - stack = refs->worktree_stack; + stack = refs->worktree_backend.stack; if (!stack) - stack = refs->main_stack; + stack = refs->main_backend.stack; if (opts->flags & PACK_REFS_AUTO) ret = reftable_stack_auto_compact(stack); @@ -1539,7 +1701,7 @@ struct write_create_symref_arg { struct write_copy_arg { struct reftable_ref_store *refs; - struct reftable_stack *stack; + struct reftable_backend *be; const char *oldname; const char *newname; const char *logmsg; @@ -1564,7 +1726,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) if (split_ident_line(&committer_ident, committer_info, strlen(committer_info))) BUG("failed splitting committer info"); - if (reftable_stack_read_ref(arg->stack, arg->oldname, &old_ref)) { + if (reftable_stack_read_ref(arg->be->stack, arg->oldname, &old_ref)) { ret = error(_("refname %s not found"), arg->oldname); goto done; } @@ -1589,7 +1751,7 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) if (arg->delete_old) string_list_insert(&skip, arg->oldname); ret = refs_verify_refname_available(&arg->refs->base, arg->newname, - NULL, &skip, &errbuf); + NULL, &skip, 0, &errbuf); if (ret < 0) { error("%s", errbuf.buf); goto done; @@ -1603,10 +1765,12 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) * 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); + deletion_ts = creation_ts = reftable_stack_next_update_index(arg->be->stack); if (arg->delete_old) creation_ts++; - reftable_writer_set_limits(writer, deletion_ts, creation_ts); + ret = reftable_writer_set_limits(writer, deletion_ts, creation_ts); + if (ret < 0) + goto done; /* * Add the new reference. If this is a rename then we also delete the @@ -1646,8 +1810,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) memcpy(logs[logs_nr].value.update.old_hash, old_ref.value.val1, GIT_MAX_RAWSZ); logs_nr++; - ret = read_ref_without_reload(arg->refs, arg->stack, "HEAD", &head_oid, - &head_referent, &head_type); + ret = reftable_backend_read_ref(arg->be, "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); @@ -1690,7 +1854,10 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data) * 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. */ - reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->be->stack, &it); + if (ret < 0) + goto done; + ret = reftable_iterator_seek_log(&it, arg->oldname); if (ret < 0) goto done; @@ -1760,10 +1927,8 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, { 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, @@ -1775,10 +1940,10 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1); if (ret) goto done; - ret = reftable_stack_add(stack, &write_copy_table, &arg); + ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg); done: assert(ret != REFTABLE_API_ERROR); @@ -1792,10 +1957,8 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, { 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, @@ -1806,10 +1969,10 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1); if (ret) goto done; - ret = reftable_stack_add(stack, &write_copy_table, &arg); + ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg); done: assert(ret != REFTABLE_API_ERROR); @@ -1911,7 +2074,10 @@ static struct reftable_reflog_iterator *reflog_iterator_for_stack(struct reftabl if (ret < 0) goto done; - reftable_stack_init_log_iterator(stack, &iter->iter); + ret = reftable_stack_init_log_iterator(stack, &iter->iter); + if (ret < 0) + goto done; + ret = reftable_iterator_seek_log(&iter->iter, ""); if (ret < 0) goto done; @@ -1927,11 +2093,11 @@ static struct ref_iterator *reftable_be_reflog_iterator_begin(struct ref_store * 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) + main_iter = reflog_iterator_for_stack(refs, refs->main_backend.stack); + if (!refs->worktree_backend.stack) return &main_iter->base; - worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_stack); + worktree_iter = reflog_iterator_for_stack(refs, refs->worktree_backend.stack); return merge_ref_iterator_begin(&worktree_iter->base, &main_iter->base, ref_iterator_select, NULL); @@ -1970,15 +2136,26 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store, { 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_log_record log = {0}; struct reftable_iterator it = {0}; + struct reftable_backend *be; int ret; if (refs->err < 0) return refs->err; - reftable_stack_init_log_iterator(stack, &it); + /* + * TODO: we should adapt this callsite to reload the stack. There is no + * obvious reason why we shouldn't. + */ + ret = backend_for(&be, refs, refname, &refname, 0); + if (ret) + goto done; + + ret = reftable_stack_init_log_iterator(be->stack, &it); + if (ret < 0) + goto done; + ret = reftable_iterator_seek_log(&it, refname); while (!ret) { ret = reftable_iterator_next_log(&it, &log); @@ -1994,6 +2171,7 @@ static int reftable_be_for_each_reflog_ent_reverse(struct ref_store *ref_store, break; } +done: reftable_log_record_release(&log); reftable_iterator_destroy(&it); return ret; @@ -2006,16 +2184,27 @@ static int reftable_be_for_each_reflog_ent(struct ref_store *ref_store, { 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_log_record *logs = NULL; struct reftable_iterator it = {0}; + struct reftable_backend *be; size_t logs_alloc = 0, logs_nr = 0, i; int ret; if (refs->err < 0) return refs->err; - reftable_stack_init_log_iterator(stack, &it); + /* + * TODO: we should adapt this callsite to reload the stack. There is no + * obvious reason why we shouldn't. + */ + ret = backend_for(&be, refs, refname, &refname, 0); + if (ret) + goto done; + + ret = reftable_stack_init_log_iterator(be->stack, &it); + if (ret < 0) + goto done; + ret = reftable_iterator_seek_log(&it, refname); while (!ret) { struct reftable_log_record log = {0}; @@ -2052,20 +2241,23 @@ static int reftable_be_reflog_exists(struct ref_store *ref_store, { 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_log_record log = {0}; struct reftable_iterator it = {0}; + struct reftable_backend *be; int ret; ret = refs->err; if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); + if (ret < 0) + goto done; + + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; - reftable_stack_init_log_iterator(stack, &it); ret = reftable_iterator_seek_log(&it, refname); if (ret < 0) goto done; @@ -2110,10 +2302,12 @@ static int write_reflog_existence_table(struct reftable_writer *writer, if (ret <= 0) goto done; - reftable_writer_set_limits(writer, ts, ts); + ret = reftable_writer_set_limits(writer, ts, ts); + if (ret < 0) + goto done; /* - * The existence entry has both old and new object ID set to the the + * The existence entry has both old and new object ID set to the * null object ID. Our iterators are aware of this and will not present * them to their callers. */ @@ -2134,10 +2328,9 @@ static int reftable_be_create_reflog(struct ref_store *ref_store, { 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 reftable_backend *be; struct write_reflog_existence_arg arg = { .refs = refs, - .stack = stack, .refname = refname, }; int ret; @@ -2146,11 +2339,12 @@ static int reftable_be_create_reflog(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) goto done; + arg.stack = be->stack; - ret = reftable_stack_add(stack, &write_reflog_existence_table, &arg); + ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg); done: return ret; @@ -2169,9 +2363,13 @@ static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_da uint64_t ts = reftable_stack_next_update_index(arg->stack); int ret; - reftable_writer_set_limits(writer, ts, ts); + ret = reftable_writer_set_limits(writer, ts, ts); + if (ret < 0) + goto out; - reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->stack, &it); + if (ret < 0) + goto out; /* * In order to delete a table we need to delete all reflog entries one @@ -2195,6 +2393,7 @@ static int write_reflog_delete_table(struct reftable_writer *writer, void *cb_da ret = reftable_writer_add_log(writer, &tombstone); } +out: reftable_log_record_release(&log); reftable_iterator_destroy(&it); return ret; @@ -2205,17 +2404,18 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store, { 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 reftable_backend *be; struct write_reflog_delete_arg arg = { - .stack = stack, .refname = refname, }; int ret; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret) return ret; - ret = reftable_stack_add(stack, &write_reflog_delete_table, &arg); + arg.stack = be->stack; + + ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg); assert(ret != REFTABLE_API_ERROR); return ret; @@ -2242,7 +2442,9 @@ static int write_reflog_expiry_table(struct reftable_writer *writer, void *cb_da if (arg->records[i].value_type == REFTABLE_LOG_UPDATE) live_records++; - reftable_writer_set_limits(writer, ts, ts); + ret = reftable_writer_set_limits(writer, ts, ts); + if (ret < 0) + return ret; if (!is_null_oid(&arg->update_oid)) { struct reftable_ref_record ref = {0}; @@ -2314,41 +2516,41 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, */ 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_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 reftable_backend *be; struct object_id oid = {0}; + struct strbuf referent = STRBUF_INIT; uint8_t *last_hash = NULL; size_t logs_nr = 0, logs_alloc = 0, i; + unsigned int type = 0; int ret; if (refs->err < 0) return refs->err; - ret = reftable_stack_reload(stack); + ret = backend_for(&be, refs, refname, &refname, 1); if (ret < 0) goto done; - reftable_stack_init_log_iterator(stack, &it); + ret = reftable_stack_init_log_iterator(be->stack, &it); + if (ret < 0) + goto done; ret = reftable_iterator_seek_log(&it, refname); if (ret < 0) goto done; - ret = reftable_stack_new_addition(&add, stack, 0); + ret = reftable_stack_new_addition(&add, be->stack, 0); if (ret < 0) goto done; - ret = reftable_stack_read_ref(stack, refname, &ref_record); + ret = reftable_backend_read_ref(be, refname, &oid, &referent, &type); if (ret < 0) goto done; - if (reftable_ref_record_val1(&ref_record)) - oidread(&oid, reftable_ref_record_val1(&ref_record), - ref_store->repo->hash_algo); prepare_fn(refname, &oid, policy_cb_data); while (1) { @@ -2415,15 +2617,14 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, } } - if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash && - reftable_ref_record_val1(&ref_record)) + if (flags & EXPIRE_REFLOGS_UPDATE_REF && last_hash && !is_null_oid(&oid)) oidread(&arg.update_oid, last_hash, ref_store->repo->hash_algo); arg.refs = refs; arg.records = rewritten; arg.len = logs_nr; - arg.stack = stack, - arg.refname = refname, + arg.stack = be->stack; + arg.refname = refname; ret = reftable_addition_add(add, &write_reflog_expiry_table, &arg); if (ret < 0) @@ -2441,18 +2642,19 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, 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]); + strbuf_release(&referent); free(logs); free(rewritten); return ret; } static int reftable_be_fsck(struct ref_store *ref_store UNUSED, - struct fsck_options *o UNUSED) + struct fsck_options *o UNUSED, + struct worktree *wt UNUSED) { return 0; } @@ -2467,7 +2669,6 @@ struct ref_storage_be refs_be_reftable = { .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, .rename_ref = reftable_be_rename_ref, diff --git a/refspec.c b/refspec.c index ec90ab349a2914..4cb80b520813d1 100644 --- a/refspec.c +++ b/refspec.c @@ -1,12 +1,15 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" #include "hash.h" #include "hex.h" +#include "string-list.h" #include "strvec.h" #include "refs.h" #include "refspec.h" +#include "remote.h" #include "strbuf.h" /* @@ -153,6 +156,7 @@ static int parse_refspec(struct refspec_item *item, const char *refspec, int fet int refspec_item_init(struct refspec_item *item, const char *refspec, int fetch) { memset(item, 0, sizeof(*item)); + item->raw = xstrdup(refspec); return parse_refspec(item, refspec, fetch); } @@ -167,6 +171,7 @@ void refspec_item_clear(struct refspec_item *item) { FREE_AND_NULL(item->src); FREE_AND_NULL(item->dst); + FREE_AND_NULL(item->raw); item->force = 0; item->pattern = 0; item->matching = 0; @@ -179,31 +184,29 @@ void refspec_init(struct refspec *rs, int fetch) rs->fetch = fetch; } -static void refspec_append_nodup(struct refspec *rs, char *refspec) +void refspec_append(struct refspec *rs, const char *refspec) { struct refspec_item item; refspec_item_init_or_die(&item, refspec, rs->fetch); ALLOC_GROW(rs->items, rs->nr + 1, rs->alloc); - rs->items[rs->nr++] = item; - - ALLOC_GROW(rs->raw, rs->raw_nr + 1, rs->raw_alloc); - rs->raw[rs->raw_nr++] = refspec; -} + rs->items[rs->nr] = item; -void refspec_append(struct refspec *rs, const char *refspec) -{ - refspec_append_nodup(rs, xstrdup(refspec)); + rs->nr++; } void refspec_appendf(struct refspec *rs, const char *fmt, ...) { va_list ap; + char *buf; va_start(ap, fmt); - refspec_append_nodup(rs, xstrvfmt(fmt, ap)); + buf = xstrvfmt(fmt, ap); va_end(ap); + + refspec_append(rs, buf); + free(buf); } void refspec_appendn(struct refspec *rs, const char **refspecs, int nr) @@ -224,12 +227,6 @@ void refspec_clear(struct refspec *rs) rs->alloc = 0; rs->nr = 0; - for (i = 0; i < rs->raw_nr; i++) - free((char *)rs->raw[i]); - FREE_AND_NULL(rs->raw); - rs->raw_alloc = 0; - rs->raw_nr = 0; - rs->fetch = 0; } @@ -241,16 +238,6 @@ int valid_fetch_refspec(const char *fetch_refspec_str) return ret; } -int valid_remote_name(const char *name) -{ - int result; - struct strbuf refspec = STRBUF_INIT; - strbuf_addf(&refspec, "refs/heads/test:refs/remotes/%s/test", name); - result = valid_fetch_refspec(refspec.buf); - strbuf_release(&refspec); - return result; -} - void refspec_ref_prefixes(const struct refspec *rs, struct strvec *ref_prefixes) { @@ -281,3 +268,204 @@ void refspec_ref_prefixes(const struct refspec *rs, } } } + +int match_refname_with_pattern(const char *pattern, const char *refname, + const char *replacement, char **result) +{ + const char *kstar = strchr(pattern, '*'); + size_t klen; + size_t ksuffixlen; + size_t namelen; + int ret; + if (!kstar) + die(_("pattern '%s' has no '*'"), pattern); + klen = kstar - pattern; + ksuffixlen = strlen(kstar + 1); + namelen = strlen(refname); + ret = !strncmp(refname, pattern, klen) && namelen >= klen + ksuffixlen && + !memcmp(refname + namelen - ksuffixlen, kstar + 1, ksuffixlen); + if (ret && replacement) { + struct strbuf sb = STRBUF_INIT; + const char *vstar = strchr(replacement, '*'); + if (!vstar) + die(_("replacement '%s' has no '*'"), replacement); + strbuf_add(&sb, replacement, vstar - replacement); + strbuf_add(&sb, refname + klen, namelen - klen - ksuffixlen); + strbuf_addstr(&sb, vstar + 1); + *result = strbuf_detach(&sb, NULL); + } + return ret; +} + +static int refspec_match(const struct refspec_item *refspec, + const char *name) +{ + if (refspec->pattern) + return match_refname_with_pattern(refspec->src, name, NULL, NULL); + + return !strcmp(refspec->src, name); +} + +int refname_matches_negative_refspec_item(const char *refname, struct refspec *rs) +{ + int i; + + for (i = 0; i < rs->nr; i++) { + if (rs->items[i].negative && refspec_match(&rs->items[i], refname)) + return 1; + } + return 0; +} + +static int refspec_find_negative_match(struct refspec *rs, struct refspec_item *query) +{ + int i, matched_negative = 0; + int find_src = !query->src; + struct string_list reversed = STRING_LIST_INIT_DUP; + const char *needle = find_src ? query->dst : query->src; + + /* + * Check whether the queried ref matches any negative refpsec. If so, + * then we should ultimately treat this as not matching the query at + * all. + * + * Note that negative refspecs always match the source, but the query + * item uses the destination. To handle this, we apply pattern + * refspecs in reverse to figure out if the query source matches any + * of the negative refspecs. + * + * The first loop finds and expands all positive refspecs + * matched by the queried ref. + * + * The second loop checks if any of the results of the first loop + * match any negative refspec. + */ + for (i = 0; i < rs->nr; i++) { + struct refspec_item *refspec = &rs->items[i]; + char *expn_name; + + if (refspec->negative) + continue; + + /* Note the reversal of src and dst */ + if (refspec->pattern) { + const char *key = refspec->dst ? refspec->dst : refspec->src; + const char *value = refspec->src; + + if (match_refname_with_pattern(key, needle, value, &expn_name)) + string_list_append_nodup(&reversed, expn_name); + } else if (refspec->matching) { + /* For the special matching refspec, any query should match */ + string_list_append(&reversed, needle); + } else if (!refspec->src) { + BUG("refspec->src should not be null here"); + } else if (!strcmp(needle, refspec->src)) { + string_list_append(&reversed, refspec->src); + } + } + + for (i = 0; !matched_negative && i < reversed.nr; i++) { + if (refname_matches_negative_refspec_item(reversed.items[i].string, rs)) + matched_negative = 1; + } + + string_list_clear(&reversed, 0); + + return matched_negative; +} + +void refspec_find_all_matches(struct refspec *rs, + struct refspec_item *query, + struct string_list *results) +{ + int i; + int find_src = !query->src; + + if (find_src && !query->dst) + BUG("refspec_find_all_matches: need either src or dst"); + + if (refspec_find_negative_match(rs, query)) + return; + + for (i = 0; i < rs->nr; i++) { + struct refspec_item *refspec = &rs->items[i]; + const char *key = find_src ? refspec->dst : refspec->src; + const char *value = find_src ? refspec->src : refspec->dst; + const char *needle = find_src ? query->dst : query->src; + char **result = find_src ? &query->src : &query->dst; + + if (!refspec->dst || refspec->negative) + continue; + if (refspec->pattern) { + if (match_refname_with_pattern(key, needle, value, result)) + string_list_append_nodup(results, *result); + } else if (!strcmp(needle, key)) { + string_list_append(results, value); + } + } +} + +int refspec_find_match(struct refspec *rs, struct refspec_item *query) +{ + int i; + int find_src = !query->src; + const char *needle = find_src ? query->dst : query->src; + char **result = find_src ? &query->src : &query->dst; + + if (find_src && !query->dst) + BUG("refspec_find_match: need either src or dst"); + + if (refspec_find_negative_match(rs, query)) + return -1; + + for (i = 0; i < rs->nr; i++) { + struct refspec_item *refspec = &rs->items[i]; + const char *key = find_src ? refspec->dst : refspec->src; + const char *value = find_src ? refspec->src : refspec->dst; + + if (!refspec->dst || refspec->negative) + continue; + if (refspec->pattern) { + if (match_refname_with_pattern(key, needle, value, result)) { + query->force = refspec->force; + return 0; + } + } else if (!strcmp(needle, key)) { + *result = xstrdup(value); + query->force = refspec->force; + return 0; + } + } + return -1; +} + +struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs) +{ + struct ref **tail; + + for (tail = &ref_map; *tail; ) { + struct ref *ref = *tail; + + if (refname_matches_negative_refspec_item(ref->name, rs)) { + *tail = ref->next; + free(ref->peer_ref); + free(ref); + } else + tail = &ref->next; + } + + return ref_map; +} + +char *apply_refspecs(struct refspec *rs, const char *name) +{ + struct refspec_item query; + + memset(&query, 0, sizeof(struct refspec_item)); + query.src = (char *)name; + + if (refspec_find_match(rs, &query)) + return NULL; + + return query.dst; +} diff --git a/refspec.h b/refspec.h index 754be45cee3ce5..e2b5cc54efbdf3 100644 --- a/refspec.h +++ b/refspec.h @@ -26,8 +26,12 @@ struct refspec_item { char *src; char *dst; + + char *raw; }; +struct string_list; + #define REFSPEC_FETCH 1 #define REFSPEC_PUSH 0 @@ -43,10 +47,6 @@ struct refspec { int alloc; int nr; - const char **raw; - int raw_alloc; - int raw_nr; - int fetch; }; @@ -63,7 +63,6 @@ void refspec_appendn(struct refspec *rs, const char **refspecs, int nr); void refspec_clear(struct refspec *rs); int valid_fetch_refspec(const char *refspec); -int valid_remote_name(const char *name); struct strvec; /* @@ -73,4 +72,40 @@ struct strvec; void refspec_ref_prefixes(const struct refspec *rs, struct strvec *ref_prefixes); +int refname_matches_negative_refspec_item(const char *refname, struct refspec *rs); + +/* + * Checks if a refname matches a globbing refspec pattern. + * If replacement is provided, computes the corresponding mapped refname. + * Returns 1 if refname matches pattern, 0 otherwise. + */ +int match_refname_with_pattern(const char *pattern, const char *refname, + const char *replacement, char **result); + +/* + * Queries a refspec for a match and updates the query item. + * Returns 0 on success, -1 if no match is found or negative refspec matches. + */ +int refspec_find_match(struct refspec *rs, struct refspec_item *query); + +/* + * Queries a refspec for all matches and appends results to the provided string + * list. + */ +void refspec_find_all_matches(struct refspec *rs, + struct refspec_item *query, + struct string_list *results); + +/* + * Remove all entries in the input list which match any negative refspec in + * the refspec list. + */ +struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs); + +/* + * Search for a refspec that matches the given name and return the + * corresponding destination (dst) if a match is found, NULL otherwise. + */ +char *apply_refspecs(struct refspec *rs, const char *name); + #endif /* REFSPEC_H */ diff --git a/reftable/basics.c b/reftable/basics.c index 0058619ca6742a..3b5ea27bbdc56e 100644 --- a/reftable/basics.c +++ b/reftable/basics.c @@ -6,7 +6,146 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ +#define REFTABLE_ALLOW_BANNED_ALLOCATORS #include "basics.h" +#include "reftable-basics.h" +#include "reftable-error.h" + +static void *(*reftable_malloc_ptr)(size_t sz); +static void *(*reftable_realloc_ptr)(void *, size_t); +static void (*reftable_free_ptr)(void *); + +void *reftable_malloc(size_t sz) +{ + if (!sz) + return NULL; + if (reftable_malloc_ptr) + return (*reftable_malloc_ptr)(sz); + return malloc(sz); +} + +void *reftable_realloc(void *p, size_t sz) +{ + if (!sz) { + reftable_free(p); + return NULL; + } + + if (reftable_realloc_ptr) + return (*reftable_realloc_ptr)(p, sz); + return realloc(p, sz); +} + +void reftable_free(void *p) +{ + if (reftable_free_ptr) + reftable_free_ptr(p); + else + free(p); +} + +void *reftable_calloc(size_t nelem, size_t elsize) +{ + void *p; + + if (nelem && elsize > SIZE_MAX / nelem) + return NULL; + + p = reftable_malloc(nelem * elsize); + if (!p) + return NULL; + + memset(p, 0, nelem * elsize); + return p; +} + +char *reftable_strdup(const char *str) +{ + size_t len = strlen(str); + char *result = reftable_malloc(len + 1); + if (!result) + return NULL; + memcpy(result, str, len + 1); + return result; +} + +void reftable_set_alloc(void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), void (*free)(void *)) +{ + reftable_malloc_ptr = malloc; + reftable_realloc_ptr = realloc; + reftable_free_ptr = free; +} + +void reftable_buf_init(struct reftable_buf *buf) +{ + struct reftable_buf empty = REFTABLE_BUF_INIT; + *buf = empty; +} + +void reftable_buf_release(struct reftable_buf *buf) +{ + reftable_free(buf->buf); + reftable_buf_init(buf); +} + +void reftable_buf_reset(struct reftable_buf *buf) +{ + if (buf->alloc) { + buf->len = 0; + buf->buf[0] = '\0'; + } +} + +int reftable_buf_setlen(struct reftable_buf *buf, size_t len) +{ + if (len > buf->len) + return -1; + if (len == buf->len) + return 0; + buf->buf[len] = '\0'; + buf->len = len; + return 0; +} + +int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b) +{ + size_t len = a->len < b->len ? a->len : b->len; + if (len) { + int cmp = memcmp(a->buf, b->buf, len); + if (cmp) + return cmp; + } + return a->len < b->len ? -1 : a->len != b->len; +} + +int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len) +{ + size_t newlen = buf->len + len; + + if (newlen + 1 > buf->alloc) { + if (REFTABLE_ALLOC_GROW(buf->buf, newlen + 1, buf->alloc)) + return REFTABLE_OUT_OF_MEMORY_ERROR; + } + + memcpy(buf->buf + buf->len, data, len); + buf->buf[newlen] = '\0'; + buf->len = newlen; + + return 0; +} + +int reftable_buf_addstr(struct reftable_buf *buf, const char *s) +{ + return reftable_buf_add(buf, s, strlen(s)); +} + +char *reftable_buf_detach(struct reftable_buf *buf) +{ + char *result = buf->buf; + reftable_buf_init(buf); + return result; +} void put_be24(uint8_t *out, uint32_t i) { @@ -75,14 +214,14 @@ size_t names_length(const char **names) return p - names; } -void parse_names(char *buf, int size, char ***namesp) +char **parse_names(char *buf, int size) { char **names = NULL; size_t names_cap = 0; size_t names_len = 0; - char *p = buf; char *end = buf + size; + while (p < end) { char *next = strchr(p, '\n'); if (next && next < end) { @@ -91,15 +230,28 @@ void parse_names(char *buf, int size, char ***namesp) next = end; } if (p < next) { - REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap); - names[names_len++] = xstrdup(p); + if (REFTABLE_ALLOC_GROW(names, names_len + 1, + names_cap)) + goto err; + + names[names_len] = reftable_strdup(p); + if (!names[names_len++]) + goto err; } p = next + 1; } - REFTABLE_REALLOC_ARRAY(names, names_len + 1); + if (REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap)) + goto err; names[names_len] = NULL; - *namesp = names; + + return names; + +err: + for (size_t i = 0; i < names_len; i++) + reftable_free(names[i]); + reftable_free(names); + return NULL; } int names_equal(const char **a, const char **b) @@ -111,13 +263,24 @@ int names_equal(const char **a, const char **b) return a[i] == b[i]; } -int common_prefix_size(struct strbuf *a, struct strbuf *b) +size_t common_prefix_size(struct reftable_buf *a, struct reftable_buf *b) { - int p = 0; - for (; p < a->len && p < b->len; p++) { + size_t p = 0; + for (; p < a->len && p < b->len; p++) if (a->buf[p] != b->buf[p]) break; - } - return p; } + +uint32_t hash_size(enum reftable_hash id) +{ + if (!id) + return REFTABLE_HASH_SIZE_SHA1; + switch (id) { + case REFTABLE_HASH_SHA1: + return REFTABLE_HASH_SIZE_SHA1; + case REFTABLE_HASH_SHA256: + return REFTABLE_HASH_SIZE_SHA256; + } + abort(); +} diff --git a/reftable/basics.h b/reftable/basics.h index c8fec68d4e887e..a2a010a0e199ba 100644 --- a/reftable/basics.h +++ b/reftable/basics.h @@ -14,6 +14,65 @@ license that can be found in the LICENSE file or at */ #include "system.h" +#include "reftable-basics.h" + +struct reftable_buf { + size_t alloc; + size_t len; + char *buf; +}; +#define REFTABLE_BUF_INIT { 0 } + +/* + * Initialize the buffer such that it is ready for use. This is equivalent to + * using REFTABLE_BUF_INIT for stack-allocated variables. + */ +void reftable_buf_init(struct reftable_buf *buf); + +/* + * Release memory associated with the buffer. The buffer is reinitialized such + * that it can be reused for subsequent operations. + */ +void reftable_buf_release(struct reftable_buf *buf); + +/* + * Reset the buffer such that it is effectively empty, without releasing the + * memory that this structure holds on to. This is equivalent to calling + * `reftable_buf_setlen(buf, 0)`. + */ +void reftable_buf_reset(struct reftable_buf *buf); + +/* + * Trim the buffer to a shorter length by updating the `len` member and writing + * a NUL byte to `buf[len]`. Returns 0 on success, -1 when `len` points outside + * of the array. + */ +int reftable_buf_setlen(struct reftable_buf *buf, size_t len); + +/* + * Lexicographically compare the two buffers. Returns 0 when both buffers have + * the same contents, -1 when `a` is lexicographically smaller than `b`, and 1 + * otherwise. + */ +int reftable_buf_cmp(const struct reftable_buf *a, const struct reftable_buf *b); + +/* + * Append `len` bytes from `data` to the buffer. This function works with + * arbitrary byte sequences, including ones that contain embedded NUL + * characters. As such, we use `void *` as input type. Returns 0 on success, + * REFTABLE_OUT_OF_MEMORY_ERROR on allocation failure. + */ +int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len); + +/* Equivalent to `reftable_buf_add(buf, s, strlen(s))`. */ +int reftable_buf_addstr(struct reftable_buf *buf, const char *s); + +/* + * Detach the buffer from the structure such that the underlying memory is now + * owned by the caller. The buffer is reinitialized such that it can be reused + * for subsequent operations. + */ +char *reftable_buf_detach(struct reftable_buf *buf); /* Bigendian en/decoding of integers */ @@ -37,9 +96,12 @@ size_t binsearch(size_t sz, int (*f)(size_t k, void *args), void *args); */ void free_names(char **a); -/* parse a newline separated list of names. `size` is the length of the buffer, - * without terminating '\0'. Empty names are discarded. */ -void parse_names(char *buf, int size, char ***namesp); +/* + * Parse a newline separated list of names. `size` is the length of the buffer, + * without terminating '\0'. Empty names are discarded. Returns a `NULL` + * pointer when allocations fail. + */ +char **parse_names(char *buf, int size); /* compares two NULL-terminated arrays of strings. */ int names_equal(const char **a, const char **b); @@ -53,22 +115,70 @@ void *reftable_malloc(size_t sz); void *reftable_realloc(void *p, size_t sz); void reftable_free(void *p); void *reftable_calloc(size_t nelem, size_t elsize); +char *reftable_strdup(const char *str); #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) + +static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize, + size_t *allocp) +{ + void *new_p; + size_t alloc = *allocp * 2 + 1; + if (alloc < nelem) + alloc = nelem; + new_p = reftable_realloc(p, st_mult(elsize, alloc)); + if (!new_p) + return p; + *allocp = alloc; + return new_p; +} + +#define REFTABLE_ALLOC_GROW(x, nr, alloc) ( \ + (nr) > (alloc) && ( \ + (x) = reftable_alloc_grow((x), (nr), sizeof(*(x)), &(alloc)), \ + (nr) > (alloc) \ + ) \ +) + +#define REFTABLE_ALLOC_GROW_OR_NULL(x, nr, alloc) do { \ + size_t reftable_alloc_grow_or_null_alloc = alloc; \ + if (REFTABLE_ALLOC_GROW((x), (nr), reftable_alloc_grow_or_null_alloc)) { \ + REFTABLE_FREE_AND_NULL(x); \ + alloc = 0; \ + } else { \ + alloc = reftable_alloc_grow_or_null_alloc; \ + } \ +} while (0) + +#define REFTABLE_FREE_AND_NULL(p) do { reftable_free(p); (p) = NULL; } while (0) + +#ifndef REFTABLE_ALLOW_BANNED_ALLOCATORS +# define REFTABLE_BANNED(func) use_reftable_##func##_instead +# undef malloc +# define malloc(sz) REFTABLE_BANNED(malloc) +# undef realloc +# define realloc(ptr, sz) REFTABLE_BANNED(realloc) +# undef free +# define free(ptr) REFTABLE_BANNED(free) +# undef calloc +# define calloc(nelem, elsize) REFTABLE_BANNED(calloc) +# undef strdup +# define strdup(str) REFTABLE_BANNED(strdup) +#endif /* Find the longest shared prefix size of `a` and `b` */ -struct strbuf; -int common_prefix_size(struct strbuf *a, struct strbuf *b); +size_t common_prefix_size(struct reftable_buf *a, struct reftable_buf *b); + +uint32_t hash_size(enum reftable_hash id); + +/* + * Format IDs that identify the hash function used by a reftable. Note that + * these constants end up on disk and thus mustn't change. The format IDs are + * "sha1" and "s256" in big endian, respectively. + */ +#define REFTABLE_FORMAT_ID_SHA1 ((uint32_t) 0x73686131) +#define REFTABLE_FORMAT_ID_SHA256 ((uint32_t) 0x73323536) #endif diff --git a/reftable/block.c b/reftable/block.c index 00030eee065234..b14a8f1259aef1 100644 --- a/reftable/block.c +++ b/reftable/block.c @@ -13,9 +13,8 @@ license that can be found in the LICENSE file or at #include "record.h" #include "reftable-error.h" #include "system.h" -#include <zlib.h> -int header_size(int version) +size_t header_size(int version) { switch (version) { case 1: @@ -26,7 +25,7 @@ int header_size(int version) abort(); } -int footer_size(int version) +size_t footer_size(int version) { switch (version) { case 1: @@ -38,39 +37,46 @@ int footer_size(int version) } static int block_writer_register_restart(struct block_writer *w, int n, - int is_restart, struct strbuf *key) + int is_restart, struct reftable_buf *key) { - int rlen = w->restart_len; - if (rlen >= MAX_RESTARTS) { + uint32_t rlen; + int err; + + rlen = w->restart_len; + if (rlen >= MAX_RESTARTS) is_restart = 0; - } - if (is_restart) { + if (is_restart) rlen++; - } if (2 + 3 * rlen + n > w->block_size - w->next) return -1; if (is_restart) { - REFTABLE_ALLOC_GROW(w->restarts, w->restart_len + 1, w->restart_cap); + REFTABLE_ALLOC_GROW_OR_NULL(w->restarts, w->restart_len + 1, + w->restart_cap); + if (!w->restarts) + return REFTABLE_OUT_OF_MEMORY_ERROR; w->restarts[w->restart_len++] = w->next; } w->next += n; - strbuf_reset(&w->last_key); - strbuf_addbuf(&w->last_key, key); + reftable_buf_reset(&w->last_key); + err = reftable_buf_add(&w->last_key, key->buf, key->len); + if (err < 0) + return err; + w->entries++; return 0; } -void block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf, - uint32_t block_size, uint32_t header_off, int hash_size) +int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *block, + uint32_t block_size, uint32_t header_off, uint32_t hash_size) { - bw->buf = buf; + bw->block = block; bw->hash_size = hash_size; bw->block_size = block_size; bw->header_off = header_off; - bw->buf[header_off] = typ; + bw->block[header_off] = typ; bw->next = header_off + 4; bw->restart_interval = 16; bw->entries = 0; @@ -78,13 +84,17 @@ void block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf, bw->last_key.len = 0; if (!bw->zstream) { REFTABLE_CALLOC_ARRAY(bw->zstream, 1); + if (!bw->zstream) + return REFTABLE_OUT_OF_MEMORY_ERROR; deflateInit(bw->zstream, 9); } + + return 0; } uint8_t block_writer_type(struct block_writer *bw) { - return bw->buf[bw->header_off]; + return bw->block[bw->header_off]; } /* Adds the reftable_record to the block. Returns -1 if it does not fit, 0 on @@ -92,56 +102,58 @@ uint8_t block_writer_type(struct block_writer *bw) empty key. */ int block_writer_add(struct block_writer *w, struct reftable_record *rec) { - struct strbuf empty = STRBUF_INIT; - struct strbuf last = + struct reftable_buf empty = REFTABLE_BUF_INIT; + struct reftable_buf last = w->entries % w->restart_interval == 0 ? empty : w->last_key; struct string_view out = { - .buf = w->buf + w->next, + .buf = w->block + w->next, .len = w->block_size - w->next, }; - struct string_view start = out; - int is_restart = 0; - struct strbuf key = STRBUF_INIT; int n = 0; - int err = -1; + int err; + + err = reftable_record_key(rec, &w->scratch); + if (err < 0) + goto done; - reftable_record_key(rec, &key); - if (!key.len) { + if (!w->scratch.len) { err = REFTABLE_API_ERROR; goto done; } - n = reftable_encode_key(&is_restart, out, last, key, + n = reftable_encode_key(&is_restart, out, last, w->scratch, reftable_record_val_type(rec)); - if (n < 0) + if (n < 0) { + err = -1; goto done; + } string_view_consume(&out, n); n = reftable_record_encode(rec, out, w->hash_size); - if (n < 0) + if (n < 0) { + err = -1; goto done; + } string_view_consume(&out, n); err = block_writer_register_restart(w, start.len - out.len, is_restart, - &key); + &w->scratch); done: - strbuf_release(&key); return err; } int block_writer_finish(struct block_writer *w) { - int i; - for (i = 0; i < w->restart_len; i++) { - put_be24(w->buf + w->next, w->restarts[i]); + for (uint32_t i = 0; i < w->restart_len; i++) { + put_be24(w->block + w->next, w->restarts[i]); w->next += 3; } - put_be16(w->buf + w->next, w->restart_len); + put_be16(w->block + w->next, w->restart_len); w->next += 2; - put_be24(w->buf + 1 + w->header_off, w->next); + put_be24(w->block + 1 + w->header_off, w->next); /* * Log records are stored zlib-compressed. Note that the compression @@ -162,11 +174,16 @@ int block_writer_finish(struct block_writer *w) * is guaranteed to return `Z_STREAM_END`. */ compressed_len = deflateBound(w->zstream, src_len); - REFTABLE_ALLOC_GROW(w->compressed, compressed_len, w->compressed_cap); + REFTABLE_ALLOC_GROW_OR_NULL(w->compressed, compressed_len, + w->compressed_cap); + if (!w->compressed) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + return ret; + } w->zstream->next_out = w->compressed; w->zstream->avail_out = compressed_len; - w->zstream->next_in = w->buf + block_header_skip; + w->zstream->next_in = w->block + block_header_skip; w->zstream->avail_in = src_len; /* @@ -184,7 +201,7 @@ int block_writer_finish(struct block_writer *w) * adjust the `next` pointer to point right after the * compressed data. */ - memcpy(w->buf + block_header_skip, w->compressed, + memcpy(w->block + block_header_skip, w->compressed, w->zstream->total_out); w->next = w->zstream->total_out + block_header_skip; } @@ -194,7 +211,7 @@ int block_writer_finish(struct block_writer *w) int block_reader_init(struct block_reader *br, struct reftable_block *block, uint32_t header_off, uint32_t table_block_size, - int hash_size) + uint32_t hash_size) { uint32_t full_block_size = table_block_size; uint8_t typ = block->data[header_off]; @@ -217,14 +234,23 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block, uLong src_len = block->len - block_header_skip; /* Log blocks specify the *uncompressed* size in their header. */ - REFTABLE_ALLOC_GROW(br->uncompressed_data, sz, - br->uncompressed_cap); + REFTABLE_ALLOC_GROW_OR_NULL(br->uncompressed_data, sz, + br->uncompressed_cap); + if (!br->uncompressed_data) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } /* Copy over the block header verbatim. It's not compressed. */ memcpy(br->uncompressed_data, block->data, block_header_skip); if (!br->zstream) { REFTABLE_CALLOC_ARRAY(br->zstream, 1); + if (!br->zstream) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + err = inflateInit(br->zstream); } else { err = inflateReset(br->zstream); @@ -306,7 +332,7 @@ uint8_t block_reader_type(const struct block_reader *r) return r->block.data[r->header_off]; } -int block_reader_first_key(const struct block_reader *br, struct strbuf *key) +int block_reader_first_key(const struct block_reader *br, struct reftable_buf *key) { int off = br->header_off + 4, n; struct string_view in = { @@ -315,7 +341,7 @@ int block_reader_first_key(const struct block_reader *br, struct strbuf *key) }; uint8_t extra = 0; - strbuf_reset(key); + reftable_buf_reset(key); n = reftable_decode_key(key, &extra, in); if (n < 0) @@ -336,13 +362,13 @@ void block_iter_seek_start(struct block_iter *it, const struct block_reader *br) it->block = br->block.data; it->block_len = br->block_len; it->hash_size = br->hash_size; - strbuf_reset(&it->last_key); + reftable_buf_reset(&it->last_key); it->next_off = br->header_off + 4; } struct restart_needle_less_args { int error; - struct strbuf needle; + struct reftable_buf needle; const struct block_reader *reader; }; @@ -414,7 +440,7 @@ int block_iter_next(struct block_iter *it, struct reftable_record *rec) void block_iter_reset(struct block_iter *it) { - strbuf_reset(&it->last_key); + reftable_buf_reset(&it->last_key); it->next_off = 0; it->block = NULL; it->block_len = 0; @@ -423,12 +449,12 @@ void block_iter_reset(struct block_iter *it) void block_iter_close(struct block_iter *it) { - strbuf_release(&it->last_key); - strbuf_release(&it->scratch); + reftable_buf_release(&it->last_key); + reftable_buf_release(&it->scratch); } int block_iter_seek_key(struct block_iter *it, const struct block_reader *br, - struct strbuf *want) + struct reftable_buf *want) { struct restart_needle_less_args args = { .needle = *want, @@ -503,6 +529,10 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br, goto done; } + err = reftable_record_key(&rec, &it->last_key); + if (err < 0) + goto done; + /* * Check whether the current key is greater or equal to the * sought-after key. In case it is greater we know that the @@ -517,8 +547,7 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br, * to `last_key` now, and naturally all keys share a prefix * with themselves. */ - reftable_record_key(&rec, &it->last_key); - if (strbuf_cmp(&it->last_key, want) >= 0) { + if (reftable_buf_cmp(&it->last_key, want) >= 0) { it->next_off = prev_off; goto done; } @@ -532,10 +561,11 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br, void block_writer_release(struct block_writer *bw) { deflateEnd(bw->zstream); - FREE_AND_NULL(bw->zstream); - FREE_AND_NULL(bw->restarts); - FREE_AND_NULL(bw->compressed); - strbuf_release(&bw->last_key); + REFTABLE_FREE_AND_NULL(bw->zstream); + REFTABLE_FREE_AND_NULL(bw->restarts); + REFTABLE_FREE_AND_NULL(bw->compressed); + reftable_buf_release(&bw->scratch); + reftable_buf_release(&bw->last_key); /* the block is not owned. */ } diff --git a/reftable/block.h b/reftable/block.h index 1c8f25ee6eb6e5..bef2b8a4c5c31e 100644 --- a/reftable/block.h +++ b/reftable/block.h @@ -22,7 +22,7 @@ struct block_writer { unsigned char *compressed; size_t compressed_cap; - uint8_t *buf; + uint8_t *block; uint32_t block_size; /* Offset of the global header. Nonzero in the first block only. */ @@ -30,7 +30,7 @@ struct block_writer { /* How often to restart keys. */ uint16_t restart_interval; - int hash_size; + uint32_t hash_size; /* Offset of next uint8_t to write. */ uint32_t next; @@ -38,15 +38,17 @@ struct block_writer { uint32_t restart_len; uint32_t restart_cap; - struct strbuf last_key; + struct reftable_buf last_key; + /* Scratch buffer used to avoid allocations. */ + struct reftable_buf scratch; int entries; }; /* - * initializes the blockwriter to write `typ` entries, using `buf` as temporary - * storage. `buf` is not owned by the block_writer. */ -void block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf, - uint32_t block_size, uint32_t header_off, int hash_size); + * initializes the blockwriter to write `typ` entries, using `block` as temporary + * storage. `block` is not owned by the block_writer. */ +int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *block, + uint32_t block_size, uint32_t header_off, uint32_t hash_size); /* returns the block type (eg. 'r' for ref records. */ uint8_t block_writer_type(struct block_writer *bw); @@ -70,7 +72,7 @@ struct block_reader { /* the memory block */ struct reftable_block block; - int hash_size; + uint32_t hash_size; /* Uncompressed data for log entries. */ z_stream *zstream; @@ -90,7 +92,7 @@ struct block_reader { /* 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, - int hash_size); + uint32_t hash_size); void block_reader_release(struct block_reader *br); @@ -98,7 +100,7 @@ void block_reader_release(struct block_reader *br); uint8_t block_reader_type(const struct block_reader *r); /* Decodes the first key in the block */ -int block_reader_first_key(const struct block_reader *br, struct strbuf *key); +int block_reader_first_key(const struct block_reader *br, struct reftable_buf *key); /* Iterate over entries in a block */ struct block_iter { @@ -106,16 +108,16 @@ struct block_iter { uint32_t next_off; const unsigned char *block; size_t block_len; - int hash_size; + uint32_t hash_size; /* key for last entry we read. */ - struct strbuf last_key; - struct strbuf scratch; + struct reftable_buf last_key; + struct reftable_buf scratch; }; #define BLOCK_ITER_INIT { \ - .last_key = STRBUF_INIT, \ - .scratch = STRBUF_INIT, \ + .last_key = REFTABLE_BUF_INIT, \ + .scratch = REFTABLE_BUF_INIT, \ } /* Position `it` at start of the block */ @@ -123,7 +125,7 @@ void block_iter_seek_start(struct block_iter *it, const struct block_reader *br) /* Position `it` to the `want` key in the block */ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br, - struct strbuf *want); + struct reftable_buf *want); /* return < 0 for error, 0 for OK, > 0 for EOF. */ int block_iter_next(struct block_iter *it, struct reftable_record *rec); @@ -135,10 +137,10 @@ void block_iter_reset(struct block_iter *it); void block_iter_close(struct block_iter *it); /* size of file header, depending on format version */ -int header_size(int version); +size_t header_size(int version); /* size of file footer, depending on format version */ -int footer_size(int version); +size_t footer_size(int version); /* returns a block to its source. */ void reftable_block_done(struct reftable_block *ret); diff --git a/reftable/blocksource.c b/reftable/blocksource.c index e93cac9bb6fbc1..bba4a45b98ab04 100644 --- a/reftable/blocksource.c +++ b/reftable/blocksource.c @@ -13,45 +13,47 @@ license that can be found in the LICENSE file or at #include "reftable-blocksource.h" #include "reftable-error.h" -static void strbuf_return_block(void *b UNUSED, struct reftable_block *dest) +static void reftable_buf_return_block(void *b UNUSED, struct reftable_block *dest) { if (dest->len) memset(dest->data, 0xff, dest->len); reftable_free(dest->data); } -static void strbuf_close(void *b UNUSED) +static void reftable_buf_close(void *b UNUSED) { } -static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off, - uint32_t size) +static ssize_t reftable_buf_read_block(void *v, struct reftable_block *dest, + uint64_t off, uint32_t size) { - struct strbuf *b = v; + struct reftable_buf *b = v; assert(off + size <= b->len); REFTABLE_CALLOC_ARRAY(dest->data, size); + if (!dest->data) + return -1; memcpy(dest->data, b->buf + off, size); dest->len = size; return size; } -static uint64_t strbuf_size(void *b) +static uint64_t reftable_buf_size(void *b) { - return ((struct strbuf *)b)->len; + return ((struct reftable_buf *)b)->len; } -static struct reftable_block_source_vtable strbuf_vtable = { - .size = &strbuf_size, - .read_block = &strbuf_read_block, - .return_block = &strbuf_return_block, - .close = &strbuf_close, +static struct reftable_block_source_vtable reftable_buf_vtable = { + .size = &reftable_buf_size, + .read_block = &reftable_buf_read_block, + .return_block = &reftable_buf_return_block, + .close = &reftable_buf_close, }; -void block_source_from_strbuf(struct reftable_block_source *bs, - struct strbuf *buf) +void block_source_from_buf(struct reftable_block_source *bs, + struct reftable_buf *buf) { assert(!bs->ops); - bs->ops = &strbuf_vtable; + bs->ops = &reftable_buf_vtable; bs->arg = buf; } @@ -76,8 +78,8 @@ static void file_close(void *v) reftable_free(b); } -static int file_read_block(void *v, struct reftable_block *dest, uint64_t off, - uint32_t size) +static ssize_t file_read_block(void *v, struct reftable_block *dest, uint64_t off, + uint32_t size) { struct file_block_source *b = v; assert(off + size <= b->size); @@ -98,27 +100,40 @@ int reftable_block_source_from_file(struct reftable_block_source *bs, { struct file_block_source *p; struct stat st; - int fd; + int fd, err; fd = open(name, O_RDONLY); if (fd < 0) { if (errno == ENOENT) return REFTABLE_NOT_EXIST_ERROR; - return -1; + err = -1; + goto out; } if (fstat(fd, &st) < 0) { - close(fd); - return REFTABLE_IO_ERROR; + err = REFTABLE_IO_ERROR; + goto out; } REFTABLE_CALLOC_ARRAY(p, 1); + if (!p) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + p->size = st.st_size; p->data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); assert(!bs->ops); bs->ops = &file_vtable; bs->arg = p; + + err = 0; + +out: + if (fd >= 0) + close(fd); + if (err < 0) + reftable_free(p); return 0; } diff --git a/reftable/blocksource.h b/reftable/blocksource.h index 659a27b4063e40..a84a3ccd891d64 100644 --- a/reftable/blocksource.h +++ b/reftable/blocksource.h @@ -12,9 +12,10 @@ license that can be found in the LICENSE file or at #include "system.h" struct reftable_block_source; +struct reftable_buf; /* Create an in-memory block source for reading reftables */ -void block_source_from_strbuf(struct reftable_block_source *bs, - struct strbuf *buf); +void block_source_from_buf(struct reftable_block_source *bs, + struct reftable_buf *buf); #endif diff --git a/reftable/error.c b/reftable/error.c index a25f28a43ebab2..660d0296170d39 100644 --- a/reftable/error.c +++ b/reftable/error.c @@ -35,6 +35,8 @@ const char *reftable_error_str(int err) return "entry too large"; case REFTABLE_OUTDATED_ERROR: return "data concurrently modified"; + case REFTABLE_OUT_OF_MEMORY_ERROR: + return "out of memory"; case -1: return "general error"; default: diff --git a/reftable/iter.c b/reftable/iter.c index 416a9f6996bac0..86e801ca9fbc6b 100644 --- a/reftable/iter.c +++ b/reftable/iter.c @@ -55,7 +55,7 @@ void iterator_set_empty(struct reftable_iterator *it) static void filtering_ref_iterator_close(void *iter_arg) { struct filtering_ref_iterator *fri = iter_arg; - strbuf_release(&fri->oid); + reftable_buf_release(&fri->oid); reftable_iterator_destroy(&fri->it); } @@ -115,7 +115,7 @@ static void indexed_table_ref_iter_close(void *p) block_iter_close(&it->cur); reftable_block_done(&it->block_reader.block); reftable_free(it->offsets); - strbuf_release(&it->oid); + reftable_buf_release(&it->oid); } static int indexed_table_ref_iter_next_block(struct indexed_table_ref_iter *it) @@ -181,26 +181,41 @@ static int indexed_table_ref_iter_next(void *p, struct reftable_record *rec) } } -int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest, +int indexed_table_ref_iter_new(struct indexed_table_ref_iter **dest, struct reftable_reader *r, uint8_t *oid, 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(1, sizeof(*itr)); + struct indexed_table_ref_iter *itr; int err = 0; + itr = reftable_calloc(1, sizeof(*itr)); + if (!itr) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + *itr = empty; itr->r = r; - strbuf_add(&itr->oid, oid, oid_len); + + err = reftable_buf_add(&itr->oid, oid, oid_len); + if (err < 0) + goto out; itr->offsets = offsets; itr->offset_len = offset_len; err = indexed_table_ref_iter_next_block(itr); + if (err < 0) + goto out; + + *dest = itr; + err = 0; + +out: if (err < 0) { + *dest = NULL; reftable_free(itr); - } else { - *dest = itr; } return err; } @@ -225,7 +240,7 @@ void reftable_iterator_destroy(struct reftable_iterator *it) return; it->ops->close(it->iter_arg); it->ops = NULL; - FREE_AND_NULL(it->iter_arg); + REFTABLE_FREE_AND_NULL(it->iter_arg); } int reftable_iterator_seek_ref(struct reftable_iterator *it, diff --git a/reftable/iter.h b/reftable/iter.h index befc4597df14c9..40f98893b85f6d 100644 --- a/reftable/iter.h +++ b/reftable/iter.h @@ -44,12 +44,12 @@ void iterator_set_empty(struct reftable_iterator *it); /* iterator that produces only ref records that point to `oid` */ struct filtering_ref_iterator { - struct strbuf oid; + struct reftable_buf oid; struct reftable_iterator it; }; #define FILTERING_REF_ITERATOR_INIT \ { \ - .oid = STRBUF_INIT \ + .oid = REFTABLE_BUF_INIT \ } void iterator_from_filtering_ref_iterator(struct reftable_iterator *, @@ -60,7 +60,7 @@ void iterator_from_filtering_ref_iterator(struct reftable_iterator *, */ struct indexed_table_ref_iter { struct reftable_reader *r; - struct strbuf oid; + struct reftable_buf oid; /* mutable */ uint64_t *offsets; @@ -75,14 +75,14 @@ struct indexed_table_ref_iter { #define INDEXED_TABLE_REF_ITER_INIT { \ .cur = BLOCK_ITER_INIT, \ - .oid = STRBUF_INIT, \ + .oid = REFTABLE_BUF_INIT, \ } void iterator_from_indexed_table_ref_iter(struct reftable_iterator *it, struct indexed_table_ref_iter *itr); /* Takes ownership of `offsets` */ -int new_indexed_table_ref_iter(struct indexed_table_ref_iter **dest, +int indexed_table_ref_iter_new(struct indexed_table_ref_iter **dest, struct reftable_reader *r, uint8_t *oid, int oid_len, uint64_t *offsets, int offset_len); diff --git a/reftable/merged.c b/reftable/merged.c index 128a810c55dd07..e72b39e178d4de 100644 --- a/reftable/merged.c +++ b/reftable/merged.c @@ -30,22 +30,6 @@ struct merged_iter { ssize_t advance_index; }; -static void merged_iter_init(struct merged_iter *mi, - struct reftable_merged_table *mt, - uint8_t typ) -{ - memset(mi, 0, sizeof(*mi)); - mi->advance_index = -1; - mi->suppress_deletions = mt->suppress_deletions; - - REFTABLE_CALLOC_ARRAY(mi->subiters, mt->readers_len); - for (size_t i = 0; i < mt->readers_len; i++) { - reftable_record_init(&mi->subiters[i].rec, typ); - reader_init_iter(mt->readers[i], &mi->subiters[i].iter, typ); - } - mi->subiters_len = mt->readers_len; -} - static void merged_iter_close(void *p) { struct merged_iter *mi = p; @@ -70,7 +54,10 @@ static int merged_iter_advance_subiter(struct merged_iter *mi, size_t idx) if (err) return err; - merged_iter_pqueue_add(&mi->pq, &e); + err = merged_iter_pqueue_add(&mi->pq, &e); + if (err) + return err; + return 0; } @@ -79,6 +66,8 @@ static int merged_iter_seek(struct merged_iter *mi, struct reftable_record *want int err; mi->advance_index = -1; + while (!merged_iter_pqueue_is_empty(mi->pq)) + merged_iter_pqueue_remove(&mi->pq); for (size_t i = 0; i < mi->subiters_len; i++) { err = iterator_seek(&mi->subiters[i].iter, want); @@ -194,7 +183,7 @@ static void iterator_from_merged_iter(struct reftable_iterator *it, int reftable_merged_table_new(struct reftable_merged_table **dest, struct reftable_reader **readers, size_t n, - uint32_t hash_id) + enum reftable_hash hash_id) { struct reftable_merged_table *m = NULL; uint64_t last_max = 0; @@ -216,6 +205,9 @@ int reftable_merged_table_new(struct reftable_merged_table **dest, } REFTABLE_CALLOC_ARRAY(m, 1); + if (!m) + return REFTABLE_OUT_OF_MEMORY_ERROR; + m->readers = readers; m->readers_len = n; m->min = first_min; @@ -244,28 +236,68 @@ reftable_merged_table_min_update_index(struct reftable_merged_table *mt) return mt->min; } -void merged_table_init_iter(struct reftable_merged_table *mt, - struct reftable_iterator *it, - uint8_t typ) +int merged_table_init_iter(struct reftable_merged_table *mt, + struct reftable_iterator *it, + uint8_t typ) { - struct merged_iter *mi = reftable_malloc(sizeof(*mi)); - merged_iter_init(mi, mt, typ); + struct merged_subiter *subiters = NULL; + struct merged_iter *mi = NULL; + int ret; + + if (mt->readers_len) { + REFTABLE_CALLOC_ARRAY(subiters, mt->readers_len); + if (!subiters) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + } + + for (size_t i = 0; i < mt->readers_len; i++) { + reftable_record_init(&subiters[i].rec, typ); + ret = reader_init_iter(mt->readers[i], &subiters[i].iter, typ); + if (ret < 0) + goto out; + } + + REFTABLE_CALLOC_ARRAY(mi, 1); + if (!mi) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + mi->advance_index = -1; + mi->suppress_deletions = mt->suppress_deletions; + mi->subiters = subiters; + mi->subiters_len = mt->readers_len; + iterator_from_merged_iter(it, mi); + ret = 0; + +out: + if (ret < 0) { + for (size_t i = 0; subiters && i < mt->readers_len; i++) { + reftable_iterator_destroy(&subiters[i].iter); + reftable_record_release(&subiters[i].rec); + } + reftable_free(subiters); + reftable_free(mi); + } + + return ret; } -void reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt, - struct reftable_iterator *it) +int reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt, + struct reftable_iterator *it) { - merged_table_init_iter(mt, it, BLOCK_TYPE_REF); + return merged_table_init_iter(mt, it, BLOCK_TYPE_REF); } -void reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt, - struct reftable_iterator *it) +int reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt, + struct reftable_iterator *it) { - merged_table_init_iter(mt, it, BLOCK_TYPE_LOG); + return merged_table_init_iter(mt, it, BLOCK_TYPE_LOG); } -uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *mt) +enum reftable_hash reftable_merged_table_hash_id(struct reftable_merged_table *mt) { return mt->hash_id; } diff --git a/reftable/merged.h b/reftable/merged.h index de5fd33f010b1b..0b7d939e92b0d9 100644 --- a/reftable/merged.h +++ b/reftable/merged.h @@ -10,11 +10,12 @@ license that can be found in the LICENSE file or at #define MERGED_H #include "system.h" +#include "reftable-basics.h" struct reftable_merged_table { struct reftable_reader **readers; size_t readers_len; - uint32_t hash_id; + enum reftable_hash hash_id; /* If unset, produce deletions. This is useful for compaction. For the * full stack, deletions should be produced. */ @@ -26,8 +27,8 @@ struct reftable_merged_table { struct reftable_iterator; -void merged_table_init_iter(struct reftable_merged_table *mt, - struct reftable_iterator *it, - uint8_t typ); +int merged_table_init_iter(struct reftable_merged_table *mt, + struct reftable_iterator *it, + uint8_t typ); #endif diff --git a/reftable/pq.c b/reftable/pq.c index 2b5b7d1c0e2866..5591e875e1e845 100644 --- a/reftable/pq.c +++ b/reftable/pq.c @@ -8,6 +8,7 @@ license that can be found in the LICENSE file or at #include "pq.h" +#include "reftable-error.h" #include "reftable-record.h" #include "system.h" #include "basics.h" @@ -44,11 +45,13 @@ struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq) return e; } -void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e) +int merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e) { size_t i = 0; - REFTABLE_ALLOC_GROW(pq->heap, pq->len + 1, pq->cap); + REFTABLE_ALLOC_GROW_OR_NULL(pq->heap, pq->len + 1, pq->cap); + if (!pq->heap) + return REFTABLE_OUT_OF_MEMORY_ERROR; pq->heap[pq->len++] = *e; i = pq->len - 1; @@ -59,10 +62,12 @@ void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry SWAP(pq->heap[j], pq->heap[i]); i = j; } + + return 0; } void merged_iter_pqueue_release(struct merged_iter_pqueue *pq) { - FREE_AND_NULL(pq->heap); + REFTABLE_FREE_AND_NULL(pq->heap); memset(pq, 0, sizeof(*pq)); } diff --git a/reftable/pq.h b/reftable/pq.h index 707bd26767bd11..83c062eecac9f2 100644 --- a/reftable/pq.h +++ b/reftable/pq.h @@ -23,7 +23,7 @@ struct merged_iter_pqueue { }; struct pq_entry merged_iter_pqueue_remove(struct merged_iter_pqueue *pq); -void merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e); +int merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry *e); void merged_iter_pqueue_release(struct merged_iter_pqueue *pq); int pq_less(struct pq_entry *a, struct pq_entry *b); diff --git a/reftable/publicbasics.c b/reftable/publicbasics.c deleted file mode 100644 index 44b84a125e43b3..00000000000000 --- a/reftable/publicbasics.c +++ /dev/null @@ -1,66 +0,0 @@ -/* -Copyright 2020 Google LLC - -Use of this source code is governed by a BSD-style -license that can be found in the LICENSE file or at -https://developers.google.com/open-source/licenses/bsd -*/ - -#include "system.h" -#include "reftable-malloc.h" - -#include "basics.h" - -static void *(*reftable_malloc_ptr)(size_t sz); -static void *(*reftable_realloc_ptr)(void *, size_t); -static void (*reftable_free_ptr)(void *); - -void *reftable_malloc(size_t sz) -{ - if (reftable_malloc_ptr) - return (*reftable_malloc_ptr)(sz); - return malloc(sz); -} - -void *reftable_realloc(void *p, size_t sz) -{ - if (reftable_realloc_ptr) - return (*reftable_realloc_ptr)(p, sz); - return realloc(p, sz); -} - -void reftable_free(void *p) -{ - if (reftable_free_ptr) - reftable_free_ptr(p); - else - free(p); -} - -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; -} - -void reftable_set_alloc(void *(*malloc)(size_t), - void *(*realloc)(void *, size_t), void (*free)(void *)) -{ - reftable_malloc_ptr = malloc; - reftable_realloc_ptr = realloc; - reftable_free_ptr = free; -} - -int hash_size(uint32_t id) -{ - switch (id) { - case 0: - case GIT_SHA1_FORMAT_ID: - return GIT_SHA1_RAWSZ; - case GIT_SHA256_FORMAT_ID: - return GIT_SHA256_RAWSZ; - } - abort(); -} diff --git a/reftable/reader.c b/reftable/reader.c index 6494ce2e32705e..24bae50ac2fab3 100644 --- a/reftable/reader.c +++ b/reftable/reader.c @@ -20,11 +20,11 @@ uint64_t block_source_size(struct reftable_block_source *source) return source->ops->size(source->arg); } -int block_source_read_block(struct reftable_block_source *source, - struct reftable_block *dest, uint64_t off, - uint32_t size) +ssize_t block_source_read_block(struct reftable_block_source *source, + struct reftable_block *dest, uint64_t off, + uint32_t size) { - int result = source->ops->read_block(source->arg, dest, off, size); + ssize_t result = source->ops->read_block(source->arg, dest, off, size); dest->source = *source; return result; } @@ -57,17 +57,20 @@ static int reader_get_block(struct reftable_reader *r, struct reftable_block *dest, uint64_t off, uint32_t sz) { + ssize_t bytes_read; if (off >= r->size) return 0; - - if (off + sz > r->size) { + if (off + sz > r->size) sz = r->size - off; - } - return block_source_read_block(&r->source, dest, off, sz); + bytes_read = block_source_read_block(&r->source, dest, off, sz); + if (bytes_read < 0) + return (int)bytes_read; + + return 0; } -uint32_t reftable_reader_hash_id(struct reftable_reader *r) +enum reftable_hash reftable_reader_hash_id(struct reftable_reader *r) { return r->hash_id; } @@ -107,18 +110,20 @@ static int parse_footer(struct reftable_reader *r, uint8_t *footer, f += 8; if (r->version == 1) { - r->hash_id = GIT_SHA1_FORMAT_ID; + r->hash_id = REFTABLE_HASH_SHA1; } else { - r->hash_id = get_be32(f); - switch (r->hash_id) { - case GIT_SHA1_FORMAT_ID: + switch (get_be32(f)) { + case REFTABLE_FORMAT_ID_SHA1: + r->hash_id = REFTABLE_HASH_SHA1; break; - case GIT_SHA256_FORMAT_ID: + case REFTABLE_FORMAT_ID_SHA256: + r->hash_id = REFTABLE_HASH_SHA256; break; default: err = REFTABLE_FORMAT_ERROR; goto done; } + f += 4; } @@ -350,13 +355,15 @@ static int table_iter_seek_start(struct table_iter *ti, uint8_t typ, int index) static int table_iter_seek_linear(struct table_iter *ti, struct reftable_record *want) { - struct strbuf want_key = STRBUF_INIT; - struct strbuf got_key = STRBUF_INIT; + struct reftable_buf want_key = REFTABLE_BUF_INIT; + struct reftable_buf got_key = REFTABLE_BUF_INIT; struct reftable_record rec; int err; reftable_record_init(&rec, reftable_record_type(want)); - reftable_record_key(want, &want_key); + err = reftable_record_key(want, &want_key); + if (err < 0) + goto done; /* * First we need to locate the block that must contain our record. To @@ -401,7 +408,7 @@ static int table_iter_seek_linear(struct table_iter *ti, if (err < 0) goto done; - if (strbuf_cmp(&got_key, &want_key) > 0) { + if (reftable_buf_cmp(&got_key, &want_key) > 0) { table_iter_block_done(&next); break; } @@ -422,8 +429,8 @@ static int table_iter_seek_linear(struct table_iter *ti, done: reftable_record_release(&rec); - strbuf_release(&want_key); - strbuf_release(&got_key); + reftable_buf_release(&want_key); + reftable_buf_release(&got_key); return err; } @@ -431,15 +438,17 @@ static int table_iter_seek_indexed(struct table_iter *ti, struct reftable_record *rec) { struct reftable_record want_index = { - .type = BLOCK_TYPE_INDEX, .u.idx = { .last_key = STRBUF_INIT } + .type = BLOCK_TYPE_INDEX, .u.idx = { .last_key = REFTABLE_BUF_INIT } }; struct reftable_record index_result = { .type = BLOCK_TYPE_INDEX, - .u.idx = { .last_key = STRBUF_INIT }, + .u.idx = { .last_key = REFTABLE_BUF_INIT }, }; int err; - reftable_record_key(rec, &want_index.u.idx.last_key); + err = reftable_record_key(rec, &want_index.u.idx.last_key); + if (err < 0) + goto done; /* * The index may consist of multiple levels, where each level may have @@ -554,32 +563,37 @@ static void iterator_from_table_iter(struct reftable_iterator *it, it->ops = &table_iter_vtable; } -void reader_init_iter(struct reftable_reader *r, - struct reftable_iterator *it, - uint8_t typ) +int reader_init_iter(struct reftable_reader *r, + struct reftable_iterator *it, + uint8_t typ) { struct reftable_reader_offsets *offs = reader_offsets_for(r, typ); if (offs->is_present) { struct table_iter *ti; REFTABLE_ALLOC_ARRAY(ti, 1); + if (!ti) + return REFTABLE_OUT_OF_MEMORY_ERROR; + table_iter_init(ti, r); iterator_from_table_iter(it, ti); } else { iterator_set_empty(it); } + + return 0; } -void reftable_reader_init_ref_iterator(struct reftable_reader *r, - struct reftable_iterator *it) +int reftable_reader_init_ref_iterator(struct reftable_reader *r, + struct reftable_iterator *it) { - reader_init_iter(r, it, BLOCK_TYPE_REF); + return reader_init_iter(r, it, BLOCK_TYPE_REF); } -void reftable_reader_init_log_iterator(struct reftable_reader *r, - struct reftable_iterator *it) +int reftable_reader_init_log_iterator(struct reftable_reader *r, + struct reftable_iterator *it) { - reader_init_iter(r, it, BLOCK_TYPE_LOG); + return reader_init_iter(r, it, BLOCK_TYPE_LOG); } int reftable_reader_new(struct reftable_reader **out, @@ -590,9 +604,14 @@ int reftable_reader_new(struct reftable_reader **out, struct reftable_reader *r; uint64_t file_size = block_source_size(source); uint32_t read_size; + ssize_t bytes_read; int err; REFTABLE_CALLOC_ARRAY(r, 1); + if (!r) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } /* * We need one extra byte to read the type of first block. We also @@ -604,8 +623,8 @@ int reftable_reader_new(struct reftable_reader **out, goto done; } - err = block_source_read_block(source, &header, 0, read_size); - if (err != read_size) { + bytes_read = block_source_read_block(source, &header, 0, read_size); + if (bytes_read < 0 || (size_t)bytes_read != read_size) { err = REFTABLE_IO_ERROR; goto done; } @@ -622,13 +641,17 @@ int reftable_reader_new(struct reftable_reader **out, r->size = file_size - footer_size(r->version); r->source = *source; - r->name = xstrdup(name); + r->name = reftable_strdup(name); + if (!r->name) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } r->hash_id = 0; r->refcount = 1; - err = block_source_read_block(source, &footer, r->size, - footer_size(r->version)); - if (err != footer_size(r->version)) { + bytes_read = block_source_read_block(source, &footer, r->size, + footer_size(r->version)); + if (bytes_read < 0 || (size_t)bytes_read != footer_size(r->version)) { err = REFTABLE_IO_ERROR; goto done; } @@ -643,6 +666,8 @@ int reftable_reader_new(struct reftable_reader **out, reftable_block_done(&footer); reftable_block_done(&header); if (err) { + if (r) + reftable_free(r->name); reftable_free(r); block_source_close(source); } @@ -665,7 +690,7 @@ void reftable_reader_decref(struct reftable_reader *r) if (--r->refcount) return; block_source_close(&r->source); - FREE_AND_NULL(r->name); + REFTABLE_FREE_AND_NULL(r->name); reftable_free(r); } @@ -689,7 +714,10 @@ static int reftable_reader_refs_for_indexed(struct reftable_reader *r, struct indexed_table_ref_iter *itr = NULL; /* Look through the reverse index. */ - reader_init_iter(r, &oit, BLOCK_TYPE_OBJ); + err = reader_init_iter(r, &oit, BLOCK_TYPE_OBJ); + if (err < 0) + goto done; + err = iterator_seek(&oit, &want); if (err != 0) goto done; @@ -707,7 +735,7 @@ static int reftable_reader_refs_for_indexed(struct reftable_reader *r, goto done; } - err = new_indexed_table_ref_iter(&itr, r, oid, hash_size(r->hash_id), + err = indexed_table_ref_iter_new(&itr, r, oid, hash_size(r->hash_id), got.u.obj.offsets, got.u.obj.offset_len); if (err < 0) @@ -728,25 +756,44 @@ static int reftable_reader_refs_for_unindexed(struct reftable_reader *r, struct table_iter *ti; struct filtering_ref_iterator *filter = NULL; struct filtering_ref_iterator empty = FILTERING_REF_ITERATOR_INIT; - int oid_len = hash_size(r->hash_id); + uint32_t oid_len = hash_size(r->hash_id); int err; REFTABLE_ALLOC_ARRAY(ti, 1); + if (!ti) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + table_iter_init(ti, r); err = table_iter_seek_start(ti, BLOCK_TYPE_REF, 0); - if (err < 0) { - reftable_free(ti); - return err; - } + if (err < 0) + goto out; - filter = reftable_malloc(sizeof(struct filtering_ref_iterator)); + filter = reftable_malloc(sizeof(*filter)); + if (!filter) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } *filter = empty; - strbuf_add(&filter->oid, oid, oid_len); + err = reftable_buf_add(&filter->oid, oid, oid_len); + if (err < 0) + goto out; + iterator_from_table_iter(&filter->it, ti); iterator_from_filtering_ref_iterator(it, filter); - return 0; + + err = 0; + +out: + if (err < 0) { + if (ti) + table_iter_close(ti); + reftable_free(ti); + } + return err; } int reftable_reader_refs_for(struct reftable_reader *r, diff --git a/reftable/reader.h b/reftable/reader.h index 3710ee09b4ca32..bb72108a6f1f5c 100644 --- a/reftable/reader.h +++ b/reftable/reader.h @@ -16,9 +16,9 @@ license that can be found in the LICENSE file or at uint64_t block_source_size(struct reftable_block_source *source); -int block_source_read_block(struct reftable_block_source *source, - struct reftable_block *dest, uint64_t off, - uint32_t size); +ssize_t block_source_read_block(struct reftable_block_source *source, + struct reftable_block *dest, uint64_t off, + uint32_t size); void block_source_close(struct reftable_block_source *source); /* metadata for a block type */ @@ -30,15 +30,15 @@ struct reftable_reader_offsets { /* The state for reading a reftable file. */ struct reftable_reader { - /* for convience, associate a name with the instance. */ + /* for convenience, associate a name with the instance. */ char *name; struct reftable_block_source source; /* Size of the file, excluding the footer. */ uint64_t size; - /* 'sha1' for SHA1, 's256' for SHA-256 */ - uint32_t hash_id; + /* The hash function used for ref records. */ + enum reftable_hash hash_id; uint32_t block_size; uint64_t min_update_index; @@ -56,9 +56,9 @@ struct reftable_reader { const char *reader_name(struct reftable_reader *r); -void reader_init_iter(struct reftable_reader *r, - struct reftable_iterator *it, - uint8_t typ); +int reader_init_iter(struct reftable_reader *r, + struct reftable_iterator *it, + uint8_t typ); /* initialize a block reader to read from `r` */ int reader_init_block_reader(struct reftable_reader *r, struct block_reader *br, diff --git a/reftable/record.c b/reftable/record.c index 6b5a075b921062..8919df8a4d3e3d 100644 --- a/reftable/record.c +++ b/reftable/record.c @@ -21,47 +21,49 @@ static void *reftable_record_data(struct reftable_record *rec); int get_var_int(uint64_t *dest, struct string_view *in) { - int ptr = 0; + const unsigned char *buf = in->buf; + unsigned char c; uint64_t val; - if (in->len == 0) + if (!in->len) return -1; - val = in->buf[ptr] & 0x7f; - - while (in->buf[ptr] & 0x80) { - ptr++; - if (ptr > in->len) { + c = *buf++; + val = c & 0x7f; + + while (c & 0x80) { + /* + * We use a micro-optimization here: whenever we see that the + * 0x80 bit is set, we know that the remainder of the value + * cannot be 0. The zero-values thus doesn't need to be encoded + * at all, which is why we subtract 1 when encoding and add 1 + * when decoding. + * + * This allows us to save a byte in some edge cases. + */ + val += 1; + if (!val || (val & (uint64_t)(~0ULL << (64 - 7)))) + return -1; /* overflow */ + if (buf >= in->buf + in->len) return -1; - } - val = (val + 1) << 7 | (uint64_t)(in->buf[ptr] & 0x7f); + c = *buf++; + val = (val << 7) + (c & 0x7f); } *dest = val; - return ptr + 1; + return buf - in->buf; } -int put_var_int(struct string_view *dest, uint64_t val) +int put_var_int(struct string_view *dest, uint64_t value) { - uint8_t buf[10] = { 0 }; - int i = 9; - int n = 0; - buf[i] = (uint8_t)(val & 0x7f); - i--; - while (1) { - val >>= 7; - if (!val) { - break; - } - val--; - buf[i] = 0x80 | (uint8_t)(val & 0x7f); - i--; - } - - n = sizeof(buf) - i - 1; - if (dest->len < n) + unsigned char varint[10]; + unsigned pos = sizeof(varint) - 1; + varint[pos] = value & 0x7f; + while (value >>= 7) + varint[--pos] = 0x80 | (--value & 0x7f); + if (dest->len < sizeof(varint) - pos) return -1; - memcpy(dest->buf, &buf[i + 1], n); - return n; + memcpy(dest->buf, varint + pos, sizeof(varint) - pos); + return sizeof(varint) - pos; } int reftable_is_block_type(uint8_t typ) @@ -98,19 +100,24 @@ const unsigned char *reftable_ref_record_val2(const struct reftable_ref_record * } } -static int decode_string(struct strbuf *dest, struct string_view in) +static int decode_string(struct reftable_buf *dest, struct string_view in) { int start_len = in.len; uint64_t tsize = 0; - int n = get_var_int(&tsize, &in); + int n, err; + + n = get_var_int(&tsize, &in); if (n <= 0) return -1; string_view_consume(&in, n); if (in.len < tsize) return -1; - strbuf_reset(dest); - strbuf_add(dest, in.buf, tsize); + reftable_buf_reset(dest); + err = reftable_buf_add(dest, in.buf, tsize); + if (err < 0) + return err; + string_view_consume(&in, tsize); return start_len - in.len; @@ -119,7 +126,7 @@ static int decode_string(struct strbuf *dest, struct string_view in) static int encode_string(const char *str, struct string_view s) { struct string_view start = s; - int l = strlen(str); + size_t l = strlen(str); int n = put_var_int(&s, l); if (n < 0) return -1; @@ -133,13 +140,13 @@ static int encode_string(const char *str, struct string_view s) } int reftable_encode_key(int *restart, struct string_view dest, - struct strbuf prev_key, struct strbuf key, + struct reftable_buf prev_key, struct reftable_buf key, uint8_t extra) { struct string_view start = dest; - int prefix_len = common_prefix_size(&prev_key, &key); + size_t prefix_len = common_prefix_size(&prev_key, &key); uint64_t suffix_len = key.len - prefix_len; - int n = put_var_int(&dest, (uint64_t)prefix_len); + int n = put_var_int(&dest, prefix_len); if (n < 0) return -1; string_view_consume(&dest, n); @@ -183,13 +190,13 @@ int reftable_decode_keylen(struct string_view in, return start_len - in.len; } -int reftable_decode_key(struct strbuf *last_key, uint8_t *extra, +int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra, struct string_view in) { int start_len = in.len; uint64_t prefix_len = 0; uint64_t suffix_len = 0; - int n; + int err, n; n = reftable_decode_keylen(in, &prefix_len, &suffix_len, extra); if (n < 0) @@ -200,30 +207,35 @@ int reftable_decode_key(struct strbuf *last_key, uint8_t *extra, prefix_len > last_key->len) return -1; - strbuf_setlen(last_key, prefix_len); - strbuf_add(last_key, in.buf, suffix_len); + err = reftable_buf_setlen(last_key, prefix_len); + if (err < 0) + return err; + + err = reftable_buf_add(last_key, in.buf, suffix_len); + if (err < 0) + return err; + string_view_consume(&in, suffix_len); return start_len - in.len; } -static void reftable_ref_record_key(const void *r, struct strbuf *dest) +static int reftable_ref_record_key(const void *r, struct reftable_buf *dest) { const struct reftable_ref_record *rec = (const struct reftable_ref_record *)r; - strbuf_reset(dest); - strbuf_addstr(dest, rec->refname); + reftable_buf_reset(dest); + return reftable_buf_addstr(dest, rec->refname); } -static void reftable_ref_record_copy_from(void *rec, const void *src_rec, - int hash_size) +static int reftable_ref_record_copy_from(void *rec, const void *src_rec, + uint32_t hash_size) { struct reftable_ref_record *ref = rec; const struct reftable_ref_record *src = src_rec; char *refname = NULL; size_t refname_cap = 0; - - assert(hash_size > 0); + int err; SWAP(refname, ref->refname); SWAP(refname_cap, ref->refname_cap); @@ -234,8 +246,13 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec, if (src->refname) { size_t refname_len = strlen(src->refname); - REFTABLE_ALLOC_GROW(ref->refname, refname_len + 1, - ref->refname_cap); + REFTABLE_ALLOC_GROW_OR_NULL(ref->refname, refname_len + 1, + ref->refname_cap); + if (!ref->refname) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + memcpy(ref->refname, src->refname, refname_len); ref->refname[refname_len] = 0; } @@ -254,9 +271,17 @@ static void reftable_ref_record_copy_from(void *rec, const void *src_rec, src->value.val2.target_value, hash_size); break; case REFTABLE_REF_SYMREF: - ref->value.symref = xstrdup(src->value.symref); + ref->value.symref = reftable_strdup(src->value.symref); + if (!ref->value.symref) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } break; } + + err = 0; +out: + return err; } static void reftable_ref_record_release_void(void *rec) @@ -292,13 +317,12 @@ static uint8_t reftable_ref_record_val_type(const void *rec) } static int reftable_ref_record_encode(const void *rec, struct string_view s, - int hash_size) + uint32_t hash_size) { const struct reftable_ref_record *r = (const struct reftable_ref_record *)rec; struct string_view start = s; int n = put_var_int(&s, r->update_index); - assert(hash_size > 0); if (n < 0) return -1; string_view_consume(&s, n); @@ -336,18 +360,16 @@ static int reftable_ref_record_encode(const void *rec, struct string_view s, return start.len - s.len; } -static int reftable_ref_record_decode(void *rec, struct strbuf key, +static int reftable_ref_record_decode(void *rec, struct reftable_buf key, uint8_t val_type, struct string_view in, - int hash_size, struct strbuf *scratch) + uint32_t hash_size, struct reftable_buf *scratch) { struct reftable_ref_record *r = rec; struct string_view start = in; uint64_t update_index = 0; const char *refname = NULL; size_t refname_cap = 0; - int n; - - assert(hash_size > 0); + int n, err; n = get_var_int(&update_index, &in); if (n < 0) @@ -360,7 +382,11 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, SWAP(r->refname, refname); SWAP(r->refname_cap, refname_cap); - REFTABLE_ALLOC_GROW(r->refname, key.len + 1, r->refname_cap); + REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len + 1, r->refname_cap); + if (!r->refname) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } memcpy(r->refname, key.buf, key.len); r->refname[key.len] = 0; @@ -369,7 +395,8 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, switch (val_type) { case REFTABLE_REF_VAL1: if (in.len < hash_size) { - return -1; + err = REFTABLE_FORMAT_ERROR; + goto done; } memcpy(r->value.val1, in.buf, hash_size); @@ -378,7 +405,8 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, case REFTABLE_REF_VAL2: if (in.len < 2 * hash_size) { - return -1; + err = REFTABLE_FORMAT_ERROR; + goto done; } memcpy(r->value.val2.value, in.buf, hash_size); @@ -391,10 +419,11 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, case REFTABLE_REF_SYMREF: { int n = decode_string(scratch, in); if (n < 0) { - return -1; + err = REFTABLE_FORMAT_ERROR; + goto done; } string_view_consume(&in, n); - r->value.symref = strbuf_detach(scratch, NULL); + r->value.symref = reftable_buf_detach(scratch); } break; case REFTABLE_REF_DELETION: @@ -405,6 +434,9 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, } return start.len - in.len; + +done: + return err; } static int reftable_ref_record_is_deletion_void(const void *p) @@ -414,7 +446,7 @@ static int reftable_ref_record_is_deletion_void(const void *p) } static int reftable_ref_record_equal_void(const void *a, - const void *b, int hash_size) + const void *b, uint32_t hash_size) { struct reftable_ref_record *ra = (struct reftable_ref_record *) a; struct reftable_ref_record *rb = (struct reftable_ref_record *) b; @@ -441,39 +473,44 @@ static struct reftable_record_vtable reftable_ref_record_vtable = { .cmp = &reftable_ref_record_cmp_void, }; -static void reftable_obj_record_key(const void *r, struct strbuf *dest) +static int reftable_obj_record_key(const void *r, struct reftable_buf *dest) { const struct reftable_obj_record *rec = (const struct reftable_obj_record *)r; - strbuf_reset(dest); - strbuf_add(dest, rec->hash_prefix, rec->hash_prefix_len); + reftable_buf_reset(dest); + return reftable_buf_add(dest, rec->hash_prefix, rec->hash_prefix_len); } static void reftable_obj_record_release(void *rec) { struct reftable_obj_record *obj = rec; - FREE_AND_NULL(obj->hash_prefix); - FREE_AND_NULL(obj->offsets); + REFTABLE_FREE_AND_NULL(obj->hash_prefix); + REFTABLE_FREE_AND_NULL(obj->offsets); memset(obj, 0, sizeof(struct reftable_obj_record)); } -static void reftable_obj_record_copy_from(void *rec, const void *src_rec, - int hash_size UNUSED) +static int reftable_obj_record_copy_from(void *rec, const void *src_rec, + uint32_t hash_size UNUSED) { struct reftable_obj_record *obj = rec; - const struct reftable_obj_record *src = - (const struct reftable_obj_record *)src_rec; + const struct reftable_obj_record *src = src_rec; reftable_obj_record_release(obj); REFTABLE_ALLOC_ARRAY(obj->hash_prefix, src->hash_prefix_len); + if (!obj->hash_prefix) + return REFTABLE_OUT_OF_MEMORY_ERROR; obj->hash_prefix_len = src->hash_prefix_len; if (src->hash_prefix_len) memcpy(obj->hash_prefix, src->hash_prefix, obj->hash_prefix_len); REFTABLE_ALLOC_ARRAY(obj->offsets, src->offset_len); + if (!obj->offsets) + return REFTABLE_OUT_OF_MEMORY_ERROR; obj->offset_len = src->offset_len; COPY_ARRAY(obj->offsets, src->offsets, src->offset_len); + + return 0; } static uint8_t reftable_obj_record_val_type(const void *rec) @@ -485,7 +522,7 @@ static uint8_t reftable_obj_record_val_type(const void *rec) } static int reftable_obj_record_encode(const void *rec, struct string_view s, - int hash_size UNUSED) + uint32_t hash_size UNUSED) { const struct reftable_obj_record *r = rec; struct string_view start = s; @@ -518,21 +555,22 @@ static int reftable_obj_record_encode(const void *rec, struct string_view s, return start.len - s.len; } -static int reftable_obj_record_decode(void *rec, struct strbuf key, +static int reftable_obj_record_decode(void *rec, struct reftable_buf key, uint8_t val_type, struct string_view in, - int hash_size UNUSED, - struct strbuf *scratch UNUSED) + uint32_t hash_size UNUSED, + struct reftable_buf *scratch UNUSED) { struct string_view start = in; struct reftable_obj_record *r = rec; uint64_t count = val_type; int n = 0; uint64_t last; - int j; reftable_obj_record_release(r); REFTABLE_ALLOC_ARRAY(r->hash_prefix, key.len); + if (!r->hash_prefix) + return REFTABLE_OUT_OF_MEMORY_ERROR; memcpy(r->hash_prefix, key.buf, key.len); r->hash_prefix_len = key.len; @@ -551,6 +589,8 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, return start.len - in.len; REFTABLE_ALLOC_ARRAY(r->offsets, count); + if (!r->offsets) + return REFTABLE_OUT_OF_MEMORY_ERROR; r->offset_len = count; n = get_var_int(&r->offsets[0], &in); @@ -559,8 +599,7 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, string_view_consume(&in, n); last = r->offsets[0]; - j = 1; - while (j < count) { + for (uint64_t j = 1; j < count; j++) { uint64_t delta = 0; int n = get_var_int(&delta, &in); if (n < 0) { @@ -569,7 +608,6 @@ static int reftable_obj_record_decode(void *rec, struct strbuf key, string_view_consume(&in, n); last = r->offsets[j] = (delta + last); - j++; } return start.len - in.len; } @@ -580,7 +618,7 @@ static int not_a_deletion(const void *p UNUSED) } static int reftable_obj_record_equal_void(const void *a, const void *b, - int hash_size UNUSED) + uint32_t hash_size UNUSED) { struct reftable_obj_record *ra = (struct reftable_obj_record *) a; struct reftable_obj_record *rb = (struct reftable_obj_record *) b; @@ -631,48 +669,67 @@ static struct reftable_record_vtable reftable_obj_record_vtable = { .cmp = &reftable_obj_record_cmp_void, }; -static void reftable_log_record_key(const void *r, struct strbuf *dest) +static int reftable_log_record_key(const void *r, struct reftable_buf *dest) { const struct reftable_log_record *rec = (const struct reftable_log_record *)r; - int len = strlen(rec->refname); + int len = strlen(rec->refname), err; uint8_t i64[8]; uint64_t ts = 0; - strbuf_reset(dest); - strbuf_add(dest, (uint8_t *)rec->refname, len + 1); + + reftable_buf_reset(dest); + err = reftable_buf_add(dest, (uint8_t *)rec->refname, len + 1); + if (err < 0) + return err; ts = (~ts) - rec->update_index; put_be64(&i64[0], ts); - strbuf_add(dest, i64, sizeof(i64)); + + err = reftable_buf_add(dest, i64, sizeof(i64)); + if (err < 0) + return err; + + return 0; } -static void reftable_log_record_copy_from(void *rec, const void *src_rec, - int hash_size) +static int reftable_log_record_copy_from(void *rec, const void *src_rec, + uint32_t hash_size) { struct reftable_log_record *dst = rec; const struct reftable_log_record *src = (const struct reftable_log_record *)src_rec; + int ret; reftable_log_record_release(dst); *dst = *src; + if (dst->refname) { - dst->refname = xstrdup(dst->refname); + dst->refname = reftable_strdup(dst->refname); + if (!dst->refname) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } } + switch (dst->value_type) { case REFTABLE_LOG_DELETION: break; case REFTABLE_LOG_UPDATE: - if (dst->value.update.email) { + if (dst->value.update.email) dst->value.update.email = - xstrdup(dst->value.update.email); - } - if (dst->value.update.name) { + reftable_strdup(dst->value.update.email); + if (dst->value.update.name) dst->value.update.name = - xstrdup(dst->value.update.name); - } - if (dst->value.update.message) { + reftable_strdup(dst->value.update.name); + if (dst->value.update.message) dst->value.update.message = - xstrdup(dst->value.update.message); + reftable_strdup(dst->value.update.message); + + if (!dst->value.update.email || + !dst->value.update.name || + !dst->value.update.message) { + ret = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; } memcpy(dst->value.update.new_hash, @@ -681,6 +738,10 @@ static void reftable_log_record_copy_from(void *rec, const void *src_rec, src->value.update.old_hash, hash_size); break; } + + ret = 0; +out: + return ret; } static void reftable_log_record_release_void(void *rec) @@ -713,7 +774,7 @@ static uint8_t reftable_log_record_val_type(const void *rec) } static int reftable_log_record_encode(const void *rec, struct string_view s, - int hash_size) + uint32_t hash_size) { const struct reftable_log_record *r = rec; struct string_view start = s; @@ -759,20 +820,25 @@ static int reftable_log_record_encode(const void *rec, struct string_view s, return start.len - s.len; } -static int reftable_log_record_decode(void *rec, struct strbuf key, +static int reftable_log_record_decode(void *rec, struct reftable_buf key, uint8_t val_type, struct string_view in, - int hash_size, struct strbuf *scratch) + uint32_t hash_size, struct reftable_buf *scratch) { struct string_view start = in; struct reftable_log_record *r = rec; uint64_t max = 0; uint64_t ts = 0; - int n; + int err, n; if (key.len <= 9 || key.buf[key.len - 9] != 0) return REFTABLE_FORMAT_ERROR; - REFTABLE_ALLOC_GROW(r->refname, key.len - 8, r->refname_cap); + REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len - 8, r->refname_cap); + if (!r->refname) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + memcpy(r->refname, key.buf, key.len - 8); ts = get_be64(key.buf + key.len - 8); @@ -781,10 +847,10 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, if (val_type != r->value_type) { switch (r->value_type) { case REFTABLE_LOG_UPDATE: - FREE_AND_NULL(r->value.update.message); + REFTABLE_FREE_AND_NULL(r->value.update.message); r->value.update.message_cap = 0; - FREE_AND_NULL(r->value.update.email); - FREE_AND_NULL(r->value.update.name); + REFTABLE_FREE_AND_NULL(r->value.update.email); + REFTABLE_FREE_AND_NULL(r->value.update.name); break; case REFTABLE_LOG_DELETION: break; @@ -795,8 +861,10 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, if (val_type == REFTABLE_LOG_DELETION) return 0; - if (in.len < 2 * hash_size) - return REFTABLE_FORMAT_ERROR; + if (in.len < 2 * hash_size) { + err = REFTABLE_FORMAT_ERROR; + goto done; + } memcpy(r->value.update.old_hash, in.buf, hash_size); memcpy(r->value.update.new_hash, in.buf + hash_size, hash_size); @@ -804,8 +872,10 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, string_view_consume(&in, 2 * hash_size); n = decode_string(scratch, in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); /* @@ -816,52 +886,75 @@ static int reftable_log_record_decode(void *rec, struct strbuf key, */ if (!r->value.update.name || strcmp(r->value.update.name, scratch->buf)) { - r->value.update.name = - reftable_realloc(r->value.update.name, scratch->len + 1); + char *name = reftable_realloc(r->value.update.name, scratch->len + 1); + if (!name) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + + r->value.update.name = name; memcpy(r->value.update.name, scratch->buf, scratch->len); r->value.update.name[scratch->len] = 0; } n = decode_string(scratch, in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); /* Same as above, but for the reflog email. */ if (!r->value.update.email || strcmp(r->value.update.email, scratch->buf)) { - r->value.update.email = - reftable_realloc(r->value.update.email, scratch->len + 1); + char *email = reftable_realloc(r->value.update.email, scratch->len + 1); + if (!email) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + + r->value.update.email = email; memcpy(r->value.update.email, scratch->buf, scratch->len); r->value.update.email[scratch->len] = 0; } ts = 0; n = get_var_int(&ts, &in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); r->value.update.time = ts; - if (in.len < 2) + if (in.len < 2) { + err = REFTABLE_FORMAT_ERROR; goto done; + } r->value.update.tz_offset = get_be16(in.buf); string_view_consume(&in, 2); n = decode_string(scratch, in); - if (n < 0) + if (n < 0) { + err = REFTABLE_FORMAT_ERROR; goto done; + } string_view_consume(&in, n); - REFTABLE_ALLOC_GROW(r->value.update.message, scratch->len + 1, - r->value.update.message_cap); + REFTABLE_ALLOC_GROW_OR_NULL(r->value.update.message, scratch->len + 1, + r->value.update.message_cap); + if (!r->value.update.message) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + memcpy(r->value.update.message, scratch->buf, scratch->len); r->value.update.message[scratch->len] = 0; return start.len - in.len; done: - return REFTABLE_FORMAT_ERROR; + return err; } static int null_streq(const char *a, const char *b) @@ -877,7 +970,7 @@ static int null_streq(const char *a, const char *b) } static int reftable_log_record_equal_void(const void *a, - const void *b, int hash_size) + const void *b, uint32_t hash_size) { return reftable_log_record_equal((struct reftable_log_record *) a, (struct reftable_log_record *) b, @@ -901,7 +994,7 @@ static int reftable_log_record_cmp_void(const void *_a, const void *_b) } int reftable_log_record_equal(const struct reftable_log_record *a, - const struct reftable_log_record *b, int hash_size) + const struct reftable_log_record *b, uint32_t hash_size) { if (!(null_streq(a->refname, b->refname) && a->update_index == b->update_index && @@ -947,28 +1040,33 @@ static struct reftable_record_vtable reftable_log_record_vtable = { .cmp = &reftable_log_record_cmp_void, }; -static void reftable_index_record_key(const void *r, struct strbuf *dest) +static int reftable_index_record_key(const void *r, struct reftable_buf *dest) { const struct reftable_index_record *rec = r; - strbuf_reset(dest); - strbuf_addbuf(dest, &rec->last_key); + reftable_buf_reset(dest); + return reftable_buf_add(dest, rec->last_key.buf, rec->last_key.len); } -static void reftable_index_record_copy_from(void *rec, const void *src_rec, - int hash_size UNUSED) +static int reftable_index_record_copy_from(void *rec, const void *src_rec, + uint32_t hash_size UNUSED) { struct reftable_index_record *dst = rec; const struct reftable_index_record *src = src_rec; + int err; - strbuf_reset(&dst->last_key); - strbuf_addbuf(&dst->last_key, &src->last_key); + reftable_buf_reset(&dst->last_key); + err = reftable_buf_add(&dst->last_key, src->last_key.buf, src->last_key.len); + if (err < 0) + return err; dst->offset = src->offset; + + return 0; } static void reftable_index_record_release(void *rec) { struct reftable_index_record *idx = rec; - strbuf_release(&idx->last_key); + reftable_buf_release(&idx->last_key); } static uint8_t reftable_index_record_val_type(const void *rec UNUSED) @@ -977,7 +1075,7 @@ static uint8_t reftable_index_record_val_type(const void *rec UNUSED) } static int reftable_index_record_encode(const void *rec, struct string_view out, - int hash_size UNUSED) + uint32_t hash_size UNUSED) { const struct reftable_index_record *r = (const struct reftable_index_record *)rec; @@ -992,18 +1090,20 @@ static int reftable_index_record_encode(const void *rec, struct string_view out, return start.len - out.len; } -static int reftable_index_record_decode(void *rec, struct strbuf key, +static int reftable_index_record_decode(void *rec, struct reftable_buf key, uint8_t val_type UNUSED, struct string_view in, - int hash_size UNUSED, - struct strbuf *scratch UNUSED) + uint32_t hash_size UNUSED, + struct reftable_buf *scratch UNUSED) { struct string_view start = in; struct reftable_index_record *r = rec; - int n = 0; + int err, n = 0; - strbuf_reset(&r->last_key); - strbuf_addbuf(&r->last_key, &key); + reftable_buf_reset(&r->last_key); + err = reftable_buf_add(&r->last_key, key.buf, key.len); + if (err < 0) + return err; n = get_var_int(&r->offset, &in); if (n < 0) @@ -1014,19 +1114,19 @@ static int reftable_index_record_decode(void *rec, struct strbuf key, } static int reftable_index_record_equal(const void *a, const void *b, - int hash_size UNUSED) + uint32_t hash_size UNUSED) { struct reftable_index_record *ia = (struct reftable_index_record *) a; struct reftable_index_record *ib = (struct reftable_index_record *) b; - return ia->offset == ib->offset && !strbuf_cmp(&ia->last_key, &ib->last_key); + return ia->offset == ib->offset && !reftable_buf_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); + return reftable_buf_cmp(&a->last_key, &b->last_key); } static struct reftable_record_vtable reftable_index_record_vtable = { @@ -1042,26 +1142,26 @@ static struct reftable_record_vtable reftable_index_record_vtable = { .cmp = &reftable_index_record_cmp, }; -void reftable_record_key(struct reftable_record *rec, struct strbuf *dest) +int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest) { - reftable_record_vtable(rec)->key(reftable_record_data(rec), dest); + return reftable_record_vtable(rec)->key(reftable_record_data(rec), dest); } int reftable_record_encode(struct reftable_record *rec, struct string_view dest, - int hash_size) + uint32_t hash_size) { return reftable_record_vtable(rec)->encode(reftable_record_data(rec), dest, hash_size); } -void reftable_record_copy_from(struct reftable_record *rec, - struct reftable_record *src, int hash_size) +int reftable_record_copy_from(struct reftable_record *rec, + struct reftable_record *src, uint32_t hash_size) { assert(src->type == rec->type); - reftable_record_vtable(rec)->copy_from(reftable_record_data(rec), - reftable_record_data(src), - hash_size); + return reftable_record_vtable(rec)->copy_from(reftable_record_data(rec), + reftable_record_data(src), + hash_size); } uint8_t reftable_record_val_type(struct reftable_record *rec) @@ -1069,9 +1169,9 @@ uint8_t reftable_record_val_type(struct reftable_record *rec) return reftable_record_vtable(rec)->val_type(reftable_record_data(rec)); } -int reftable_record_decode(struct reftable_record *rec, struct strbuf key, - uint8_t extra, struct string_view src, int hash_size, - struct strbuf *scratch) +int reftable_record_decode(struct reftable_record *rec, struct reftable_buf key, + uint8_t extra, struct string_view src, uint32_t hash_size, + struct reftable_buf *scratch) { return reftable_record_vtable(rec)->decode(reftable_record_data(rec), key, extra, src, hash_size, @@ -1097,7 +1197,7 @@ int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b) reftable_record_data(a), reftable_record_data(b)); } -int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size) +int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, uint32_t hash_size) { if (a->type != b->type) return 0; @@ -1105,7 +1205,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(const unsigned char *a, const unsigned char *b, int hash_size) +static int hash_equal(const unsigned char *a, const unsigned char *b, uint32_t hash_size) { if (a && b) return !memcmp(a, b, hash_size); @@ -1114,9 +1214,8 @@ static int hash_equal(const unsigned char *a, const unsigned char *b, int hash_s } int reftable_ref_record_equal(const struct reftable_ref_record *a, - const struct reftable_ref_record *b, int hash_size) + const struct reftable_ref_record *b, uint32_t hash_size) { - assert(hash_size > 0); if (!null_streq(a->refname, b->refname)) return 0; @@ -1212,7 +1311,7 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ) case BLOCK_TYPE_OBJ: return; case BLOCK_TYPE_INDEX: - strbuf_init(&rec->u.idx.last_key, 0); + reftable_buf_init(&rec->u.idx.last_key); return; default: BUG("unhandled record type"); diff --git a/reftable/record.h b/reftable/record.h index 5003bacdb0c21e..c7755a4d750339 100644 --- a/reftable/record.h +++ b/reftable/record.h @@ -9,6 +9,7 @@ license that can be found in the LICENSE file or at #ifndef RECORD_H #define RECORD_H +#include "basics.h" #include "system.h" #include <stdint.h> @@ -31,32 +32,34 @@ static inline void string_view_consume(struct string_view *s, int n) s->len -= n; } -/* utilities for de/encoding varints */ - +/* + * Decode and encode a varint. Returns the number of bytes read/written, or a + * negative value in case encoding/decoding the varint has failed. + */ int get_var_int(uint64_t *dest, struct string_view *in); int put_var_int(struct string_view *dest, uint64_t val); /* Methods for records. */ struct reftable_record_vtable { - /* encode the key of to a uint8_t strbuf. */ - void (*key)(const void *rec, struct strbuf *dest); + /* encode the key of to a uint8_t reftable_buf. */ + int (*key)(const void *rec, struct reftable_buf *dest); /* The record type of ('r' for ref). */ uint8_t type; - void (*copy_from)(void *dest, const void *src, int hash_size); + int (*copy_from)(void *dest, const void *src, uint32_t hash_size); /* a value of [0..7], indicating record subvariants (eg. ref vs. symref * vs ref deletion) */ uint8_t (*val_type)(const void *rec); /* encodes rec into dest, returning how much space was used. */ - int (*encode)(const void *rec, struct string_view dest, int hash_size); + int (*encode)(const void *rec, struct string_view dest, uint32_t hash_size); /* decode data from `src` into the record. */ - int (*decode)(void *rec, struct strbuf key, uint8_t extra, - struct string_view src, int hash_size, - struct strbuf *scratch); + int (*decode)(void *rec, struct reftable_buf key, uint8_t extra, + struct string_view src, uint32_t hash_size, + struct reftable_buf *scratch); /* deallocate and null the record. */ void (*release)(void *rec); @@ -65,16 +68,13 @@ struct reftable_record_vtable { int (*is_deletion)(const void *rec); /* 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); + int (*equal)(const void *a, const void *b, uint32_t 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); }; /* returns true for recognized block types. Block start with the block type. */ @@ -83,7 +83,7 @@ int reftable_is_block_type(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, - struct strbuf prev_key, struct strbuf key, + struct reftable_buf prev_key, struct reftable_buf key, uint8_t extra); /* Decode a record's key lengths. */ @@ -96,13 +96,13 @@ int reftable_decode_keylen(struct string_view in, * Decode into `last_key` and `extra` from `in`. `last_key` is expected to * contain the decoded key of the preceding record, if any. */ -int reftable_decode_key(struct strbuf *last_key, uint8_t *extra, +int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra, struct string_view in); /* reftable_index_record are used internally to speed up lookups. */ struct reftable_index_record { uint64_t offset; /* Offset of block */ - struct strbuf last_key; /* Last key of the block. */ + struct reftable_buf last_key; /* Last key of the block. */ }; /* reftable_obj_record stores an object ID => ref mapping. */ @@ -135,16 +135,16 @@ 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_key(struct reftable_record *rec, struct strbuf *dest); -void reftable_record_copy_from(struct reftable_record *rec, - struct reftable_record *src, int hash_size); +int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, uint32_t hash_size); +int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest); +int reftable_record_copy_from(struct reftable_record *rec, + struct reftable_record *src, uint32_t hash_size); uint8_t reftable_record_val_type(struct reftable_record *rec); int reftable_record_encode(struct reftable_record *rec, struct string_view dest, - int hash_size); -int reftable_record_decode(struct reftable_record *rec, struct strbuf key, + uint32_t hash_size); +int reftable_record_decode(struct reftable_record *rec, struct reftable_buf key, uint8_t extra, struct string_view src, - int hash_size, struct strbuf *scratch); + uint32_t hash_size, struct reftable_buf *scratch); int reftable_record_is_deletion(struct reftable_record *rec); static inline uint8_t reftable_record_type(struct reftable_record *rec) diff --git a/reftable/reftable-basics.h b/reftable/reftable-basics.h new file mode 100644 index 00000000000000..e0397ed5836969 --- /dev/null +++ b/reftable/reftable-basics.h @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Google LLC + * + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file or at + * https://developers.google.com/open-source/licenses/bsd +*/ + +#ifndef REFTABLE_BASICS_H +#define REFTABLE_BASICS_H + +#include <stddef.h> + +/* + * Hash functions understood by the reftable library. Note that the values are + * arbitrary and somewhat random such that we can easily detect cases where the + * hash hasn't been properly set up. + */ +enum reftable_hash { + REFTABLE_HASH_SHA1 = 89, + REFTABLE_HASH_SHA256 = 247, +}; +#define REFTABLE_HASH_SIZE_SHA1 20 +#define REFTABLE_HASH_SIZE_SHA256 32 +#define REFTABLE_HASH_SIZE_MAX REFTABLE_HASH_SIZE_SHA256 + +/* Overrides the functions to use for memory management. */ +void reftable_set_alloc(void *(*malloc)(size_t), + void *(*realloc)(void *, size_t), void (*free)(void *)); + +#endif diff --git a/reftable/reftable-blocksource.h b/reftable/reftable-blocksource.h index 5aa3990a5732f6..6b326aa5ea5db8 100644 --- a/reftable/reftable-blocksource.h +++ b/reftable/reftable-blocksource.h @@ -22,7 +22,7 @@ struct reftable_block_source { * so it can return itself into the pool. */ struct reftable_block { uint8_t *data; - int len; + size_t len; struct reftable_block_source source; }; @@ -31,10 +31,13 @@ struct reftable_block_source_vtable { /* returns the size of a block source */ uint64_t (*size)(void *source); - /* reads a segment from the block source. It is an error to read - beyond the end of the block */ - int (*read_block)(void *source, struct reftable_block *dest, - uint64_t off, uint32_t size); + /* + * Reads a segment from the block source. It is an error to read beyond + * the end of the block. + */ + ssize_t (*read_block)(void *source, struct reftable_block *dest, + uint64_t off, uint32_t size); + /* mark the block as read; may return the data back to malloc */ void (*return_block)(void *source, struct reftable_block *blockp); diff --git a/reftable/reftable-error.h b/reftable/reftable-error.h index 6368cd9ed9dab9..a7e33d964d0cfe 100644 --- a/reftable/reftable-error.h +++ b/reftable/reftable-error.h @@ -30,6 +30,7 @@ enum reftable_error { /* Misuse of the API: * - on writing a record with NULL refname. + * - on writing a record before setting the writer limits. * - on writing a reftable_ref_record outside the table limits * - on writing a ref or log record before the stack's * next_update_inde*x @@ -57,6 +58,9 @@ enum reftable_error { /* Trying to write out-of-date data. */ REFTABLE_OUTDATED_ERROR = -12, + + /* An allocation has failed due to an out-of-memory situation. */ + REFTABLE_OUT_OF_MEMORY_ERROR = -13, }; /* convert the numeric error code to a string. The string should not be diff --git a/reftable/reftable-malloc.h b/reftable/reftable-malloc.h deleted file mode 100644 index 5f2185f1f34386..00000000000000 --- a/reftable/reftable-malloc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2020 Google LLC - -Use of this source code is governed by a BSD-style -license that can be found in the LICENSE file or at -https://developers.google.com/open-source/licenses/bsd -*/ - -#ifndef REFTABLE_H -#define REFTABLE_H - -#include <stddef.h> - -/* Overrides the functions to use for memory management. */ -void reftable_set_alloc(void *(*malloc)(size_t), - void *(*realloc)(void *, size_t), void (*free)(void *)); - -#endif diff --git a/reftable/reftable-merged.h b/reftable/reftable-merged.h index 16d19f8df206f3..f2d01c3ef82149 100644 --- a/reftable/reftable-merged.h +++ b/reftable/reftable-merged.h @@ -34,15 +34,15 @@ struct reftable_reader; */ int reftable_merged_table_new(struct reftable_merged_table **dest, struct reftable_reader **readers, size_t n, - uint32_t hash_id); + enum reftable_hash hash_id); /* Initialize a merged table iterator for reading refs. */ -void reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt, - struct reftable_iterator *it); +int reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt, + struct reftable_iterator *it); /* Initialize a merged table iterator for reading logs. */ -void reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt, - struct reftable_iterator *it); +int reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt, + struct reftable_iterator *it); /* returns the max update_index covered by this merged table. */ uint64_t @@ -56,6 +56,6 @@ reftable_merged_table_min_update_index(struct reftable_merged_table *mt); void reftable_merged_table_free(struct reftable_merged_table *m); /* return the hash ID of the merged table. */ -uint32_t reftable_merged_table_hash_id(struct reftable_merged_table *m); +enum reftable_hash reftable_merged_table_hash_id(struct reftable_merged_table *m); #endif diff --git a/reftable/reftable-reader.h b/reftable/reftable-reader.h index a600452b565803..0085fbb903291a 100644 --- a/reftable/reftable-reader.h +++ b/reftable/reftable-reader.h @@ -46,15 +46,15 @@ void reftable_reader_incref(struct reftable_reader *reader); void reftable_reader_decref(struct reftable_reader *reader); /* Initialize a reftable iterator for reading refs. */ -void reftable_reader_init_ref_iterator(struct reftable_reader *r, - struct reftable_iterator *it); +int reftable_reader_init_ref_iterator(struct reftable_reader *r, + struct reftable_iterator *it); /* Initialize a reftable iterator for reading logs. */ -void reftable_reader_init_log_iterator(struct reftable_reader *r, - struct reftable_iterator *it); +int reftable_reader_init_log_iterator(struct reftable_reader *r, + struct reftable_iterator *it); /* returns the hash ID used in this table. */ -uint32_t reftable_reader_hash_id(struct reftable_reader *r); +enum reftable_hash reftable_reader_hash_id(struct reftable_reader *r); /* return an iterator for the refs pointing to `oid`. */ int reftable_reader_refs_for(struct reftable_reader *r, diff --git a/reftable/reftable-record.h b/reftable/reftable-record.h index 2d42463c5811ba..931e59474416dd 100644 --- a/reftable/reftable-record.h +++ b/reftable/reftable-record.h @@ -9,7 +9,7 @@ license that can be found in the LICENSE file or at #ifndef REFTABLE_RECORD_H #define REFTABLE_RECORD_H -#include "hash.h" +#include "reftable-basics.h" #include <stdint.h> /* @@ -40,10 +40,10 @@ struct reftable_ref_record { #define REFTABLE_NR_REF_VALUETYPES 4 } value_type; union { - unsigned char val1[GIT_MAX_RAWSZ]; + unsigned char val1[REFTABLE_HASH_SIZE_MAX]; struct { - unsigned char value[GIT_MAX_RAWSZ]; /* first hash */ - unsigned char target_value[GIT_MAX_RAWSZ]; /* second hash */ + unsigned char value[REFTABLE_HASH_SIZE_MAX]; /* first hash */ + unsigned char target_value[REFTABLE_HASH_SIZE_MAX]; /* second hash */ } val2; char *symref; /* referent, malloced 0-terminated string */ } value; @@ -65,7 +65,7 @@ void reftable_ref_record_release(struct reftable_ref_record *ref); /* returns whether two reftable_ref_records are the same. Useful for testing. */ int reftable_ref_record_equal(const struct reftable_ref_record *a, - const struct reftable_ref_record *b, int hash_size); + const struct reftable_ref_record *b, uint32_t hash_size); /* reftable_log_record holds a reflog entry */ struct reftable_log_record { @@ -85,8 +85,8 @@ struct reftable_log_record { union { struct { - unsigned char new_hash[GIT_MAX_RAWSZ]; - unsigned char old_hash[GIT_MAX_RAWSZ]; + unsigned char new_hash[REFTABLE_HASH_SIZE_MAX]; + unsigned char old_hash[REFTABLE_HASH_SIZE_MAX]; char *name; char *email; uint64_t time; @@ -105,6 +105,6 @@ void reftable_log_record_release(struct reftable_log_record *log); /* returns whether two records are equal. Useful for testing. */ int reftable_log_record_equal(const struct reftable_log_record *a, - const struct reftable_log_record *b, int hash_size); + const struct reftable_log_record *b, uint32_t hash_size); #endif diff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h index 6370fe45ddfa00..ae14270ea74108 100644 --- a/reftable/reftable-stack.h +++ b/reftable/reftable-stack.h @@ -82,16 +82,16 @@ struct reftable_iterator; * be used to iterate through refs. The iterator is valid until the next reload * or write. */ -void reftable_stack_init_ref_iterator(struct reftable_stack *st, - struct reftable_iterator *it); +int reftable_stack_init_ref_iterator(struct reftable_stack *st, + struct reftable_iterator *it); /* * Initialize an iterator for the merged tables contained in the stack that can * be used to iterate through logs. The iterator is valid until the next reload * or write. */ -void reftable_stack_init_log_iterator(struct reftable_stack *st, - struct reftable_iterator *it); +int reftable_stack_init_log_iterator(struct reftable_stack *st, + struct reftable_iterator *it); /* returns the merged_table for seeking. This table is valid until the * next write or reload, and should not be closed or deleted. @@ -149,4 +149,7 @@ struct reftable_compaction_stats { struct reftable_compaction_stats * reftable_stack_compaction_stats(struct reftable_stack *st); +/* Return the hash of the stack. */ +enum reftable_hash reftable_stack_hash_id(struct reftable_stack *st); + #endif diff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h index f5e25cfda163d9..1befe3b07cfe58 100644 --- a/reftable/reftable-writer.h +++ b/reftable/reftable-writer.h @@ -33,7 +33,7 @@ struct reftable_write_options { /* 4-byte identifier ("sha1", "s256") of the hash. * Defaults to SHA1 if unset */ - uint32_t hash_id; + enum reftable_hash hash_id; /* Default mode for creating files. If unset, use 0666 (+umask) */ unsigned int default_permissions; @@ -62,6 +62,21 @@ struct reftable_write_options { * negative value will cause us to block indefinitely. */ long lock_timeout_ms; + + /* + * Optional callback used to fsync files to disk. Falls back to using + * fsync(3P) when unset. + */ + int (*fsync)(int fd); + + /* + * Callback function to execute whenever the stack is being reloaded. + * This can be used e.g. to discard cached information that relies on + * the old stack's data. The payload data will be passed as argument to + * the callback. + */ + void (*on_reload)(void *payload); + void *on_reload_payload; }; /* reftable_block_stats holds statistics for a single block type */ @@ -69,7 +84,7 @@ struct reftable_block_stats { /* total number of entries written */ int entries; /* total number of key restarts */ - int restarts; + uint32_t restarts; /* total number of blocks */ int blocks; /* total number of index blocks */ @@ -101,23 +116,29 @@ struct reftable_stats { int object_id_len; }; -/* 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, const struct reftable_write_options *opts); +struct reftable_writer; -/* Set the range of update indices for the records we will add. When writing a - table into a stack, the min should be at least - reftable_stack_next_update_index(), or REFTABLE_API_ERROR is returned. +/* Create a new writer. */ +int reftable_writer_new(struct reftable_writer **out, + ssize_t (*writer_func)(void *, const void *, size_t), + int (*flush_func)(void *), + void *writer_arg, const struct reftable_write_options *opts); - For transactional updates to a stack, typically min==max, and the - update_index can be obtained by inspeciting the stack. When converting an - existing ref database into a single reftable, this would be a range of - update-index timestamps. +/* + * Set the range of update indices for the records we will add. When writing a + * table into a stack, the min should be at least + * reftable_stack_next_update_index(), or REFTABLE_API_ERROR is returned. + * + * For transactional updates to a stack, typically min==max, and the + * update_index can be obtained by inspeciting the stack. When converting an + * existing ref database into a single reftable, this would be a range of + * update-index timestamps. + * + * The function should be called before adding any records to the writer. If not + * it will fail with REFTABLE_API_ERROR. */ -void reftable_writer_set_limits(struct reftable_writer *w, uint64_t min, - uint64_t max); +int reftable_writer_set_limits(struct reftable_writer *w, uint64_t min, + uint64_t max); /* Add a reftable_ref_record. The record should have names that come after diff --git a/reftable/stack.c b/reftable/stack.c index 84cf37a2ad03ea..6c4e8be19b1050 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -8,7 +8,6 @@ license that can be found in the LICENSE file or at #include "stack.h" -#include "../write-or-die.h" #include "system.h" #include "constants.h" #include "merged.h" @@ -17,7 +16,6 @@ license that can be found in the LICENSE file or at #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, @@ -31,58 +29,87 @@ static void reftable_addition_close(struct reftable_addition *add); static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, int reuse_open); -static void stack_filename(struct strbuf *dest, struct reftable_stack *st, - const char *name) +static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st, + const char *name) { - strbuf_reset(dest); - strbuf_addstr(dest, st->reftable_dir); - strbuf_addstr(dest, "/"); - strbuf_addstr(dest, name); + int err; + reftable_buf_reset(dest); + if ((err = reftable_buf_addstr(dest, st->reftable_dir)) < 0 || + (err = reftable_buf_addstr(dest, "/")) < 0 || + (err = reftable_buf_addstr(dest, name)) < 0) + return err; + return 0; } -static ssize_t reftable_fd_write(void *arg, const void *data, size_t sz) +static int stack_fsync(const struct reftable_write_options *opts, int fd) { - int *fdp = (int *)arg; - return write_in_full(*fdp, data, sz); + if (opts->fsync) + return opts->fsync(fd); + return fsync(fd); } -static int reftable_fd_flush(void *arg) +struct fd_writer { + const struct reftable_write_options *opts; + int fd; +}; + +static ssize_t fd_writer_write(void *arg, const void *data, size_t sz) { - int *fdp = (int *)arg; + struct fd_writer *writer = arg; + return write_in_full(writer->fd, data, sz); +} - return fsync_component(FSYNC_COMPONENT_REFERENCE, *fdp); +static int fd_writer_flush(void *arg) +{ + struct fd_writer *writer = arg; + return stack_fsync(writer->opts, writer->fd); } int reftable_new_stack(struct reftable_stack **dest, const char *dir, const struct reftable_write_options *_opts) { - struct reftable_stack *p = reftable_calloc(1, sizeof(*p)); - struct strbuf list_file_name = STRBUF_INIT; - struct reftable_write_options opts = {0}; - int err = 0; + struct reftable_buf list_file_name = REFTABLE_BUF_INIT; + struct reftable_write_options opts = { 0 }; + struct reftable_stack *p; + int err; + + p = reftable_calloc(1, sizeof(*p)); + if (!p) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } if (_opts) opts = *_opts; if (opts.hash_id == 0) - opts.hash_id = GIT_SHA1_FORMAT_ID; + opts.hash_id = REFTABLE_HASH_SHA1; *dest = NULL; - strbuf_reset(&list_file_name); - strbuf_addstr(&list_file_name, dir); - strbuf_addstr(&list_file_name, "/tables.list"); + reftable_buf_reset(&list_file_name); + if ((err = reftable_buf_addstr(&list_file_name, dir)) < 0 || + (err = reftable_buf_addstr(&list_file_name, "/tables.list")) < 0) + goto out; - p->list_file = strbuf_detach(&list_file_name, NULL); + p->list_file = reftable_buf_detach(&list_file_name); p->list_fd = -1; - p->reftable_dir = xstrdup(dir); p->opts = opts; + p->reftable_dir = reftable_strdup(dir); + if (!p->reftable_dir) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } err = reftable_stack_reload_maybe_reuse(p, 1); - if (err < 0) { + if (err < 0) + goto out; + + *dest = p; + err = 0; + +out: + if (err < 0) reftable_stack_destroy(p); - } else { - *dest = p; - } return err; } @@ -102,13 +129,22 @@ static int fd_read_lines(int fd, char ***namesp) } REFTABLE_ALLOC_ARRAY(buf, size + 1); + if (!buf) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + if (read_in_full(fd, buf, size) != size) { err = REFTABLE_IO_ERROR; goto done; } buf[size] = 0; - parse_names(buf, size, namesp); + *namesp = parse_names(buf, size); + if (!*namesp) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } done: reftable_free(buf); @@ -122,6 +158,8 @@ int read_lines(const char *filename, char ***namesp) if (fd < 0) { if (errno == ENOENT) { REFTABLE_CALLOC_ARRAY(*namesp, 1); + if (!*namesp) + return REFTABLE_OUT_OF_MEMORY_ERROR; return 0; } @@ -132,18 +170,18 @@ int read_lines(const char *filename, char ***namesp) return err; } -void reftable_stack_init_ref_iterator(struct reftable_stack *st, +int reftable_stack_init_ref_iterator(struct reftable_stack *st, struct reftable_iterator *it) { - merged_table_init_iter(reftable_stack_merged_table(st), - it, BLOCK_TYPE_REF); + return merged_table_init_iter(reftable_stack_merged_table(st), + it, BLOCK_TYPE_REF); } -void reftable_stack_init_log_iterator(struct reftable_stack *st, - struct reftable_iterator *it) +int reftable_stack_init_log_iterator(struct reftable_stack *st, + struct reftable_iterator *it) { - merged_table_init_iter(reftable_stack_merged_table(st), - it, BLOCK_TYPE_LOG); + return merged_table_init_iter(reftable_stack_merged_table(st), + it, BLOCK_TYPE_LOG); } struct reftable_merged_table * @@ -167,6 +205,10 @@ void reftable_stack_destroy(struct reftable_stack *st) { char **names = NULL; int err = 0; + + if (!st) + return; + if (st->merged) { reftable_merged_table_free(st->merged); st->merged = NULL; @@ -174,28 +216,32 @@ void reftable_stack_destroy(struct reftable_stack *st) err = read_lines(st->list_file, &names); if (err < 0) { - FREE_AND_NULL(names); + REFTABLE_FREE_AND_NULL(names); } if (st->readers) { - int i = 0; - struct strbuf filename = STRBUF_INIT; - for (i = 0; i < st->readers_len; i++) { + struct reftable_buf filename = REFTABLE_BUF_INIT; + + for (size_t i = 0; i < st->readers_len; i++) { const char *name = reader_name(st->readers[i]); - strbuf_reset(&filename); + int try_unlinking = 1; + + reftable_buf_reset(&filename); if (names && !has_name(names, name)) { - stack_filename(&filename, st, name); + if (stack_filename(&filename, st, name) < 0) + try_unlinking = 0; } reftable_reader_decref(st->readers[i]); - if (filename.len) { + if (try_unlinking && filename.len) { /* On Windows, can only unlink after closing. */ unlink(filename.buf); } } - strbuf_release(&filename); + + reftable_buf_release(&filename); st->readers_len = 0; - FREE_AND_NULL(st->readers); + REFTABLE_FREE_AND_NULL(st->readers); } if (st->list_fd >= 0) { @@ -203,20 +249,20 @@ void reftable_stack_destroy(struct reftable_stack *st) st->list_fd = -1; } - FREE_AND_NULL(st->list_file); - FREE_AND_NULL(st->reftable_dir); + REFTABLE_FREE_AND_NULL(st->list_file); + REFTABLE_FREE_AND_NULL(st->reftable_dir); reftable_free(st); free_names(names); } static struct reftable_reader **stack_copy_readers(struct reftable_stack *st, - int cur_len) + size_t cur_len) { struct reftable_reader **cur = reftable_calloc(cur_len, sizeof(*cur)); - int i = 0; - for (i = 0; i < cur_len; i++) { + if (!cur) + return NULL; + for (size_t i = 0; i < cur_len; i++) cur[i] = st->readers[i]; - } return cur; } @@ -225,18 +271,34 @@ static int reftable_stack_reload_once(struct reftable_stack *st, int reuse_open) { size_t cur_len = !st->merged ? 0 : st->merged->readers_len; - struct reftable_reader **cur = stack_copy_readers(st, cur_len); + struct reftable_reader **cur = NULL; struct reftable_reader **reused = NULL; - size_t reused_len = 0, reused_alloc = 0; - size_t names_len = names_length(names); - struct reftable_reader **new_readers = - reftable_calloc(names_len, sizeof(*new_readers)); + struct reftable_reader **new_readers = NULL; + size_t reused_len = 0, reused_alloc = 0, names_len; size_t new_readers_len = 0; struct reftable_merged_table *new_merged = NULL; - struct strbuf table_path = STRBUF_INIT; + struct reftable_buf table_path = REFTABLE_BUF_INIT; int err = 0; size_t i; + if (cur_len) { + cur = stack_copy_readers(st, cur_len); + if (!cur) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + } + + names_len = names_length(names); + + if (names_len) { + new_readers = reftable_calloc(names_len, sizeof(*new_readers)); + if (!new_readers) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + } + while (*names) { struct reftable_reader *rd = NULL; const char *name = *names++; @@ -256,7 +318,13 @@ static int reftable_stack_reload_once(struct reftable_stack *st, * thus need to keep them alive here, which we * do by bumping their refcount. */ - REFTABLE_ALLOC_GROW(reused, reused_len + 1, reused_alloc); + REFTABLE_ALLOC_GROW_OR_NULL(reused, + reused_len + 1, + reused_alloc); + if (!reused) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } reused[reused_len++] = rd; reftable_reader_incref(rd); break; @@ -265,7 +333,10 @@ static int reftable_stack_reload_once(struct reftable_stack *st, if (!rd) { struct reftable_block_source src = { NULL }; - stack_filename(&table_path, st, name); + + err = stack_filename(&table_path, st, name); + if (err < 0) + goto done; err = reftable_block_source_from_file(&src, table_path.buf); @@ -296,7 +367,11 @@ static int reftable_stack_reload_once(struct reftable_stack *st, for (i = 0; i < cur_len; i++) { if (cur[i]) { const char *name = reader_name(cur[i]); - stack_filename(&table_path, st, name); + + err = stack_filename(&table_path, st, name); + if (err < 0) + goto done; + reftable_reader_decref(cur[i]); unlink(table_path.buf); } @@ -329,7 +404,7 @@ static int reftable_stack_reload_once(struct reftable_stack *st, reftable_free(new_readers); reftable_free(reused); reftable_free(cur); - strbuf_release(&table_path); + reftable_buf_release(&table_path); return err; } @@ -382,6 +457,10 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, } REFTABLE_CALLOC_ARRAY(names, 1); + if (!names) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } } else { err = fd_read_lines(fd, &names); if (err < 0) @@ -415,7 +494,7 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, close(fd); fd = -1; - delay = delay + (delay * rand()) / RAND_MAX + 1; + delay = delay + (delay * git_rand(CSPRNG_BYTES_INSECURE)) / UINT32_MAX + 1; sleep_millisec(delay); } @@ -476,6 +555,10 @@ static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, close(fd); free_names(names); free_names(names_after); + + if (st->opts.on_reload) + st->opts.on_reload(st->opts.on_reload_payload); + return err; } @@ -486,7 +569,6 @@ static int stack_uptodate(struct reftable_stack *st) { char **names = NULL; int err; - int i = 0; /* * When we have cached stat information available then we use it to @@ -526,7 +608,7 @@ static int stack_uptodate(struct reftable_stack *st) if (err < 0) return err; - for (i = 0; i < st->readers_len; i++) { + for (size_t i = 0; i < st->readers_len; i++) { if (!names[i]) { err = 1; goto done; @@ -574,18 +656,18 @@ int reftable_stack_add(struct reftable_stack *st, return 0; } -static void format_name(struct strbuf *dest, uint64_t min, uint64_t max) +static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max) { char buf[100]; - uint32_t rnd = (uint32_t)git_rand(); + uint32_t rnd = git_rand(CSPRNG_BYTES_INSECURE); snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x", min, max, rnd); - strbuf_reset(dest); - strbuf_addstr(dest, buf); + reftable_buf_reset(dest); + return reftable_buf_addstr(dest, buf); } struct reftable_addition { - struct lock_file tables_list_lock; + struct reftable_flock tables_list_lock; struct reftable_stack *stack; char **new_tables; @@ -599,15 +681,13 @@ static int reftable_stack_init_addition(struct reftable_addition *add, struct reftable_stack *st, unsigned int flags) { - struct strbuf lock_file_name = STRBUF_INIT; + struct reftable_buf lock_file_name = REFTABLE_BUF_INIT; int err; add->stack = st; - err = hold_lock_file_for_update_timeout(&add->tables_list_lock, - st->list_file, - LOCK_NO_DEREF, - st->opts.lock_timeout_ms); + err = flock_acquire(&add->tables_list_lock, st->list_file, + st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) { err = REFTABLE_LOCK_ERROR; @@ -617,7 +697,7 @@ static int reftable_stack_init_addition(struct reftable_addition *add, goto done; } if (st->opts.default_permissions) { - if (chmod(get_lock_file_path(&add->tables_list_lock), + if (chmod(add->tables_list_lock.path, st->opts.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -641,18 +721,18 @@ static int reftable_stack_init_addition(struct reftable_addition *add, done: if (err) reftable_addition_close(add); - strbuf_release(&lock_file_name); + reftable_buf_release(&lock_file_name); return err; } static void reftable_addition_close(struct reftable_addition *add) { - struct strbuf nm = STRBUF_INIT; + struct reftable_buf nm = REFTABLE_BUF_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); + if (!stack_filename(&nm, add->stack, add->new_tables[i])) + unlink(nm.buf); reftable_free(add->new_tables[i]); add->new_tables[i] = NULL; } @@ -661,8 +741,8 @@ static void reftable_addition_close(struct reftable_addition *add) add->new_tables_len = 0; add->new_tables_cap = 0; - rollback_lock_file(&add->tables_list_lock); - strbuf_release(&nm); + flock_release(&add->tables_list_lock); + reftable_buf_release(&nm); } void reftable_addition_destroy(struct reftable_addition *add) @@ -676,8 +756,7 @@ void reftable_addition_destroy(struct reftable_addition *add) int reftable_addition_commit(struct reftable_addition *add) { - struct strbuf table_list = STRBUF_INIT; - int lock_file_fd = get_lock_file_fd(&add->tables_list_lock); + struct reftable_buf table_list = REFTABLE_BUF_INIT; int err = 0; size_t i; @@ -685,28 +764,30 @@ int reftable_addition_commit(struct reftable_addition *add) goto done; for (i = 0; i < add->stack->merged->readers_len; i++) { - strbuf_addstr(&table_list, add->stack->readers[i]->name); - strbuf_addstr(&table_list, "\n"); + if ((err = reftable_buf_addstr(&table_list, add->stack->readers[i]->name)) < 0 || + (err = reftable_buf_addstr(&table_list, "\n")) < 0) + goto done; } for (i = 0; i < add->new_tables_len; i++) { - strbuf_addstr(&table_list, add->new_tables[i]); - strbuf_addstr(&table_list, "\n"); + if ((err = reftable_buf_addstr(&table_list, add->new_tables[i])) < 0 || + (err = reftable_buf_addstr(&table_list, "\n")) < 0) + goto done; } - err = write_in_full(lock_file_fd, table_list.buf, table_list.len); - strbuf_release(&table_list); + err = write_in_full(add->tables_list_lock.fd, table_list.buf, table_list.len); + reftable_buf_release(&table_list); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; } - err = fsync_component(FSYNC_COMPONENT_REFERENCE, lock_file_fd); + err = stack_fsync(&add->stack->opts, add->tables_list_lock.fd); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; } - err = commit_lock_file(&add->tables_list_lock); + err = flock_commit(&add->tables_list_lock); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -749,7 +830,11 @@ int reftable_stack_new_addition(struct reftable_addition **dest, { int err = 0; struct reftable_addition empty = REFTABLE_ADDITION_INIT; + REFTABLE_CALLOC_ARRAY(*dest, 1); + if (!*dest) + return REFTABLE_OUT_OF_MEMORY_ERROR; + **dest = empty; err = reftable_stack_init_addition(*dest, st, flags); if (err) { @@ -784,36 +869,47 @@ int reftable_addition_add(struct reftable_addition *add, void *arg), void *arg) { - struct strbuf temp_tab_file_name = STRBUF_INIT; - struct strbuf tab_file_name = STRBUF_INIT; - struct strbuf next_name = STRBUF_INIT; + struct reftable_buf temp_tab_file_name = REFTABLE_BUF_INIT; + struct reftable_buf tab_file_name = REFTABLE_BUF_INIT; + struct reftable_buf next_name = REFTABLE_BUF_INIT; struct reftable_writer *wr = NULL; - struct tempfile *tab_file = NULL; + struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT; + struct fd_writer writer = { + .opts = &add->stack->opts, + }; int err = 0; - int tab_fd; - strbuf_reset(&next_name); - format_name(&next_name, add->next_update_index, add->next_update_index); + reftable_buf_reset(&next_name); - stack_filename(&temp_tab_file_name, add->stack, next_name.buf); - strbuf_addstr(&temp_tab_file_name, ".temp.XXXXXX"); + err = format_name(&next_name, add->next_update_index, add->next_update_index); + if (err < 0) + goto done; - tab_file = mks_tempfile(temp_tab_file_name.buf); - if (!tab_file) { - err = REFTABLE_IO_ERROR; + err = stack_filename(&temp_tab_file_name, add->stack, next_name.buf); + if (err < 0) + goto done; + + err = reftable_buf_addstr(&temp_tab_file_name, ".temp.XXXXXX"); + if (err < 0) + goto done; + + err = tmpfile_from_pattern(&tab_file, temp_tab_file_name.buf); + if (err < 0) goto done; - } if (add->stack->opts.default_permissions) { - if (chmod(get_tempfile_path(tab_file), + if (chmod(tab_file.path, add->stack->opts.default_permissions)) { err = REFTABLE_IO_ERROR; goto done; } } - tab_fd = get_tempfile_fd(tab_file); - wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, &tab_fd, - &add->stack->opts); + writer.fd = tab_file.fd; + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush, + &writer, &add->stack->opts); + if (err < 0) + goto done; + err = write_table(wr, arg); if (err < 0) goto done; @@ -826,39 +922,48 @@ int reftable_addition_add(struct reftable_addition *add, if (err < 0) goto done; - err = close_tempfile_gently(tab_file); - if (err < 0) { - err = REFTABLE_IO_ERROR; + err = tmpfile_close(&tab_file); + if (err < 0) goto done; - } if (wr->min_update_index < add->next_update_index) { err = REFTABLE_API_ERROR; goto done; } - format_name(&next_name, wr->min_update_index, wr->max_update_index); - strbuf_addstr(&next_name, ".ref"); - stack_filename(&tab_file_name, add->stack, next_name.buf); + err = format_name(&next_name, wr->min_update_index, wr->max_update_index); + if (err < 0) + goto done; + + err = reftable_buf_addstr(&next_name, ".ref"); + if (err < 0) + goto done; + + err = stack_filename(&tab_file_name, add->stack, next_name.buf); + if (err < 0) + goto done; /* On windows, this relies on rand() picking a unique destination name. Maybe we should do retry loop as well? */ - err = rename_tempfile(&tab_file, tab_file_name.buf); - if (err < 0) { - err = REFTABLE_IO_ERROR; + err = tmpfile_rename(&tab_file, tab_file_name.buf); + if (err < 0) + goto done; + + REFTABLE_ALLOC_GROW_OR_NULL(add->new_tables, add->new_tables_len + 1, + add->new_tables_cap); + if (!add->new_tables) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; } + add->new_tables[add->new_tables_len++] = reftable_buf_detach(&next_name); - 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: - delete_tempfile(&tab_file); - strbuf_release(&temp_tab_file_name); - strbuf_release(&tab_file_name); - strbuf_release(&next_name); + tmpfile_delete(&tab_file); + reftable_buf_release(&temp_tab_file_name); + reftable_buf_release(&tab_file_name); + reftable_buf_release(&next_name); reftable_writer_free(wr); return err; } @@ -875,35 +980,46 @@ uint64_t reftable_stack_next_update_index(struct reftable_stack *st) static int stack_compact_locked(struct reftable_stack *st, size_t first, size_t last, struct reftable_log_expiry_config *config, - struct tempfile **tab_file_out) + struct reftable_tmpfile *tab_file_out) { - struct strbuf next_name = STRBUF_INIT; - struct strbuf tab_file_path = STRBUF_INIT; + struct reftable_buf next_name = REFTABLE_BUF_INIT; + struct reftable_buf tab_file_path = REFTABLE_BUF_INIT; struct reftable_writer *wr = NULL; - struct tempfile *tab_file; - int tab_fd, err = 0; + struct fd_writer writer= { + .opts = &st->opts, + }; + struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT; + int err = 0; - format_name(&next_name, - reftable_reader_min_update_index(st->readers[first]), - reftable_reader_max_update_index(st->readers[last])); - stack_filename(&tab_file_path, st, next_name.buf); - strbuf_addstr(&tab_file_path, ".temp.XXXXXX"); + err = format_name(&next_name, reftable_reader_min_update_index(st->readers[first]), + reftable_reader_max_update_index(st->readers[last])); + if (err < 0) + goto done; - tab_file = mks_tempfile(tab_file_path.buf); - if (!tab_file) { - err = REFTABLE_IO_ERROR; + err = stack_filename(&tab_file_path, st, next_name.buf); + if (err < 0) + goto done; + + err = reftable_buf_addstr(&tab_file_path, ".temp.XXXXXX"); + if (err < 0) + goto done; + + err = tmpfile_from_pattern(&tab_file, tab_file_path.buf); + if (err < 0) goto done; - } - tab_fd = get_tempfile_fd(tab_file); if (st->opts.default_permissions && - chmod(get_tempfile_path(tab_file), st->opts.default_permissions) < 0) { + chmod(tab_file.path, st->opts.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; } - wr = reftable_new_writer(reftable_fd_write, reftable_fd_flush, - &tab_fd, &st->opts); + writer.fd = tab_file.fd; + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush, + &writer, &st->opts); + if (err < 0) + goto done; + err = stack_write_compact(st, wr, first, last, config); if (err < 0) goto done; @@ -912,18 +1028,18 @@ static int stack_compact_locked(struct reftable_stack *st, if (err < 0) goto done; - err = close_tempfile_gently(tab_file); + err = tmpfile_close(&tab_file); if (err < 0) goto done; *tab_file_out = tab_file; - tab_file = NULL; + tab_file = REFTABLE_TMPFILE_INIT; done: - delete_tempfile(&tab_file); + tmpfile_delete(&tab_file); reftable_writer_free(wr); - strbuf_release(&next_name); - strbuf_release(&tab_file_path); + reftable_buf_release(&next_name); + reftable_buf_release(&tab_file_path); return err; } @@ -942,15 +1058,20 @@ static int stack_write_compact(struct reftable_stack *st, for (size_t i = first; i <= last; i++) st->stats.bytes += st->readers[i]->size; - reftable_writer_set_limits(wr, st->readers[first]->min_update_index, - st->readers[last]->max_update_index); + err = reftable_writer_set_limits(wr, st->readers[first]->min_update_index, + st->readers[last]->max_update_index); + if (err < 0) + goto done; err = reftable_merged_table_new(&mt, st->readers + first, subtabs_len, st->opts.hash_id); if (err < 0) goto done; - merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + err = merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + if (err < 0) + goto done; + err = reftable_iterator_seek_ref(&it, ""); if (err < 0) goto done; @@ -975,7 +1096,10 @@ static int stack_write_compact(struct reftable_stack *st, } reftable_iterator_destroy(&it); - merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); + err = merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); + if (err < 0) + goto done; + err = reftable_iterator_seek_log(&it, ""); if (err < 0) goto done; @@ -1041,13 +1165,13 @@ static int stack_compact_range(struct reftable_stack *st, struct reftable_log_expiry_config *expiry, unsigned int flags) { - struct strbuf tables_list_buf = STRBUF_INIT; - struct strbuf new_table_name = STRBUF_INIT; - struct strbuf new_table_path = STRBUF_INIT; - struct strbuf table_name = STRBUF_INIT; - struct lock_file tables_list_lock = LOCK_INIT; - struct lock_file *table_locks = NULL; - struct tempfile *new_table = NULL; + struct reftable_buf tables_list_buf = REFTABLE_BUF_INIT; + struct reftable_buf new_table_name = REFTABLE_BUF_INIT; + struct reftable_buf new_table_path = REFTABLE_BUF_INIT; + struct reftable_buf table_name = REFTABLE_BUF_INIT; + struct reftable_flock tables_list_lock = REFTABLE_FLOCK_INIT; + struct reftable_flock *table_locks = NULL; + struct reftable_tmpfile new_table = REFTABLE_TMPFILE_INIT; int is_empty_table = 0, err = 0; size_t first_to_replace, last_to_replace; size_t i, nlocks = 0; @@ -1064,10 +1188,7 @@ static int stack_compact_range(struct reftable_stack *st, * Hold the lock so that we can read "tables.list" and lock all tables * which are part of the user-specified range. */ - err = hold_lock_file_for_update_timeout(&tables_list_lock, - st->list_file, - LOCK_NO_DEREF, - st->opts.lock_timeout_ms); + err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) err = REFTABLE_LOCK_ERROR; @@ -1090,12 +1211,20 @@ static int stack_compact_range(struct reftable_stack *st, * older process is still busy compacting tables which are preexisting * from the point of view of the newer process. */ - REFTABLE_CALLOC_ARRAY(table_locks, last - first + 1); + REFTABLE_ALLOC_ARRAY(table_locks, last - first + 1); + if (!table_locks) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + for (i = 0; i < last - first + 1; i++) + table_locks[i] = REFTABLE_FLOCK_INIT; + for (i = last + 1; i > first; i--) { - stack_filename(&table_name, st, reader_name(st->readers[i - 1])); + err = stack_filename(&table_name, st, reader_name(st->readers[i - 1])); + if (err < 0) + goto done; - err = hold_lock_file_for_update(&table_locks[nlocks], - table_name.buf, LOCK_NO_DEREF); + err = flock_acquire(&table_locks[nlocks], table_name.buf, 0); if (err < 0) { /* * When the table is locked already we may do a @@ -1131,7 +1260,7 @@ static int stack_compact_range(struct reftable_stack *st, * run into file descriptor exhaustion when we compress a lot * of tables. */ - err = close_lock_file_gently(&table_locks[nlocks++]); + err = flock_close(&table_locks[nlocks++]); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1143,7 +1272,7 @@ static int stack_compact_range(struct reftable_stack *st, * "tables.list" lock while compacting the locked tables. This allows * concurrent updates to the stack to proceed. */ - err = rollback_lock_file(&tables_list_lock); + err = flock_release(&tables_list_lock); if (err < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1166,10 +1295,7 @@ static int stack_compact_range(struct reftable_stack *st, * "tables.list". We'll then replace the compacted range of tables with * the new table. */ - err = hold_lock_file_for_update_timeout(&tables_list_lock, - st->list_file, - LOCK_NO_DEREF, - st->opts.lock_timeout_ms); + err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) err = REFTABLE_LOCK_ERROR; @@ -1179,7 +1305,7 @@ static int stack_compact_range(struct reftable_stack *st, } if (st->opts.default_permissions) { - if (chmod(get_lock_file_path(&tables_list_lock), + if (chmod(tables_list_lock.path, st->opts.default_permissions) < 0) { err = REFTABLE_IO_ERROR; goto done; @@ -1274,8 +1400,18 @@ static int stack_compact_range(struct reftable_stack *st, * thus have to allocate `readers_len + 1` many entries. */ REFTABLE_CALLOC_ARRAY(names, st->merged->readers_len + 1); - for (size_t i = 0; i < st->merged->readers_len; i++) - names[i] = xstrdup(st->readers[i]->name); + if (!names) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + + for (size_t i = 0; i < st->merged->readers_len; i++) { + names[i] = reftable_strdup(st->readers[i]->name); + if (!names[i]) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto done; + } + } first_to_replace = first; last_to_replace = last; } @@ -1285,16 +1421,22 @@ static int stack_compact_range(struct reftable_stack *st, * it into place now. */ if (!is_empty_table) { - format_name(&new_table_name, st->readers[first]->min_update_index, - st->readers[last]->max_update_index); - strbuf_addstr(&new_table_name, ".ref"); - stack_filename(&new_table_path, st, new_table_name.buf); + err = format_name(&new_table_name, st->readers[first]->min_update_index, + st->readers[last]->max_update_index); + if (err < 0) + goto done; - err = rename_tempfile(&new_table, new_table_path.buf); - if (err < 0) { - err = REFTABLE_IO_ERROR; + err = reftable_buf_addstr(&new_table_name, ".ref"); + if (err < 0) + goto done; + + err = stack_filename(&new_table_path, st, new_table_name.buf); + if (err < 0) + goto done; + + err = tmpfile_rename(&new_table, new_table_path.buf); + if (err < 0) goto done; - } } /* @@ -1302,14 +1444,23 @@ static int stack_compact_range(struct reftable_stack *st, * have just written. In case the compacted table became empty we * simply skip writing it. */ - for (i = 0; i < first_to_replace; i++) - strbuf_addf(&tables_list_buf, "%s\n", names[i]); - if (!is_empty_table) - strbuf_addf(&tables_list_buf, "%s\n", new_table_name.buf); - for (i = last_to_replace + 1; names[i]; i++) - strbuf_addf(&tables_list_buf, "%s\n", names[i]); - - err = write_in_full(get_lock_file_fd(&tables_list_lock), + for (i = 0; i < first_to_replace; i++) { + if ((err = reftable_buf_addstr(&tables_list_buf, names[i])) < 0 || + (err = reftable_buf_addstr(&tables_list_buf, "\n")) < 0) + goto done; + } + if (!is_empty_table) { + if ((err = reftable_buf_addstr(&tables_list_buf, new_table_name.buf)) < 0 || + (err = reftable_buf_addstr(&tables_list_buf, "\n")) < 0) + goto done; + } + for (i = last_to_replace + 1; names[i]; i++) { + if ((err = reftable_buf_addstr(&tables_list_buf, names[i])) < 0 || + (err = reftable_buf_addstr(&tables_list_buf, "\n")) < 0) + goto done; + } + + err = write_in_full(tables_list_lock.fd, tables_list_buf.buf, tables_list_buf.len); if (err < 0) { err = REFTABLE_IO_ERROR; @@ -1317,14 +1468,14 @@ static int stack_compact_range(struct reftable_stack *st, goto done; } - err = fsync_component(FSYNC_COMPONENT_REFERENCE, get_lock_file_fd(&tables_list_lock)); + err = stack_fsync(&st->opts, tables_list_lock.fd); if (err < 0) { err = REFTABLE_IO_ERROR; unlink(new_table_path.buf); goto done; } - err = commit_lock_file(&tables_list_lock); + err = flock_commit(&tables_list_lock); if (err < 0) { err = REFTABLE_IO_ERROR; unlink(new_table_path.buf); @@ -1345,23 +1496,28 @@ static int stack_compact_range(struct reftable_stack *st, * readers, so it is expected that unlinking tables may fail. */ for (i = 0; i < nlocks; i++) { - struct lock_file *table_lock = &table_locks[i]; - char *table_path = get_locked_file_path(table_lock); - unlink(table_path); - free(table_path); + struct reftable_flock *table_lock = &table_locks[i]; + + reftable_buf_reset(&table_name); + err = reftable_buf_add(&table_name, table_lock->path, + strlen(table_lock->path) - strlen(".lock")); + if (err) + continue; + + unlink(table_name.buf); } done: - rollback_lock_file(&tables_list_lock); + flock_release(&tables_list_lock); for (i = 0; table_locks && i < nlocks; i++) - rollback_lock_file(&table_locks[i]); + flock_release(&table_locks[i]); reftable_free(table_locks); - delete_tempfile(&new_table); - strbuf_release(&new_table_name); - strbuf_release(&new_table_path); - strbuf_release(&tables_list_buf); - strbuf_release(&table_name); + tmpfile_delete(&new_table); + reftable_buf_release(&new_table_name); + reftable_buf_release(&new_table_path); + reftable_buf_release(&tables_list_buf); + reftable_buf_release(&table_name); free_names(names); if (err == REFTABLE_LOCK_ERROR) @@ -1460,11 +1616,13 @@ struct segment suggest_compaction_segment(uint64_t *sizes, size_t n, static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st) { - int version = (st->opts.hash_id == GIT_SHA1_FORMAT_ID) ? 1 : 2; + int version = (st->opts.hash_id == REFTABLE_HASH_SHA1) ? 1 : 2; int overhead = header_size(version) - 1; uint64_t *sizes; REFTABLE_CALLOC_ARRAY(sizes, st->merged->readers_len); + if (!sizes) + return NULL; for (size_t i = 0; i < st->merged->readers_len; i++) sizes[i] = st->readers[i]->size - overhead; @@ -1474,11 +1632,20 @@ static uint64_t *stack_table_sizes_for_compaction(struct reftable_stack *st) int reftable_stack_auto_compact(struct reftable_stack *st) { - uint64_t *sizes = stack_table_sizes_for_compaction(st); - struct segment seg = - suggest_compaction_segment(sizes, st->merged->readers_len, - st->opts.auto_compaction_factor); + struct segment seg; + uint64_t *sizes; + + if (st->merged->readers_len < 2) + return 0; + + sizes = stack_table_sizes_for_compaction(st); + if (!sizes) + return REFTABLE_OUT_OF_MEMORY_ERROR; + + seg = suggest_compaction_segment(sizes, st->merged->readers_len, + st->opts.auto_compaction_factor); reftable_free(sizes); + if (segment_size(&seg) > 0) return stack_compact_range(st, seg.start, seg.end - 1, NULL, STACK_COMPACT_RANGE_BEST_EFFORT); @@ -1498,7 +1665,10 @@ int reftable_stack_read_ref(struct reftable_stack *st, const char *refname, struct reftable_iterator it = { 0 }; int ret; - reftable_merged_table_init_ref_iterator(st->merged, &it); + ret = reftable_merged_table_init_ref_iterator(st->merged, &it); + if (ret) + goto out; + ret = reftable_iterator_seek_ref(&it, refname); if (ret) goto out; @@ -1525,7 +1695,10 @@ int reftable_stack_read_log(struct reftable_stack *st, const char *refname, struct reftable_iterator it = {0}; int err; - reftable_stack_init_log_iterator(st, &it); + err = reftable_stack_init_log_iterator(st, &it); + if (err) + goto done; + err = reftable_iterator_seek_log(&it, refname); if (err) goto done; @@ -1561,8 +1734,11 @@ static void remove_maybe_stale_table(struct reftable_stack *st, uint64_t max, uint64_t update_idx = 0; struct reftable_block_source src = { NULL }; struct reftable_reader *rd = NULL; - struct strbuf table_path = STRBUF_INIT; - stack_filename(&table_path, st, name); + struct reftable_buf table_path = REFTABLE_BUF_INIT; + + err = stack_filename(&table_path, st, name); + if (err < 0) + goto done; err = reftable_block_source_from_file(&src, table_path.buf); if (err < 0) @@ -1579,7 +1755,7 @@ static void remove_maybe_stale_table(struct reftable_stack *st, uint64_t max, unlink(table_path.buf); } done: - strbuf_release(&table_path); + reftable_buf_release(&table_path); } static int reftable_stack_clean_locked(struct reftable_stack *st) @@ -1593,14 +1769,12 @@ static int reftable_stack_clean_locked(struct reftable_stack *st) } while ((d = readdir(dir))) { - int i = 0; int found = 0; if (!is_table_name(d->d_name)) continue; - for (i = 0; !found && i < st->readers_len; i++) { + for (size_t i = 0; !found && i < st->readers_len; i++) found = !strcmp(reader_name(st->readers[i]), d->d_name); - } if (found) continue; @@ -1630,3 +1804,8 @@ int reftable_stack_clean(struct reftable_stack *st) reftable_addition_destroy(add); return err; } + +enum reftable_hash reftable_stack_hash_id(struct reftable_stack *st) +{ + return reftable_merged_table_hash_id(st->merged); +} diff --git a/reftable/system.c b/reftable/system.c new file mode 100644 index 00000000000000..adf8e4d30b823c --- /dev/null +++ b/reftable/system.c @@ -0,0 +1,126 @@ +#include "system.h" +#include "basics.h" +#include "reftable-error.h" +#include "../lockfile.h" +#include "../tempfile.h" + +int tmpfile_from_pattern(struct reftable_tmpfile *out, const char *pattern) +{ + struct tempfile *tempfile; + + tempfile = mks_tempfile(pattern); + if (!tempfile) + return REFTABLE_IO_ERROR; + + out->path = tempfile->filename.buf; + out->fd = tempfile->fd; + out->priv = tempfile; + + return 0; +} + +int tmpfile_close(struct reftable_tmpfile *t) +{ + struct tempfile *tempfile = t->priv; + int ret = close_tempfile_gently(tempfile); + t->fd = -1; + if (ret < 0) + return REFTABLE_IO_ERROR; + return 0; +} + +int tmpfile_delete(struct reftable_tmpfile *t) +{ + struct tempfile *tempfile = t->priv; + int ret = delete_tempfile(&tempfile); + *t = REFTABLE_TMPFILE_INIT; + if (ret < 0) + return REFTABLE_IO_ERROR; + return 0; +} + +int tmpfile_rename(struct reftable_tmpfile *t, const char *path) +{ + struct tempfile *tempfile = t->priv; + int ret = rename_tempfile(&tempfile, path); + *t = REFTABLE_TMPFILE_INIT; + if (ret < 0) + return REFTABLE_IO_ERROR; + return 0; +} + +int flock_acquire(struct reftable_flock *l, const char *target_path, + long timeout_ms) +{ + struct lock_file *lockfile; + int err; + + lockfile = reftable_malloc(sizeof(*lockfile)); + if (!lockfile) + return REFTABLE_OUT_OF_MEMORY_ERROR; + + err = hold_lock_file_for_update_timeout(lockfile, target_path, LOCK_NO_DEREF, + timeout_ms); + if (err < 0) { + reftable_free(lockfile); + if (errno == EEXIST) + return REFTABLE_LOCK_ERROR; + return -1; + } + + l->fd = get_lock_file_fd(lockfile); + l->path = get_lock_file_path(lockfile); + l->priv = lockfile; + + return 0; +} + +int flock_close(struct reftable_flock *l) +{ + struct lock_file *lockfile = l->priv; + int ret; + + if (!lockfile) + return REFTABLE_API_ERROR; + + ret = close_lock_file_gently(lockfile); + l->fd = -1; + if (ret < 0) + return REFTABLE_IO_ERROR; + + return 0; +} + +int flock_release(struct reftable_flock *l) +{ + struct lock_file *lockfile = l->priv; + int ret; + + if (!lockfile) + return 0; + + ret = rollback_lock_file(lockfile); + reftable_free(lockfile); + *l = REFTABLE_FLOCK_INIT; + if (ret < 0) + return REFTABLE_IO_ERROR; + + return 0; +} + +int flock_commit(struct reftable_flock *l) +{ + struct lock_file *lockfile = l->priv; + int ret; + + if (!lockfile) + return REFTABLE_API_ERROR; + + ret = commit_lock_file(lockfile); + reftable_free(lockfile); + *l = REFTABLE_FLOCK_INIT; + if (ret < 0) + return REFTABLE_IO_ERROR; + + return 0; +} diff --git a/reftable/system.h b/reftable/system.h index d0cabd5d171363..d02eacea8f02dd 100644 --- a/reftable/system.h +++ b/reftable/system.h @@ -12,12 +12,91 @@ license that can be found in the LICENSE file or at /* This header glues the reftable library to the rest of Git */ #include "git-compat-util.h" -#include "lockfile.h" -#include "strbuf.h" -#include "tempfile.h" -#include "hash.h" /* hash ID, sizes.*/ -#include "dir.h" /* remove_dir_recursively, for tests.*/ +#include "compat/zlib-compat.h" -int hash_size(uint32_t id); +/* + * An implementation-specific temporary file. By making this specific to the + * implementation it becomes possible to tie temporary files into any kind of + * signal or atexit handlers for cleanup on abnormal situations. + */ +struct reftable_tmpfile { + const char *path; + int fd; + void *priv; +}; +#define REFTABLE_TMPFILE_INIT ((struct reftable_tmpfile) { .fd = -1, }) + +/* + * Create a temporary file from a pattern similar to how mkstemp(3p) would. + * The `pattern` shall not be modified. On success, the structure at `out` has + * been initialized such that it is ready for use. Returns 0 on success, a + * reftable error code on error. + */ +int tmpfile_from_pattern(struct reftable_tmpfile *out, const char *pattern); + +/* + * Close the temporary file's file descriptor without removing the file itself. + * This is a no-op in case the file has already been closed beforehand. Returns + * 0 on success, a reftable error code on error. + */ +int tmpfile_close(struct reftable_tmpfile *t); + +/* + * Close the temporary file and delete it. This is a no-op in case the file has + * already been deleted or renamed beforehand. Returns 0 on success, a reftable + * error code on error. + */ +int tmpfile_delete(struct reftable_tmpfile *t); + +/* + * Rename the temporary file to the provided path. The temporary file must be + * active. Return 0 on success, a reftable error code on error. Deactivates the + * temporary file. + */ +int tmpfile_rename(struct reftable_tmpfile *t, const char *path); + +/* + * An implementation-specific file lock. Same as with `reftable_tmpfile`, + * making this specific to the implementation makes it possible to tie this + * into signal or atexit handlers such that we know to clean up stale locks on + * abnormal exits. + */ +struct reftable_flock { + const char *path; + int fd; + void *priv; +}; +#define REFTABLE_FLOCK_INIT ((struct reftable_flock){ .fd = -1, }) + +/* + * Acquire the lock for the given target path by exclusively creating a file + * with ".lock" appended to it. If that lock exists, we wait up to `timeout_ms` + * to acquire the lock. If `timeout_ms` is 0 we don't wait, if it is negative + * we block indefinitely. + * + * Retrun 0 on success, a reftable error code on error. + */ +int flock_acquire(struct reftable_flock *l, const char *target_path, + long timeout_ms); + +/* + * Close the lockfile's file descriptor without removing the lock itself. This + * is a no-op in case the lockfile has already been closed beforehand. Returns + * 0 on success, a reftable error code on error. + */ +int flock_close(struct reftable_flock *l); + +/* + * Release the lock by unlinking the lockfile. This is a no-op in case the + * lockfile has already been released or committed beforehand. Returns 0 on + * success, a reftable error code on error. + */ +int flock_release(struct reftable_flock *l); + +/* + * Commit the lock by renaming the lockfile into place. Returns 0 on success, a + * reftable error code on error. + */ +int flock_commit(struct reftable_flock *l); #endif diff --git a/reftable/tree.c b/reftable/tree.c index 5ffb2e0d690cad..f4dbe720901e14 100644 --- a/reftable/tree.c +++ b/reftable/tree.c @@ -11,28 +11,44 @@ license that can be found in the LICENSE file or at #include "basics.h" -struct tree_node *tree_search(void *key, struct tree_node **rootp, - int (*compare)(const void *, const void *), - int insert) +struct tree_node *tree_search(struct tree_node *tree, + void *key, + int (*compare)(const void *, const void *)) { int res; + if (!tree) + return NULL; + res = compare(key, tree->key); + if (res < 0) + return tree_search(tree->left, key, compare); + else if (res > 0) + return tree_search(tree->right, key, compare); + return tree; +} + +struct tree_node *tree_insert(struct tree_node **rootp, + void *key, + int (*compare)(const void *, const void *)) +{ + int res; + if (!*rootp) { - if (!insert) { + struct tree_node *n; + + REFTABLE_CALLOC_ARRAY(n, 1); + if (!n) return NULL; - } else { - struct tree_node *n; - REFTABLE_CALLOC_ARRAY(n, 1); - n->key = key; - *rootp = n; - return *rootp; - } + + n->key = key; + *rootp = n; + return *rootp; } res = compare(key, (*rootp)->key); if (res < 0) - return tree_search(key, &(*rootp)->left, compare, insert); + return tree_insert(&(*rootp)->left, key, compare); else if (res > 0) - return tree_search(key, &(*rootp)->right, compare, insert); + return tree_insert(&(*rootp)->right, key, compare); return *rootp; } diff --git a/reftable/tree.h b/reftable/tree.h index fbdd002e23afcf..9604453b6d541a 100644 --- a/reftable/tree.h +++ b/reftable/tree.h @@ -15,12 +15,23 @@ struct tree_node { struct tree_node *left, *right; }; -/* looks for `key` in `rootp` using `compare` as comparison function. If insert - * is set, insert the key if it's not found. Else, return NULL. +/* + * Search the tree for the node matching the given key using `compare` as + * comparison function. Returns the node whose key matches or `NULL` in case + * the key does not exist in the tree. + */ +struct tree_node *tree_search(struct tree_node *tree, + void *key, + int (*compare)(const void *, const void *)); + +/* + * Insert a node into the tree. Returns the newly inserted node if the key does + * not yet exist. Otherwise it returns the preexisting node. Returns `NULL` + * when allocating the new node fails. */ -struct tree_node *tree_search(void *key, struct tree_node **rootp, - int (*compare)(const void *, const void *), - int insert); +struct tree_node *tree_insert(struct tree_node **rootp, + void *key, + int (*compare)(const void *, const void *)); /* performs an infix walk of the tree. */ void infix_walk(struct tree_node *t, void (*action)(void *arg, void *key), diff --git a/reftable/writer.c b/reftable/writer.c index 9d5e6072bc6116..f3ab1035d61d96 100644 --- a/reftable/writer.c +++ b/reftable/writer.c @@ -49,8 +49,14 @@ 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, sizeof(*zeroed)); - int n = w->write(w->write_arg, zeroed, w->pending_padding); + uint8_t *zeroed; + int n; + + zeroed = reftable_calloc(w->pending_padding, sizeof(*zeroed)); + if (!zeroed) + return -1; + + n = w->write(w->write_arg, zeroed, w->pending_padding); if (n < 0) return n; @@ -73,7 +79,7 @@ static void options_set_defaults(struct reftable_write_options *opts) } if (opts->hash_id == 0) { - opts->hash_id = GIT_SHA1_FORMAT_ID; + opts->hash_id = REFTABLE_HASH_SHA1; } if (opts->block_size == 0) { opts->block_size = DEFAULT_BLOCK_SIZE; @@ -82,7 +88,7 @@ static void options_set_defaults(struct reftable_write_options *opts) static int writer_version(struct reftable_writer *w) { - return (w->opts.hash_id == 0 || w->opts.hash_id == GIT_SHA1_FORMAT_ID) ? + return (w->opts.hash_id == 0 || w->opts.hash_id == REFTABLE_HASH_SHA1) ? 1 : 2; } @@ -97,33 +103,56 @@ static int writer_write_header(struct reftable_writer *w, uint8_t *dest) put_be64(dest + 8, w->min_update_index); put_be64(dest + 16, w->max_update_index); if (writer_version(w) == 2) { - put_be32(dest + 24, w->opts.hash_id); + uint32_t hash_id; + + switch (w->opts.hash_id) { + case REFTABLE_HASH_SHA1: + hash_id = REFTABLE_FORMAT_ID_SHA1; + break; + case REFTABLE_HASH_SHA256: + hash_id = REFTABLE_FORMAT_ID_SHA256; + break; + default: + return -1; + } + + put_be32(dest + 24, hash_id); } + return header_size(writer_version(w)); } -static void writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ) +static int writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ) { - int block_start = 0; - if (w->next == 0) { + int block_start = 0, ret; + + if (w->next == 0) block_start = header_size(writer_version(w)); - } - strbuf_reset(&w->last_key); - block_writer_init(&w->block_writer_data, typ, w->block, - w->opts.block_size, block_start, - hash_size(w->opts.hash_id)); + reftable_buf_reset(&w->last_key); + ret = block_writer_init(&w->block_writer_data, typ, w->block, + w->opts.block_size, block_start, + hash_size(w->opts.hash_id)); + if (ret < 0) + return ret; + w->block_writer = &w->block_writer_data; w->block_writer->restart_interval = w->opts.restart_interval; + + return 0; } -struct reftable_writer * -reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t), - int (*flush_func)(void *), - void *writer_arg, const struct reftable_write_options *_opts) +int reftable_writer_new(struct reftable_writer **out, + ssize_t (*writer_func)(void *, const void *, size_t), + int (*flush_func)(void *), + void *writer_arg, const struct reftable_write_options *_opts) { - struct reftable_writer *wp = reftable_calloc(1, sizeof(*wp)); struct reftable_write_options opts = {0}; + struct reftable_writer *wp; + + wp = reftable_calloc(1, sizeof(*wp)); + if (!wp) + return REFTABLE_OUT_OF_MEMORY_ERROR; if (_opts) opts = *_opts; @@ -131,23 +160,43 @@ reftable_new_writer(ssize_t (*writer_func)(void *, const void *, size_t), if (opts.block_size >= (1 << 24)) BUG("configured block size exceeds 16MB"); - strbuf_init(&wp->block_writer_data.last_key, 0); - strbuf_init(&wp->last_key, 0); + reftable_buf_init(&wp->block_writer_data.last_key); + reftable_buf_init(&wp->last_key); + reftable_buf_init(&wp->scratch); REFTABLE_CALLOC_ARRAY(wp->block, opts.block_size); + if (!wp->block) { + reftable_free(wp); + return REFTABLE_OUT_OF_MEMORY_ERROR; + } 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; + *out = wp; + + return 0; } -void reftable_writer_set_limits(struct reftable_writer *w, uint64_t min, +int reftable_writer_set_limits(struct reftable_writer *w, uint64_t min, uint64_t max) { + /* + * Set the min/max update index limits for the reftable writer. + * This must be called before adding any records, since: + * - The 'next' field gets set after writing the first block. + * - The 'last_key' field updates with each new record (but resets + * after sections). + * Returns REFTABLE_API_ERROR if called after writing has begun. + */ + if (w->next || w->last_key.len) + return REFTABLE_API_ERROR; + w->min_update_index = min; w->max_update_index = max; + + return 0; } static void writer_release(struct reftable_writer *w) @@ -158,7 +207,8 @@ static void writer_release(struct reftable_writer *w) block_writer_release(&w->block_writer_data); w->block_writer = NULL; writer_clear_index(w); - strbuf_release(&w->last_key); + reftable_buf_release(&w->last_key); + reftable_buf_release(&w->scratch); } } @@ -169,7 +219,7 @@ void reftable_writer_free(struct reftable_writer *w) } struct obj_index_tree_node { - struct strbuf hash; + struct reftable_buf hash; uint64_t *offsets; size_t offset_len; size_t offset_cap; @@ -177,61 +227,79 @@ struct obj_index_tree_node { #define OBJ_INDEX_TREE_NODE_INIT \ { \ - .hash = STRBUF_INIT \ + .hash = REFTABLE_BUF_INIT \ } static int obj_index_tree_node_compare(const void *a, const void *b) { - return strbuf_cmp(&((const struct obj_index_tree_node *)a)->hash, + return reftable_buf_cmp(&((const struct obj_index_tree_node *)a)->hash, &((const struct obj_index_tree_node *)b)->hash); } -static void writer_index_hash(struct reftable_writer *w, struct strbuf *hash) +static int writer_index_hash(struct reftable_writer *w, struct reftable_buf *hash) { uint64_t off = w->next; - struct obj_index_tree_node want = { .hash = *hash }; + struct obj_index_tree_node *key; + struct tree_node *node; - struct tree_node *node = tree_search(&want, &w->obj_index_tree, - &obj_index_tree_node_compare, 0); - struct obj_index_tree_node *key = NULL; + node = tree_search(w->obj_index_tree, &want, &obj_index_tree_node_compare); if (!node) { struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT; - key = reftable_malloc(sizeof(struct obj_index_tree_node)); + int err; + + key = reftable_malloc(sizeof(*key)); + if (!key) + return REFTABLE_OUT_OF_MEMORY_ERROR; + *key = empty; - strbuf_reset(&key->hash); - strbuf_addbuf(&key->hash, hash); - tree_search((void *)key, &w->obj_index_tree, - &obj_index_tree_node_compare, 1); + reftable_buf_reset(&key->hash); + err = reftable_buf_add(&key->hash, hash->buf, hash->len); + if (err < 0) + return err; + tree_insert(&w->obj_index_tree, key, + &obj_index_tree_node_compare); } else { key = node->key; } - if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off) { - return; - } + if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off) + return 0; - REFTABLE_ALLOC_GROW(key->offsets, key->offset_len + 1, key->offset_cap); + REFTABLE_ALLOC_GROW_OR_NULL(key->offsets, key->offset_len + 1, + key->offset_cap); + if (!key->offsets) + return REFTABLE_OUT_OF_MEMORY_ERROR; key->offsets[key->offset_len++] = off; + + return 0; } static int writer_add_record(struct reftable_writer *w, struct reftable_record *rec) { - struct strbuf key = STRBUF_INIT; int err; - reftable_record_key(rec, &key); - if (strbuf_cmp(&w->last_key, &key) >= 0) { + err = reftable_record_key(rec, &w->scratch); + if (err < 0) + goto done; + + if (reftable_buf_cmp(&w->last_key, &w->scratch) >= 0) { err = REFTABLE_API_ERROR; goto done; } - strbuf_reset(&w->last_key); - strbuf_addbuf(&w->last_key, &key); - if (!w->block_writer) - writer_reinit_block_writer(w, reftable_record_type(rec)); + reftable_buf_reset(&w->last_key); + err = reftable_buf_add(&w->last_key, w->scratch.buf, w->scratch.len); + if (err < 0) + goto done; + + if (!w->block_writer) { + err = writer_reinit_block_writer(w, reftable_record_type(rec)); + if (err < 0) + goto done; + } if (block_writer_type(w->block_writer) != reftable_record_type(rec)) BUG("record of type %d added to writer of type %d", @@ -254,7 +322,9 @@ static int writer_add_record(struct reftable_writer *w, err = writer_flush_block(w); if (err < 0) goto done; - writer_reinit_block_writer(w, reftable_record_type(rec)); + err = writer_reinit_block_writer(w, reftable_record_type(rec)); + if (err < 0) + goto done; /* * Try to add the record to the writer again. If this still fails then @@ -271,7 +341,6 @@ static int writer_add_record(struct reftable_writer *w, } done: - strbuf_release(&key); return err; } @@ -284,11 +353,10 @@ int reftable_writer_add_ref(struct reftable_writer *w, .ref = *ref }, }; - int err = 0; + int err; - if (!ref->refname) - return REFTABLE_API_ERROR; - if (ref->update_index < w->min_update_index || + if (!ref->refname || + ref->update_index < w->min_update_index || ref->update_index > w->max_update_index) return REFTABLE_API_ERROR; @@ -296,24 +364,36 @@ int reftable_writer_add_ref(struct reftable_writer *w, err = writer_add_record(w, &rec); if (err < 0) - return err; + goto out; if (!w->opts.skip_index_objects && reftable_ref_record_val1(ref)) { - struct strbuf h = STRBUF_INIT; - strbuf_add(&h, (char *)reftable_ref_record_val1(ref), - hash_size(w->opts.hash_id)); - writer_index_hash(w, &h); - strbuf_release(&h); + reftable_buf_reset(&w->scratch); + err = reftable_buf_add(&w->scratch, (char *)reftable_ref_record_val1(ref), + hash_size(w->opts.hash_id)); + if (err < 0) + goto out; + + err = writer_index_hash(w, &w->scratch); + if (err < 0) + goto out; } if (!w->opts.skip_index_objects && reftable_ref_record_val2(ref)) { - struct strbuf h = STRBUF_INIT; - strbuf_add(&h, reftable_ref_record_val2(ref), - hash_size(w->opts.hash_id)); - writer_index_hash(w, &h); - strbuf_release(&h); + reftable_buf_reset(&w->scratch); + err = reftable_buf_add(&w->scratch, reftable_ref_record_val2(ref), + hash_size(w->opts.hash_id)); + if (err < 0) + goto out; + + err = writer_index_hash(w, &w->scratch); + if (err < 0) + goto out; } - return 0; + + err = 0; + +out: + return err; } int reftable_writer_add_refs(struct reftable_writer *w, @@ -353,35 +433,57 @@ int reftable_writer_add_log(struct reftable_writer *w, struct reftable_log_record *log) { char *input_log_message = NULL; - struct strbuf cleaned_message = STRBUF_INIT; + struct reftable_buf cleaned_message = REFTABLE_BUF_INIT; int err = 0; if (log->value_type == REFTABLE_LOG_DELETION) return reftable_writer_add_log_verbatim(w, log); + /* + * Verify only the upper limit of the update_index. Each reflog entry + * is tied to a specific update_index. Entries in the reflog can be + * replaced by adding a new entry with the same update_index, + * effectively canceling the old one. + * + * Consequently, reflog updates may include update_index values lower + * than the writer's min_update_index. + */ + if (log->update_index > w->max_update_index) + return REFTABLE_API_ERROR; + if (!log->refname) return REFTABLE_API_ERROR; input_log_message = log->value.update.message; if (!w->opts.exact_log_message && log->value.update.message) { - strbuf_addstr(&cleaned_message, log->value.update.message); + err = reftable_buf_addstr(&cleaned_message, log->value.update.message); + if (err < 0) + goto done; + while (cleaned_message.len && - cleaned_message.buf[cleaned_message.len - 1] == '\n') - strbuf_setlen(&cleaned_message, - cleaned_message.len - 1); + cleaned_message.buf[cleaned_message.len - 1] == '\n') { + err = reftable_buf_setlen(&cleaned_message, + cleaned_message.len - 1); + if (err < 0) + goto done; + } if (strchr(cleaned_message.buf, '\n')) { /* multiple lines not allowed. */ err = REFTABLE_API_ERROR; goto done; } - strbuf_addstr(&cleaned_message, "\n"); + + err = reftable_buf_addstr(&cleaned_message, "\n"); + if (err < 0) + goto done; + log->value.update.message = cleaned_message.buf; } err = reftable_writer_add_log_verbatim(w, log); log->value.update.message = input_log_message; done: - strbuf_release(&cleaned_message); + reftable_buf_release(&cleaned_message); return err; } @@ -436,7 +538,9 @@ static int writer_finish_section(struct reftable_writer *w) max_level++; index_start = w->next; - writer_reinit_block_writer(w, BLOCK_TYPE_INDEX); + err = writer_reinit_block_writer(w, BLOCK_TYPE_INDEX); + if (err < 0) + return err; idx = w->index; idx_len = w->index_len; @@ -462,7 +566,7 @@ static int writer_finish_section(struct reftable_writer *w) return err; for (i = 0; i < idx_len; i++) - strbuf_release(&idx[i].last_key); + reftable_buf_release(&idx[i].last_key); reftable_free(idx); } @@ -479,14 +583,14 @@ static int writer_finish_section(struct reftable_writer *w) bstats->max_index_level = max_level; /* Reinit lastKey, as the next section can start with any key. */ - strbuf_reset(&w->last_key); + reftable_buf_reset(&w->last_key); return 0; } struct common_prefix_arg { - struct strbuf *last; - int max; + struct reftable_buf *last; + size_t max; }; static void update_common(void *void_arg, void *key) @@ -494,10 +598,9 @@ static void update_common(void *void_arg, void *key) struct common_prefix_arg *arg = void_arg; struct obj_index_tree_node *entry = key; if (arg->last) { - int n = common_prefix_size(&entry->hash, arg->last); - if (n > arg->max) { + size_t n = common_prefix_size(&entry->hash, arg->last); + if (n > arg->max) arg->max = n; - } } arg->last = &entry->hash; } @@ -530,7 +633,10 @@ static void write_object_record(void *void_arg, void *key) if (arg->err < 0) goto done; - writer_reinit_block_writer(arg->w, BLOCK_TYPE_OBJ); + arg->err = writer_reinit_block_writer(arg->w, BLOCK_TYPE_OBJ); + if (arg->err < 0) + goto done; + arg->err = block_writer_add(arg->w->block_writer, &rec); if (arg->err == 0) goto done; @@ -548,8 +654,8 @@ static void object_record_free(void *void_arg UNUSED, void *key) { struct obj_index_tree_node *entry = key; - FREE_AND_NULL(entry->offsets); - strbuf_release(&entry->hash); + REFTABLE_FREE_AND_NULL(entry->offsets); + reftable_buf_release(&entry->hash); reftable_free(entry); } @@ -559,16 +665,18 @@ static int writer_dump_object_index(struct reftable_writer *w) struct common_prefix_arg common = { .max = 1, /* obj_id_len should be >= 2. */ }; - if (w->obj_index_tree) { + int err; + + if (w->obj_index_tree) infix_walk(w->obj_index_tree, &update_common, &common); - } w->stats.object_id_len = common.max + 1; - writer_reinit_block_writer(w, BLOCK_TYPE_OBJ); + err = writer_reinit_block_writer(w, BLOCK_TYPE_OBJ); + if (err < 0) + return err; - if (w->obj_index_tree) { + if (w->obj_index_tree) infix_walk(w->obj_index_tree, &write_object_record, &closure); - } if (closure.err < 0) return closure.err; @@ -661,8 +769,8 @@ int reftable_writer_close(struct reftable_writer *w) static void writer_clear_index(struct reftable_writer *w) { for (size_t i = 0; w->index && i < w->index_len; i++) - strbuf_release(&w->index[i].last_key); - FREE_AND_NULL(w->index); + reftable_buf_release(&w->index[i].last_key); + REFTABLE_FREE_AND_NULL(w->index); w->index_len = 0; w->index_cap = 0; } @@ -670,7 +778,7 @@ static void writer_clear_index(struct reftable_writer *w) static int writer_flush_nonempty_block(struct reftable_writer *w) { struct reftable_index_record index_record = { - .last_key = STRBUF_INIT, + .last_key = REFTABLE_BUF_INIT, }; uint8_t typ = block_writer_type(w->block_writer); struct reftable_block_stats *bstats; @@ -725,10 +833,16 @@ static int writer_flush_nonempty_block(struct reftable_writer *w) * Note that this also applies when flushing index blocks, in which * case we will end up with a multi-level index. */ - REFTABLE_ALLOC_GROW(w->index, w->index_len + 1, w->index_cap); + REFTABLE_ALLOC_GROW_OR_NULL(w->index, w->index_len + 1, w->index_cap); + if (!w->index) + return REFTABLE_OUT_OF_MEMORY_ERROR; + index_record.offset = w->next; - strbuf_reset(&index_record.last_key); - strbuf_addbuf(&index_record.last_key, &w->block_writer->last_key); + reftable_buf_reset(&index_record.last_key); + err = reftable_buf_add(&index_record.last_key, w->block_writer->last_key.buf, + w->block_writer->last_key.len); + if (err < 0) + return err; w->index[w->index_len] = index_record; w->index_len++; diff --git a/reftable/writer.h b/reftable/writer.h index 8d0df9cc528dba..1f4788a430c52c 100644 --- a/reftable/writer.h +++ b/reftable/writer.h @@ -19,7 +19,9 @@ struct reftable_writer { int (*flush)(void *); void *write_arg; int pending_padding; - struct strbuf last_key; + struct reftable_buf last_key; + /* Scratch buffer used to avoid allocations. */ + struct reftable_buf scratch; /* offset of next block to write. */ uint64_t next; diff --git a/remote-curl.c b/remote-curl.c index 4adcf25ed6eeb5..1273507a96cae9 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "git-curl-compat.h" @@ -347,7 +348,7 @@ static struct ref *parse_info_refs(struct discovery *heads) ref->next = refs; refs = ref; } else { - free(ref); + free_one_ref(ref); } return refs; @@ -941,7 +942,7 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece do { err = probe_rpc(rpc, &results); if (err == HTTP_REAUTH) - credential_fill(&http_auth, 0); + credential_fill(the_repository, &http_auth, 0); } while (err == HTTP_REAUTH); if (err != HTTP_OK) return -1; @@ -1063,7 +1064,7 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece rpc->any_written = 0; err = run_slot(slot, NULL); if (err == HTTP_REAUTH && !large_request) { - credential_fill(&http_auth, 0); + credential_fill(the_repository, &http_auth, 0); curl_slist_free_all(headers); goto retry; } diff --git a/remote.c b/remote.c index 390a03c2643db6..e609cf5c56a772 100644 --- a/remote.c +++ b/remote.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -24,6 +25,7 @@ #include "advice.h" #include "connect.h" #include "parse-options.h" +#include "transport.h" enum map_direction { FROM_SRC, FROM_DST }; @@ -143,6 +145,7 @@ static struct remote *make_remote(struct remote_state *remote_state, ret->name = xstrndup(name, len); refspec_init(&ret->push, REFSPEC_PUSH); refspec_init(&ret->fetch, REFSPEC_FETCH); + string_list_init_dup(&ret->server_options); ALLOC_GROW(remote_state->remotes, remote_state->remotes_nr + 1, remote_state->remotes_alloc); @@ -166,6 +169,7 @@ static void remote_clear(struct remote *remote) free((char *)remote->uploadpack); FREE_AND_NULL(remote->http_proxy); FREE_AND_NULL(remote->http_proxy_authmethod); + string_list_clear(&remote->server_options, 0); } static void add_merge(struct branch *branch, const char *name) @@ -290,6 +294,7 @@ static void add_instead_of(struct rewrite *rewrite, const char *instead_of) rewrite->instead_of_nr++; } +#ifndef WITH_BREAKING_CHANGES static const char *skip_spaces(const char *s) { while (isspace(*s)) @@ -297,14 +302,33 @@ static const char *skip_spaces(const char *s) return s; } +static void warn_about_deprecated_remote_type(const char *type, + const struct remote *remote) +{ + warning(_("reading remote from \"%s/%s\", which is nominated for removal.\n" + "\n" + "If you still use the \"remotes/\" directory it is recommended to\n" + "migrate to config-based remotes:\n" + "\n" + "\tgit remote rename %s %s\n" + "\n" + "If you cannot, please let us know why you still need to use it by\n" + "sending an e-mail to <git@vger.kernel.org>."), + type, remote->name, remote->name, remote->name); +} + static void read_remotes_file(struct remote_state *remote_state, struct remote *remote) { struct strbuf buf = STRBUF_INIT; - FILE *f = fopen_or_warn(git_path("remotes/%s", remote->name), "r"); + FILE *f = fopen_or_warn(repo_git_path_append(the_repository, &buf, + "remotes/%s", remote->name), "r"); if (!f) - return; + goto out; + + warn_about_deprecated_remote_type("remotes", remote); + remote->configured_in_repo = 1; remote->origin = REMOTE_REMOTES; while (strbuf_getline(&buf, f) != EOF) { @@ -320,8 +344,10 @@ static void read_remotes_file(struct remote_state *remote_state, else if (skip_prefix(buf.buf, "Pull:", &v)) refspec_append(&remote->fetch, skip_spaces(v)); } - strbuf_release(&buf); fclose(f); + +out: + strbuf_release(&buf); } static void read_branches_file(struct remote_state *remote_state, @@ -329,18 +355,19 @@ static void read_branches_file(struct remote_state *remote_state, { char *frag, *to_free = NULL; struct strbuf buf = STRBUF_INIT; - FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r"); + FILE *f = fopen_or_warn(repo_git_path_append(the_repository, &buf, + "branches/%s", remote->name), "r"); if (!f) - return; + goto out; + + warn_about_deprecated_remote_type("branches", remote); strbuf_getline_lf(&buf, f); fclose(f); strbuf_trim(&buf); - if (!buf.len) { - strbuf_release(&buf); - return; - } + if (!buf.len) + goto out; remote->configured_in_repo = 1; remote->origin = REMOTE_BRANCHES; @@ -368,9 +395,11 @@ static void read_branches_file(struct remote_state *remote_state, refspec_appendf(&remote->push, "HEAD:refs/heads/%s", frag); remote->fetch_tags = 1; /* always auto-follow */ +out: strbuf_release(&buf); free(to_free); } +#endif /* WITH_BREAKING_CHANGES */ static int handle_config(const char *key, const char *value, const struct config_context *ctx, void *cb) @@ -508,6 +537,27 @@ static int handle_config(const char *key, const char *value, } else if (!strcmp(subkey, "vcs")) { FREE_AND_NULL(remote->foreign_vcs); return git_config_string(&remote->foreign_vcs, key, value); + } else if (!strcmp(subkey, "serveroption")) { + return parse_transport_option(key, value, + &remote->server_options); + } else if (!strcmp(subkey, "followremotehead")) { + const char *no_warn_branch; + if (!strcmp(value, "never")) + remote->follow_remote_head = FOLLOW_REMOTE_NEVER; + else if (!strcmp(value, "create")) + remote->follow_remote_head = FOLLOW_REMOTE_CREATE; + else if (!strcmp(value, "warn")) { + remote->follow_remote_head = FOLLOW_REMOTE_WARN; + remote->no_warn_branch = NULL; + } else if (skip_prefix(value, "warn-if-not-", &no_warn_branch)) { + remote->follow_remote_head = FOLLOW_REMOTE_WARN; + remote->no_warn_branch = no_warn_branch; + } else if (!strcmp(value, "always")) { + remote->follow_remote_head = FOLLOW_REMOTE_ALWAYS; + } else { + warning(_("unrecognized followRemoteHEAD value '%s' ignored"), + value); + } } return 0; } @@ -566,6 +616,7 @@ static void read_config(struct repository *repo, int early) alias_all_urls(repo->remote_state); } +#ifndef WITH_BREAKING_CHANGES static int valid_remote_nick(const char *name) { if (!name[0] || is_dot_or_dotdot(name)) @@ -577,6 +628,7 @@ static int valid_remote_nick(const char *name) return 0; return 1; } +#endif /* WITH_BREAKING_CHANGES */ static const char *remotes_remote_for_branch(struct remote_state *remote_state, struct branch *branch, @@ -719,12 +771,14 @@ remotes_remote_get_1(struct remote_state *remote_state, const char *name, &name_given); ret = make_remote(remote_state, name, 0); +#ifndef WITH_BREAKING_CHANGES if (valid_remote_nick(name) && have_git_dir()) { if (!valid_remote(ret)) read_remotes_file(remote_state, ret); if (!valid_remote(ret)) read_branches_file(remote_state, ret); } +#endif /* WITH_BREAKING_CHANGES */ if (name_given && !valid_remote(ret)) add_url_alias(remote_state, ret, name); if (!valid_remote(ret)) @@ -868,210 +922,23 @@ struct strvec *push_url_of_remote(struct remote *remote) return remote->pushurl.nr ? &remote->pushurl : &remote->url; } -static int match_name_with_pattern(const char *key, const char *name, - const char *value, char **result) -{ - const char *kstar = strchr(key, '*'); - size_t klen; - size_t ksuffixlen; - size_t namelen; - int ret; - if (!kstar) - die(_("key '%s' of pattern had no '*'"), key); - klen = kstar - key; - ksuffixlen = strlen(kstar + 1); - namelen = strlen(name); - ret = !strncmp(name, key, klen) && namelen >= klen + ksuffixlen && - !memcmp(name + namelen - ksuffixlen, kstar + 1, ksuffixlen); - if (ret && value) { - struct strbuf sb = STRBUF_INIT; - const char *vstar = strchr(value, '*'); - if (!vstar) - die(_("value '%s' of pattern has no '*'"), value); - strbuf_add(&sb, value, vstar - value); - strbuf_add(&sb, name + klen, namelen - klen - ksuffixlen); - strbuf_addstr(&sb, vstar + 1); - *result = strbuf_detach(&sb, NULL); - } - return ret; -} - -static int refspec_match(const struct refspec_item *refspec, - const char *name) +void ref_push_report_free(struct ref_push_report *report) { - if (refspec->pattern) - return match_name_with_pattern(refspec->src, name, NULL, NULL); + while (report) { + struct ref_push_report *next = report->next; - return !strcmp(refspec->src, name); -} + free(report->ref_name); + free(report->old_oid); + free(report->new_oid); + free(report); -int omit_name_by_refspec(const char *name, struct refspec *rs) -{ - int i; - - for (i = 0; i < rs->nr; i++) { - if (rs->items[i].negative && refspec_match(&rs->items[i], name)) - return 1; + report = next; } - return 0; -} - -struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs) -{ - struct ref **tail; - - for (tail = &ref_map; *tail; ) { - struct ref *ref = *tail; - - if (omit_name_by_refspec(ref->name, rs)) { - *tail = ref->next; - free(ref->peer_ref); - free(ref); - } else - tail = &ref->next; - } - - return ref_map; -} - -static int query_matches_negative_refspec(struct refspec *rs, struct refspec_item *query) -{ - int i, matched_negative = 0; - int find_src = !query->src; - struct string_list reversed = STRING_LIST_INIT_DUP; - const char *needle = find_src ? query->dst : query->src; - - /* - * Check whether the queried ref matches any negative refpsec. If so, - * then we should ultimately treat this as not matching the query at - * all. - * - * Note that negative refspecs always match the source, but the query - * item uses the destination. To handle this, we apply pattern - * refspecs in reverse to figure out if the query source matches any - * of the negative refspecs. - * - * The first loop finds and expands all positive refspecs - * matched by the queried ref. - * - * The second loop checks if any of the results of the first loop - * match any negative refspec. - */ - for (i = 0; i < rs->nr; i++) { - struct refspec_item *refspec = &rs->items[i]; - char *expn_name; - - if (refspec->negative) - continue; - - /* Note the reversal of src and dst */ - if (refspec->pattern) { - const char *key = refspec->dst ? refspec->dst : refspec->src; - const char *value = refspec->src; - - if (match_name_with_pattern(key, needle, value, &expn_name)) - string_list_append_nodup(&reversed, expn_name); - } else if (refspec->matching) { - /* For the special matching refspec, any query should match */ - string_list_append(&reversed, needle); - } else if (!refspec->src) { - BUG("refspec->src should not be null here"); - } else if (!strcmp(needle, refspec->src)) { - string_list_append(&reversed, refspec->src); - } - } - - for (i = 0; !matched_negative && i < reversed.nr; i++) { - if (omit_name_by_refspec(reversed.items[i].string, rs)) - matched_negative = 1; - } - - string_list_clear(&reversed, 0); - - return matched_negative; -} - -static void query_refspecs_multiple(struct refspec *rs, - struct refspec_item *query, - struct string_list *results) -{ - int i; - int find_src = !query->src; - - if (find_src && !query->dst) - BUG("query_refspecs_multiple: need either src or dst"); - - if (query_matches_negative_refspec(rs, query)) - return; - - for (i = 0; i < rs->nr; i++) { - struct refspec_item *refspec = &rs->items[i]; - const char *key = find_src ? refspec->dst : refspec->src; - const char *value = find_src ? refspec->src : refspec->dst; - const char *needle = find_src ? query->dst : query->src; - char **result = find_src ? &query->src : &query->dst; - - if (!refspec->dst || refspec->negative) - continue; - if (refspec->pattern) { - if (match_name_with_pattern(key, needle, value, result)) - string_list_append_nodup(results, *result); - } else if (!strcmp(needle, key)) { - string_list_append(results, value); - } - } -} - -int query_refspecs(struct refspec *rs, struct refspec_item *query) -{ - int i; - int find_src = !query->src; - const char *needle = find_src ? query->dst : query->src; - char **result = find_src ? &query->src : &query->dst; - - if (find_src && !query->dst) - BUG("query_refspecs: need either src or dst"); - - if (query_matches_negative_refspec(rs, query)) - return -1; - - for (i = 0; i < rs->nr; i++) { - struct refspec_item *refspec = &rs->items[i]; - const char *key = find_src ? refspec->dst : refspec->src; - const char *value = find_src ? refspec->src : refspec->dst; - - if (!refspec->dst || refspec->negative) - continue; - if (refspec->pattern) { - if (match_name_with_pattern(key, needle, value, result)) { - query->force = refspec->force; - return 0; - } - } else if (!strcmp(needle, key)) { - *result = xstrdup(value); - query->force = refspec->force; - return 0; - } - } - return -1; -} - -char *apply_refspecs(struct refspec *rs, const char *name) -{ - struct refspec_item query; - - memset(&query, 0, sizeof(struct refspec_item)); - query.src = (char *)name; - - if (query_refspecs(rs, &query)) - return NULL; - - return query.dst; } int remote_find_tracking(struct remote *remote, struct refspec_item *refspec) { - return query_refspecs(&remote->fetch, refspec); + return refspec_find_match(&remote->fetch, refspec); } static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen, @@ -1122,6 +989,7 @@ void free_one_ref(struct ref *ref) if (!ref) return; free_one_ref(ref->peer_ref); + ref_push_report_free(ref->report); free(ref->remote_status); free(ref->tracking_ref); free(ref->symref); @@ -1194,7 +1062,7 @@ int count_refspec_match(const char *pattern, } } -static void tail_link_ref(struct ref *ref, struct ref ***tail) +void tail_link_ref(struct ref *ref, struct ref ***tail) { **tail = ref; while (ref->next) @@ -1457,9 +1325,9 @@ static char *get_ref_match(const struct refspec *rs, const struct ref *ref, const char *dst_side = item->dst ? item->dst : item->src; int match; if (direction == FROM_SRC) - match = match_name_with_pattern(item->src, ref->name, dst_side, &name); + match = match_refname_with_pattern(item->src, ref->name, dst_side, &name); else - match = match_name_with_pattern(dst_side, ref->name, item->src, &name); + match = match_refname_with_pattern(dst_side, ref->name, item->src, &name); if (match) { matching_refs = i; break; @@ -1495,7 +1363,7 @@ static struct ref **tail_ref(struct ref **head) struct tips { struct commit **tip; - int nr, alloc; + size_t nr, alloc; }; static void add_to_tips(struct tips *tips, const struct object_id *oid) @@ -1562,7 +1430,7 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds const int reachable_flag = 1; struct commit_list *found_commits; struct commit **src_commits; - int nr_src_commits = 0, alloc_src_commits = 16; + size_t nr_src_commits = 0, alloc_src_commits = 16; ALLOC_ARRAY(src_commits, alloc_src_commits); for_each_string_list_item(item, &src_tag) { @@ -2077,7 +1945,7 @@ static struct ref *get_expanded_map(const struct ref *remote_refs, if (strchr(ref->name, '^')) continue; /* a dereference item */ - if (match_name_with_pattern(refspec->src, ref->name, + if (match_refname_with_pattern(refspec->src, ref->name, refspec->dst, &expn_name) && !ignore_symref_update(expn_name, &scratch)) { struct ref *cpy = copy_ref(ref); @@ -2495,7 +2363,7 @@ static int get_stale_heads_cb(const char *refname, const char *referent UNUSED, memset(&query, 0, sizeof(struct refspec_item)); query.dst = (char *)refname; - query_refspecs_multiple(info->rs, &query, &matches); + refspec_find_all_matches(info->rs, &query, &matches); if (matches.nr == 0) goto clean_exit; /* No matches */ @@ -2544,7 +2412,7 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map) /* * Compare-and-swap */ -static void clear_cas_option(struct push_cas_option *cas) +void clear_cas_option(struct push_cas_option *cas) { int i; @@ -2833,9 +2701,9 @@ void apply_push_cas(struct push_cas_option *cas, struct remote_state *remote_state_new(void) { - struct remote_state *r = xmalloc(sizeof(*r)); + struct remote_state *r; - memset(r, 0, sizeof(*r)); + CALLOC_ARRAY(r, 1); hashmap_init(&r->remotes_hash, remotes_hash_cmp, NULL, 0); hashmap_init(&r->branches_hash, branches_hash_cmp, NULL, 0); @@ -2963,3 +2831,13 @@ char *relative_url(const char *remote_url, const char *url, free(out); return strbuf_detach(&sb, NULL); } + +int valid_remote_name(const char *name) +{ + int result; + struct strbuf refspec = STRBUF_INIT; + strbuf_addf(&refspec, "refs/heads/test:refs/remotes/%s/test", name); + result = valid_fetch_refspec(refspec.buf); + strbuf_release(&refspec); + return result; +} diff --git a/remote.h b/remote.h index a58713f20ad654..6be5031f64bec7 100644 --- a/remote.h +++ b/remote.h @@ -4,6 +4,7 @@ #include "hash.h" #include "hashmap.h" #include "refspec.h" +#include "string-list.h" #include "strvec.h" struct option; @@ -20,8 +21,10 @@ struct transport_ls_refs_options; enum { REMOTE_UNCONFIGURED = 0, REMOTE_CONFIG, +#ifndef WITH_BREAKING_CHANGES REMOTE_REMOTES, REMOTE_BRANCHES +#endif /* WITH_BREAKING_CHANGES */ }; struct rewrite { @@ -58,6 +61,13 @@ struct remote_state { void remote_state_clear(struct remote_state *remote_state); struct remote_state *remote_state_new(void); + enum follow_remote_head_settings { + FOLLOW_REMOTE_NEVER = -1, + FOLLOW_REMOTE_CREATE = 0, + FOLLOW_REMOTE_WARN = 1, + FOLLOW_REMOTE_ALWAYS = 2, + }; + struct remote { struct hashmap_entry ent; @@ -104,6 +114,11 @@ struct remote { /* The method used for authenticating against `http_proxy`. */ char *http_proxy_authmethod; + + struct string_list server_options; + + enum follow_remote_head_settings follow_remote_head; + const char *no_warn_branch; }; /** @@ -126,13 +141,15 @@ int remote_has_url(struct remote *remote, const char *url); struct strvec *push_url_of_remote(struct remote *remote); struct ref_push_report { - const char *ref_name; + char *ref_name; struct object_id *old_oid; struct object_id *new_oid; unsigned int forced_update:1; struct ref_push_report *next; }; +void ref_push_report_free(struct ref_push_report *); + struct ref { struct ref *next; struct object_id old_oid; @@ -204,6 +221,11 @@ struct ref *alloc_ref(const char *name); struct ref *copy_ref(const struct ref *ref); struct ref *copy_ref_list(const struct ref *ref); int count_refspec_match(const char *, struct ref *refs, struct ref **matched_ref); +/* + * Put a ref in the tail and prepare tail for adding another one. + * *tail is the pointer to the tail of the list of refs. + */ +void tail_link_ref(struct ref *ref, struct ref ***tail); int check_ref_type(const struct ref *ref, int flags); @@ -246,21 +268,6 @@ int resolve_remote_symref(struct ref *ref, struct ref *list); */ struct ref *ref_remove_duplicates(struct ref *ref_map); -/* - * Check whether a name matches any negative refspec in rs. Returns 1 if the - * name matches at least one negative refspec, and 0 otherwise. - */ -int omit_name_by_refspec(const char *name, struct refspec *rs); - -/* - * Remove all entries in the input list which match any negative refspec in - * the refspec list. - */ -struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs); - -int query_refspecs(struct refspec *rs, struct refspec_item *query); -char *apply_refspecs(struct refspec *rs, const char *name); - int check_push_refs(struct ref *src, struct refspec *rs); int match_push_refs(struct ref *src, struct ref **dst, struct refspec *rs, int flags); @@ -409,6 +416,7 @@ struct push_cas_option { }; int parseopt_push_cas_option(const struct option *, const char *arg, int unset); +void clear_cas_option(struct push_cas_option *); int is_empty_cas(const struct push_cas_option *); void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *); @@ -445,4 +453,6 @@ void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *); char *relative_url(const char *remote_url, const char *url, const char *up_path); +int valid_remote_name(const char *name); + #endif diff --git a/repo-settings.c b/repo-settings.c index 4699b4b3650fc3..67e9cfd2e63d9c 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -3,6 +3,8 @@ #include "repo-settings.h" #include "repository.h" #include "midx.h" +#include "pack-objects.h" +#include "setup.h" static void repo_cfg_bool(struct repository *r, const char *key, int *dest, int def) @@ -20,12 +22,12 @@ static void repo_cfg_int(struct repository *r, const char *key, int *dest, void prepare_repo_settings(struct repository *r) { - const struct repo_settings defaults = REPO_SETTINGS_INIT; int experimental; int value; const char *strval; int manyfiles; int read_changed_paths; + unsigned long ulongval; if (!r->gitdir) BUG("Cannot add settings for uninitialized repository"); @@ -33,7 +35,7 @@ void prepare_repo_settings(struct repository *r) if (r->settings.initialized) return; - memcpy(&r->settings, &defaults, sizeof(defaults)); + repo_settings_clear(r); r->settings.initialized++; /* Booleans config or default, cascades to other settings */ @@ -123,6 +125,30 @@ void prepare_repo_settings(struct repository *r) * removed. */ r->settings.command_requires_full_index = 1; + + if (!repo_config_get_ulong(r, "core.deltabasecachelimit", &ulongval)) + r->settings.delta_base_cache_limit = ulongval; + + if (!repo_config_get_ulong(r, "core.packedgitwindowsize", &ulongval)) { + int pgsz_x2 = getpagesize() * 2; + + /* This value must be multiple of (pagesize * 2) */ + ulongval /= pgsz_x2; + if (ulongval < 1) + ulongval = 1; + r->settings.packed_git_window_size = ulongval * pgsz_x2; + } + + if (!repo_config_get_ulong(r, "core.packedgitlimit", &ulongval)) + r->settings.packed_git_limit = ulongval; +} + +void repo_settings_clear(struct repository *r) +{ + struct repo_settings empty = REPO_SETTINGS_INIT; + FREE_AND_NULL(r->settings.fsmonitor); + FREE_AND_NULL(r->settings.hooks_path); + r->settings = empty; } enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo) @@ -149,3 +175,35 @@ int repo_settings_get_warn_ambiguous_refs(struct repository *repo) &repo->settings.warn_ambiguous_refs, 1); return repo->settings.warn_ambiguous_refs; } + +const char *repo_settings_get_hooks_path(struct repository *repo) +{ + if (!repo->settings.hooks_path) + repo_config_get_pathname(repo, "core.hookspath", &repo->settings.hooks_path); + return repo->settings.hooks_path; +} + +int repo_settings_get_shared_repository(struct repository *repo) +{ + if (!repo->settings.shared_repository_initialized) { + const char *var = "core.sharedrepository"; + const char *value; + if (!repo_config_get_value(repo, var, &value)) + repo->settings.shared_repository = git_config_perm(var, value); + else + repo->settings.shared_repository = PERM_UMASK; + repo->settings.shared_repository_initialized = 1; + } + return repo->settings.shared_repository; +} + +void repo_settings_set_shared_repository(struct repository *repo, int value) +{ + repo->settings.shared_repository = value; + repo->settings.shared_repository_initialized = 1; +} + +void repo_settings_reset_shared_repository(struct repository *repo) +{ + repo->settings.shared_repository_initialized = 0; +} diff --git a/repo-settings.h b/repo-settings.h index 51d6156a1172e3..ddc11967e015df 100644 --- a/repo-settings.h +++ b/repo-settings.h @@ -37,6 +37,9 @@ struct repo_settings { int pack_use_bitmap_boundary_traversal; int pack_use_multi_pack_reuse; + int shared_repository; + int shared_repository_initialized; + /* * Does this repository have core.useReplaceRefs=true (on by * default)? This provides a repository-scoped version of this @@ -57,19 +60,37 @@ struct repo_settings { int core_multi_pack_index; int warn_ambiguous_refs; /* lazily loaded via accessor */ + + size_t delta_base_cache_limit; + size_t packed_git_window_size; + size_t packed_git_limit; + + char *hooks_path; }; #define REPO_SETTINGS_INIT { \ + .shared_repository = -1, \ .index_version = -1, \ .core_untracked_cache = UNTRACKED_CACHE_KEEP, \ .fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE, \ .warn_ambiguous_refs = -1, \ + .delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT, \ + .packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE, \ + .packed_git_limit = DEFAULT_PACKED_GIT_LIMIT, \ } void prepare_repo_settings(struct repository *r); +void repo_settings_clear(struct repository *r); /* Read the value for "core.logAllRefUpdates". */ enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo); /* Read the value for "core.warnAmbiguousRefs". */ int repo_settings_get_warn_ambiguous_refs(struct repository *repo); +/* Read the value for "core.hooksPath". */ +const char *repo_settings_get_hooks_path(struct repository *repo); + +/* Read, set or reset the value for "core.sharedRepository". */ +int repo_settings_get_shared_repository(struct repository *repo); +void repo_settings_set_shared_repository(struct repository *repo, int value); +void repo_settings_reset_shared_repository(struct repository *repo); #endif /* REPO_SETTINGS_H */ diff --git a/repository.c b/repository.c index f988b8ae68a6a2..6cbaf2e3daa93a 100644 --- a/repository.c +++ b/repository.c @@ -283,6 +283,7 @@ int repo_init(struct repository *repo, repo_set_compat_hash_algo(repo, format.compat_hash_algo); repo_set_ref_storage_format(repo, format.ref_storage_format); repo->repository_format_worktree_config = format.worktree_config; + repo->repository_format_relative_worktrees = format.relative_worktrees; /* take ownership of format.partial_clone */ repo->repository_format_partial_clone = format.partial_clone; @@ -311,8 +312,8 @@ int repo_submodule_init(struct repository *subrepo, struct strbuf worktree = STRBUF_INIT; int ret = 0; - strbuf_repo_worktree_path(&gitdir, superproject, "%s/.git", path); - strbuf_repo_worktree_path(&worktree, superproject, "%s", path); + repo_worktree_path_append(superproject, &gitdir, "%s/.git", path); + repo_worktree_path_append(superproject, &worktree, "%s", path); if (repo_init(subrepo, gitdir.buf, worktree.buf)) { /* @@ -379,7 +380,7 @@ void repo_clear(struct repository *repo) parsed_object_pool_clear(repo->parsed_objects); FREE_AND_NULL(repo->parsed_objects); - FREE_AND_NULL(repo->settings.fsmonitor); + repo_settings_clear(repo); if (repo->config) { git_configset_clear(repo->config); diff --git a/repository.h b/repository.h index 24a66a496a6ff5..c4c92b2ab9c9e3 100644 --- a/repository.h +++ b/repository.h @@ -150,6 +150,7 @@ struct repository { /* Configurations */ int repository_format_worktree_config; + int repository_format_relative_worktrees; /* Indicate if a repository has a different 'commondir' from 'gitdir' */ unsigned different_commondir:1; diff --git a/rerere.c b/rerere.c index d01e98bf653b04..740e8ad1a0b40a 100644 --- a/rerere.c +++ b/rerere.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -90,16 +91,18 @@ static void assign_variant(struct rerere_id *id) id->variant = variant; } -const char *rerere_path(const struct rerere_id *id, const char *file) +const char *rerere_path(struct strbuf *buf, const struct rerere_id *id, const char *file) { if (!file) - return git_path("rr-cache/%s", rerere_id_hex(id)); + return repo_git_path_replace(the_repository, buf, "rr-cache/%s", + rerere_id_hex(id)); if (id->variant <= 0) - return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); + return repo_git_path_replace(the_repository, buf, "rr-cache/%s/%s", + rerere_id_hex(id), file); - return git_path("rr-cache/%s/%s.%d", - rerere_id_hex(id), file, id->variant); + return repo_git_path_replace(the_repository, buf, "rr-cache/%s/%s.%d", + rerere_id_hex(id), file, id->variant); } static int is_rr_file(const char *name, const char *filename, int *variant) @@ -124,8 +127,12 @@ static int is_rr_file(const char *name, const char *filename, int *variant) static void scan_rerere_dir(struct rerere_dir *rr_dir) { struct dirent *de; - DIR *dir = opendir(git_path("rr-cache/%s", rr_dir->name)); + char *path; + DIR *dir; + path = repo_git_path(the_repository, "rr-cache/%s", rr_dir->name); + dir = opendir(path); + free(path); if (!dir) return; while ((de = readdir(dir)) != NULL) { @@ -357,7 +364,7 @@ static void rerere_strbuf_putconflict(struct strbuf *buf, int ch, size_t size) } static int handle_conflict(struct strbuf *out, struct rerere_io *io, - int marker_size, git_hash_ctx *ctx) + int marker_size, struct git_hash_ctx *ctx) { enum { RR_SIDE_1 = 0, RR_SIDE_2, RR_ORIGINAL @@ -395,12 +402,12 @@ static int handle_conflict(struct strbuf *out, struct rerere_io *io, strbuf_addbuf(out, &two); rerere_strbuf_putconflict(out, '>', marker_size); if (ctx) { - the_hash_algo->update_fn(ctx, one.buf ? - one.buf : "", - one.len + 1); - the_hash_algo->update_fn(ctx, two.buf ? - two.buf : "", - two.len + 1); + git_hash_update(ctx, one.buf ? + one.buf : "", + one.len + 1); + git_hash_update(ctx, two.buf ? + two.buf : "", + two.len + 1); } break; } else if (hunk == RR_SIDE_1) @@ -431,7 +438,7 @@ static int handle_conflict(struct strbuf *out, struct rerere_io *io, */ static int handle_path(unsigned char *hash, struct rerere_io *io, int marker_size) { - git_hash_ctx ctx; + struct git_hash_ctx ctx; struct strbuf buf = STRBUF_INIT, out = STRBUF_INIT; int has_conflicts = 0; if (hash) @@ -452,7 +459,7 @@ static int handle_path(unsigned char *hash, struct rerere_io *io, int marker_siz strbuf_release(&out); if (hash) - the_hash_algo->final_fn(hash, &ctx); + git_hash_final(hash, &ctx); return has_conflicts; } @@ -623,9 +630,10 @@ static int try_merge(struct index_state *istate, { enum ll_merge_result ret; mmfile_t base = {NULL, 0}, other = {NULL, 0}; + struct strbuf buf = STRBUF_INIT; - if (read_mmfile(&base, rerere_path(id, "preimage")) || - read_mmfile(&other, rerere_path(id, "postimage"))) { + if (read_mmfile(&base, rerere_path(&buf, id, "preimage")) || + read_mmfile(&other, rerere_path(&buf, id, "postimage"))) { ret = LL_MERGE_CONFLICT; } else { /* @@ -636,6 +644,7 @@ static int try_merge(struct index_state *istate, istate, NULL); } + strbuf_release(&buf); free(base.ptr); free(other.ptr); @@ -656,6 +665,7 @@ static int merge(struct index_state *istate, const struct rerere_id *id, const c { FILE *f; int ret; + struct strbuf buf = STRBUF_INIT; mmfile_t cur = {NULL, 0}; mmbuffer_t result = {NULL, 0}; @@ -663,8 +673,8 @@ static int merge(struct index_state *istate, const struct rerere_id *id, const c * Normalize the conflicts in path and write it out to * "thisimage" temporary file. */ - if ((handle_file(istate, path, NULL, rerere_path(id, "thisimage")) < 0) || - read_mmfile(&cur, rerere_path(id, "thisimage"))) { + if ((handle_file(istate, path, NULL, rerere_path(&buf, id, "thisimage")) < 0) || + read_mmfile(&cur, rerere_path(&buf, id, "thisimage"))) { ret = 1; goto out; } @@ -677,9 +687,9 @@ static int merge(struct index_state *istate, const struct rerere_id *id, const c * A successful replay of recorded resolution. * Mark that "postimage" was used to help gc. */ - if (utime(rerere_path(id, "postimage"), NULL) < 0) + if (utime(rerere_path(&buf, id, "postimage"), NULL) < 0) warning_errno(_("failed utime() on '%s'"), - rerere_path(id, "postimage")); + rerere_path(&buf, id, "postimage")); /* Update "path" with the resolution */ f = fopen(path, "w"); @@ -693,6 +703,7 @@ static int merge(struct index_state *istate, const struct rerere_id *id, const c out: free(cur.ptr); free(result.ptr); + strbuf_release(&buf); return ret; } @@ -719,9 +730,11 @@ static void update_paths(struct repository *r, struct string_list *update) static void remove_variant(struct rerere_id *id) { - unlink_or_warn(rerere_path(id, "postimage")); - unlink_or_warn(rerere_path(id, "preimage")); + struct strbuf buf = STRBUF_INIT; + unlink_or_warn(rerere_path(&buf, id, "postimage")); + unlink_or_warn(rerere_path(&buf, id, "preimage")); id->collection->status[id->variant] = 0; + strbuf_release(&buf); } /* @@ -738,6 +751,7 @@ static void do_rerere_one_path(struct index_state *istate, const char *path = rr_item->string; struct rerere_id *id = rr_item->util; struct rerere_dir *rr_dir = id->collection; + struct strbuf buf = STRBUF_INIT; int variant; variant = id->variant; @@ -745,12 +759,12 @@ static void do_rerere_one_path(struct index_state *istate, /* Has the user resolved it already? */ if (variant >= 0) { if (!handle_file(istate, path, NULL, NULL)) { - copy_file(rerere_path(id, "postimage"), path, 0666); + copy_file(rerere_path(&buf, id, "postimage"), path, 0666); id->collection->status[variant] |= RR_HAS_POSTIMAGE; fprintf_ln(stderr, _("Recorded resolution for '%s'."), path); free_rerere_id(rr_item); rr_item->util = NULL; - return; + goto out; } /* * There may be other variants that can cleanly @@ -786,22 +800,25 @@ static void do_rerere_one_path(struct index_state *istate, path); free_rerere_id(rr_item); rr_item->util = NULL; - return; + goto out; } /* None of the existing one applies; we need a new variant */ assign_variant(id); variant = id->variant; - handle_file(istate, path, NULL, rerere_path(id, "preimage")); + handle_file(istate, path, NULL, rerere_path(&buf, id, "preimage")); if (id->collection->status[variant] & RR_HAS_POSTIMAGE) { - const char *path = rerere_path(id, "postimage"); + const char *path = rerere_path(&buf, id, "postimage"); if (unlink(path)) die_errno(_("cannot unlink stray '%s'"), path); id->collection->status[variant] &= ~RR_HAS_POSTIMAGE; } id->collection->status[variant] |= RR_HAS_PREIMAGE; fprintf_ln(stderr, _("Recorded preimage for '%s'"), path); + +out: + strbuf_release(&buf); } static int do_plain_rerere(struct repository *r, @@ -809,6 +826,7 @@ static int do_plain_rerere(struct repository *r, { struct string_list conflict = STRING_LIST_INIT_DUP; struct string_list update = STRING_LIST_INIT_DUP; + struct strbuf buf = STRBUF_INIT; int i; find_conflict(r, &conflict); @@ -842,7 +860,7 @@ static int do_plain_rerere(struct repository *r, string_list_insert(rr, path)->util = id; /* Ensure that the directory exists. */ - mkdir_in_gitdir(rerere_path(id, NULL)); + mkdir_in_gitdir(rerere_path(&buf, id, NULL)); } for (i = 0; i < rr->nr; i++) @@ -853,6 +871,7 @@ static int do_plain_rerere(struct repository *r, string_list_clear(&conflict, 0); string_list_clear(&update, 0); + strbuf_release(&buf); return write_rr(rr, fd); } @@ -1032,6 +1051,7 @@ static int rerere_forget_one_path(struct index_state *istate, struct rerere_id *id; unsigned char hash[GIT_MAX_RAWSZ]; int ret; + struct strbuf buf = STRBUF_INIT; struct string_list_item *item; /* @@ -1055,8 +1075,8 @@ static int rerere_forget_one_path(struct index_state *istate, if (!has_rerere_resolution(id)) continue; - handle_cache(istate, path, hash, rerere_path(id, "thisimage")); - if (read_mmfile(&cur, rerere_path(id, "thisimage"))) { + handle_cache(istate, path, hash, rerere_path(&buf, id, "thisimage")); + if (read_mmfile(&cur, rerere_path(&buf, id, "thisimage"))) { free(cur.ptr); error(_("failed to update conflicted state in '%s'"), path); goto fail_exit; @@ -1073,7 +1093,7 @@ static int rerere_forget_one_path(struct index_state *istate, goto fail_exit; } - filename = rerere_path(id, "postimage"); + filename = rerere_path(&buf, id, "postimage"); if (unlink(filename)) { if (errno == ENOENT) error(_("no remembered resolution for '%s'"), path); @@ -1087,7 +1107,7 @@ static int rerere_forget_one_path(struct index_state *istate, * conflict in the working tree, run us again to record * the postimage. */ - handle_cache(istate, path, hash, rerere_path(id, "preimage")); + handle_cache(istate, path, hash, rerere_path(&buf, id, "preimage")); fprintf_ln(stderr, _("Updated preimage for '%s'"), path); /* @@ -1098,9 +1118,11 @@ static int rerere_forget_one_path(struct index_state *istate, free_rerere_id(item); item->util = id; fprintf(stderr, _("Forgot resolution for '%s'\n"), path); + strbuf_release(&buf); return 0; fail_exit: + strbuf_release(&buf); free(id); return -1; } @@ -1146,16 +1168,26 @@ int rerere_forget(struct repository *r, struct pathspec *pathspec) static timestamp_t rerere_created_at(struct rerere_id *id) { + struct strbuf buf = STRBUF_INIT; struct stat st; + timestamp_t ret; + + ret = stat(rerere_path(&buf, id, "preimage"), &st) ? (time_t) 0 : st.st_mtime; - return stat(rerere_path(id, "preimage"), &st) ? (time_t) 0 : st.st_mtime; + strbuf_release(&buf); + return ret; } static timestamp_t rerere_last_used_at(struct rerere_id *id) { + struct strbuf buf = STRBUF_INIT; struct stat st; + timestamp_t ret; + + ret = stat(rerere_path(&buf, id, "postimage"), &st) ? (time_t) 0 : st.st_mtime; - return stat(rerere_path(id, "postimage"), &st) ? (time_t) 0 : st.st_mtime; + strbuf_release(&buf); + return ret; } /* @@ -1163,9 +1195,11 @@ static timestamp_t rerere_last_used_at(struct rerere_id *id) */ static void unlink_rr_item(struct rerere_id *id) { - unlink_or_warn(rerere_path(id, "thisimage")); + struct strbuf buf = STRBUF_INIT; + unlink_or_warn(rerere_path(&buf, id, "thisimage")); remove_variant(id); id->collection->status[id->variant] = 0; + strbuf_release(&buf); } static void prune_one(struct rerere_id *id, @@ -1204,6 +1238,7 @@ void rerere_gc(struct repository *r, struct string_list *rr) timestamp_t now = time(NULL); timestamp_t cutoff_noresolve = now - 15 * 86400; timestamp_t cutoff_resolve = now - 60 * 86400; + struct strbuf buf = STRBUF_INIT; if (setup_rerere(r, rr, 0) < 0) return; @@ -1213,7 +1248,7 @@ void rerere_gc(struct repository *r, struct string_list *rr) repo_config_get_expiry_in_days(the_repository, "gc.rerereunresolved", &cutoff_noresolve, now); git_config(git_default_config, NULL); - dir = opendir(git_path("rr-cache")); + dir = opendir(repo_git_path_replace(the_repository, &buf, "rr-cache")); if (!dir) die_errno(_("unable to open rr-cache directory")); /* Collect stale conflict IDs ... */ @@ -1242,9 +1277,12 @@ void rerere_gc(struct repository *r, struct string_list *rr) /* ... and then remove the empty directories */ for (i = 0; i < to_remove.nr; i++) - rmdir(git_path("rr-cache/%s", to_remove.items[i].string)); + rmdir(repo_git_path_replace(the_repository, &buf, + "rr-cache/%s", to_remove.items[i].string)); + string_list_clear(&to_remove, 0); rollback_lock_file(&write_lock); + strbuf_release(&buf); } /* @@ -1263,10 +1301,14 @@ void rerere_clear(struct repository *r, struct string_list *merge_rr) for (i = 0; i < merge_rr->nr; i++) { struct rerere_id *id = merge_rr->items[i].util; + struct strbuf buf = STRBUF_INIT; + if (!has_rerere_resolution(id)) { unlink_rr_item(id); - rmdir(rerere_path(id, NULL)); + rmdir(rerere_path(&buf, id, NULL)); } + + strbuf_release(&buf); } unlink_or_warn(git_path_merge_rr(r)); rollback_lock_file(&write_lock); diff --git a/rerere.h b/rerere.h index 5d6cb638793a49..d4b5f7c932006a 100644 --- a/rerere.h +++ b/rerere.h @@ -32,7 +32,8 @@ int repo_rerere(struct repository *, int); * path to that filesystem entity. With "file" specified with NULL, * return the path to the directory that houses these files. */ -const char *rerere_path(const struct rerere_id *, const char *file); +const char *rerere_path(struct strbuf *buf, const struct rerere_id *, + const char *file); int rerere_forget(struct repository *, struct pathspec *); int rerere_remaining(struct repository *, struct string_list *); void rerere_clear(struct repository *, struct string_list *); diff --git a/resolve-undo.c b/resolve-undo.c index 8c9911affbe409..52c45e5a494636 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "dir.h" @@ -33,7 +33,8 @@ void record_resolve_undo(struct index_state *istate, struct cache_entry *ce) ui->mode[stage - 1] = ce->ce_mode; } -void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo) +void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo, + const struct git_hash_algo *algop) { struct string_list_item *item; for_each_string_list_item(item, resolve_undo) { @@ -49,18 +50,19 @@ void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo) for (i = 0; i < 3; i++) { if (!ui->mode[i]) continue; - strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz); + strbuf_add(sb, ui->oid[i].hash, algop->rawsz); } } } -struct string_list *resolve_undo_read(const char *data, unsigned long size) +struct string_list *resolve_undo_read(const char *data, unsigned long size, + const struct git_hash_algo *algop) { struct string_list *resolve_undo; size_t len; char *endptr; int i; - const unsigned rawsz = the_hash_algo->rawsz; + const unsigned rawsz = algop->rawsz; CALLOC_ARRAY(resolve_undo, 1); resolve_undo->strdup_strings = 1; @@ -95,8 +97,7 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size) continue; if (size < rawsz) goto error; - oidread(&ui->oid[i], (const unsigned char *)data, - the_repository->hash_algo); + oidread(&ui->oid[i], (const unsigned char *)data, algop); size -= rawsz; data += rawsz; } diff --git a/resolve-undo.h b/resolve-undo.h index 89a32272620f2b..7ed11a1c59b819 100644 --- a/resolve-undo.h +++ b/resolve-undo.h @@ -14,8 +14,10 @@ struct resolve_undo_info { }; void record_resolve_undo(struct index_state *, struct cache_entry *); -void resolve_undo_write(struct strbuf *, struct string_list *); -struct string_list *resolve_undo_read(const char *, unsigned long); +void resolve_undo_write(struct strbuf *, struct string_list *, + const struct git_hash_algo *algop); +struct string_list *resolve_undo_read(const char *, unsigned long, + const struct git_hash_algo *algop); void resolve_undo_clear_index(struct index_state *); int unmerge_index_entry(struct index_state *, const char *, struct resolve_undo_info *, unsigned); void unmerge_index(struct index_state *, const struct pathspec *, unsigned); diff --git a/revision.c b/revision.c index 2d7ad2bddff345..c4390f0938cbde 100644 --- a/revision.c +++ b/revision.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -51,8 +52,8 @@ volatile show_early_output_fn_t show_early_output; -static const char *term_bad; -static const char *term_good; +static char *term_bad; +static char *term_good; implement_shared_commit_slab(revision_sources, char *); @@ -390,7 +391,8 @@ static struct object *get_reference(struct rev_info *revs, const char *name, if (!object) { if (revs->ignore_missing) return NULL; - if (revs->exclude_promisor_objects && is_promisor_object(oid)) + if (revs->exclude_promisor_objects && + is_promisor_object(revs->repo, oid)) return NULL; if (revs->do_not_die_on_missing_objects) { oidset_insert(&revs->missing_commits, oid); @@ -432,7 +434,7 @@ static struct commit *handle_commit(struct rev_info *revs, if (revs->ignore_missing_links || (flags & UNINTERESTING)) return NULL; if (revs->exclude_promisor_objects && - is_promisor_object(&tag->tagged->oid)) + is_promisor_object(revs->repo, &tag->tagged->oid)) return NULL; if (revs->do_not_die_on_missing_objects && oid) { oidset_insert(&revs->missing_commits, oid); @@ -1071,7 +1073,11 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) ts->treesame[nth_parent] = 1; continue; } + + free_commit_list(parent->next); parent->next = NULL; + while (commit->parents != parent) + pop_commit(&commit->parents); commit->parents = parent; /* @@ -1103,6 +1109,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit) die("cannot simplify commit %s (invalid %s)", oid_to_hex(&commit->object.oid), oid_to_hex(&p->object.oid)); + free_commit_list(p->parents); p->parents = NULL; } /* fallthrough */ @@ -1206,7 +1213,7 @@ static int process_parents(struct rev_info *revs, struct commit *commit, revs->do_not_die_on_missing_objects; if (repo_parse_commit_gently(revs->repo, p, gently) < 0) { if (revs->exclude_promisor_objects && - is_promisor_object(&p->object.oid)) { + is_promisor_object(revs->repo, &p->object.oid)) { if (revs->first_parent_only) break; continue; @@ -1867,15 +1874,20 @@ void add_index_objects_to_pending(struct rev_info *revs, unsigned int flags) for (p = worktrees; *p; p++) { struct worktree *wt = *p; struct index_state istate = INDEX_STATE_INIT(revs->repo); + char *wt_gitdir; if (wt->is_current) continue; /* current index already taken care of */ + wt_gitdir = get_worktree_git_dir(wt); + if (read_index_from(&istate, worktree_git_path(the_repository, wt, "index"), - get_worktree_git_dir(wt)) > 0) + wt_gitdir) > 0) do_add_index_objects_to_pending(revs, &istate, flags); + discard_index(&istate); + free(wt_gitdir); } free_worktrees(worktrees); } @@ -3222,6 +3234,11 @@ void release_revisions(struct rev_info *revs) clear_decoration(&revs->treesame, free); line_log_free(revs); oidset_clear(&revs->missing_commits); + + for (int i = 0; i < revs->bloom_keys_nr; i++) + clear_bloom_key(&revs->bloom_keys[i]); + FREE_AND_NULL(revs->bloom_keys); + revs->bloom_keys_nr = 0; } static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child) @@ -3245,6 +3262,7 @@ static int remove_duplicate_parents(struct rev_info *revs, struct commit *commit struct commit *parent = p->item; if (parent->object.flags & TMP_MARK) { *pp = p->next; + free(p); if (ts) compact_treesame(revs, commit, surviving_parents); continue; @@ -3909,7 +3927,7 @@ int prepare_revision_walk(struct rev_info *revs) revs->treesame.name = "treesame"; if (revs->exclude_promisor_objects) { - for_each_packed_object(mark_uninteresting, revs, + for_each_packed_object(revs->repo, mark_uninteresting, revs, FOR_EACH_OBJECT_PROMISOR_ONLY); } @@ -4000,6 +4018,7 @@ int rewrite_parents(struct rev_info *revs, struct commit *commit, break; case rewrite_one_noparents: *pp = parent->next; + free(parent); continue; case rewrite_one_error: return -1; @@ -4096,10 +4115,10 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi { if (commit->object.flags & SHOWN) return commit_ignore; - if (revs->unpacked && has_object_pack(&commit->object.oid)) + if (revs->unpacked && has_object_pack(revs->repo, &commit->object.oid)) return commit_ignore; if (revs->no_kept_objects) { - if (has_object_kept_pack(&commit->object.oid, + if (has_object_kept_pack(revs->repo, &commit->object.oid, revs->keep_pack_cache_flags)) return commit_ignore; } @@ -4200,10 +4219,18 @@ static void save_parents(struct rev_info *revs, struct commit *commit) *pp = EMPTY_PARENT_LIST; } +static void free_saved_parent(struct commit_list **parents) +{ + if (*parents != EMPTY_PARENT_LIST) + free_commit_list(*parents); +} + static void free_saved_parents(struct rev_info *revs) { - if (revs->saved_parents_slab) - clear_saved_parents(revs->saved_parents_slab); + if (!revs->saved_parents_slab) + return; + deep_clear_saved_parents(revs->saved_parents_slab, free_saved_parent); + FREE_AND_NULL(revs->saved_parents_slab); } struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit) diff --git a/run-command.c b/run-command.c index 94f2f3079ff754..402138b8b53ae8 100644 --- a/run-command.c +++ b/run-command.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "run-command.h" diff --git a/scalar.c b/scalar.c index 73b79a5d4c9979..da42b4be0cc9b6 100644 --- a/scalar.c +++ b/scalar.c @@ -379,7 +379,7 @@ static int delete_enlistment(struct strbuf *enlistment) offset = offset_1st_component(enlistment->buf); path_sep = find_last_dir_sep(enlistment->buf + offset); strbuf_add(&parent, enlistment->buf, - path_sep ? path_sep - enlistment->buf : offset); + path_sep ? (size_t) (path_sep - enlistment->buf) : offset); if (chdir(parent.buf) < 0) { int res = error_errno(_("could not switch to '%s'"), parent.buf); strbuf_release(&parent); @@ -409,6 +409,7 @@ void load_builtin_commands(const char *prefix UNUSED, static int cmd_clone(int argc, const char **argv) { const char *branch = NULL; + char *branch_to_free = NULL; int full_clone = 0, single_branch = 0, show_progress = isatty(2); int src = 1, tags = 1; struct option clone_options[] = { @@ -490,7 +491,7 @@ static int cmd_clone(int argc, const char **argv) /* common-main already logs `argv` */ trace2_def_repo(the_repository); - if (!branch && !(branch = remote_default_branch(url))) { + if (!branch && !(branch = branch_to_free = remote_default_branch(url))) { res = error(_("failed to get default branch for '%s'"), url); goto cleanup; } @@ -552,6 +553,7 @@ static int cmd_clone(int argc, const char **argv) res = register_dir(); cleanup: + free(branch_to_free); free(enlistment); free(dir); strbuf_release(&buf); @@ -654,7 +656,7 @@ static int cmd_reconfigure(int argc, const char **argv) NULL }; struct string_list scalar_repos = STRING_LIST_INIT_DUP; - int i, res = 0; + int res = 0; struct strbuf commondir = STRBUF_INIT, gitdir = STRBUF_INIT; argc = parse_options(argc, argv, NULL, options, @@ -672,7 +674,7 @@ static int cmd_reconfigure(int argc, const char **argv) git_config(get_scalar_repos, &scalar_repos); - for (i = 0; i < scalar_repos.nr; i++) { + for (size_t i = 0; i < scalar_repos.nr; i++) { int succeeded = 0; struct repository *old_repo, r = { NULL }; const char *dir = scalar_repos.items[i].string; @@ -732,6 +734,7 @@ static int cmd_reconfigure(int argc, const char **argv) succeeded = 1; the_repository = old_repo; + repo_clear(&r); if (toggle_maintenance(1) >= 0) succeeded = 1; diff --git a/send-pack.c b/send-pack.c index 6677c44e8acd19..856a65d5f5abce 100644 --- a/send-pack.c +++ b/send-pack.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "config.h" #include "commit.h" @@ -44,10 +42,11 @@ int option_parse_push_signed(const struct option *opt, die("bad %s argument: %s", opt->long_name, arg); } -static void feed_object(const struct object_id *oid, FILE *fh, int negative) +static void feed_object(struct repository *r, + const struct object_id *oid, FILE *fh, int negative) { if (negative && - !repo_has_object_file_with_flags(the_repository, oid, + !repo_has_object_file_with_flags(r, oid, OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK)) return; @@ -61,7 +60,8 @@ static void feed_object(const struct object_id *oid, FILE *fh, int negative) /* * Make a pack stream and spit it out into file descriptor fd */ -static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised, +static int pack_objects(struct repository *r, + int fd, struct ref *refs, struct oid_array *advertised, struct oid_array *negotiated, struct send_pack_args *args) { @@ -72,10 +72,9 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised, */ struct child_process po = CHILD_PROCESS_INIT; FILE *po_in; - int i; int rc; - trace2_region_enter("send_pack", "pack_objects", the_repository); + trace2_region_enter("send_pack", "pack_objects", r); strvec_push(&po.args, "pack-objects"); strvec_push(&po.args, "--all-progress-implied"); strvec_push(&po.args, "--revs"); @@ -88,7 +87,7 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised, strvec_push(&po.args, "-q"); if (args->progress) strvec_push(&po.args, "--progress"); - if (is_repository_shallow(the_repository)) + if (is_repository_shallow(r)) strvec_push(&po.args, "--shallow"); if (args->disable_bitmaps) strvec_push(&po.args, "--no-use-bitmap-index"); @@ -104,16 +103,16 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised, * parameters by writing to the pipe. */ po_in = xfdopen(po.in, "w"); - for (i = 0; i < advertised->nr; i++) - feed_object(&advertised->oid[i], po_in, 1); - for (i = 0; i < negotiated->nr; i++) - feed_object(&negotiated->oid[i], po_in, 1); + for (size_t i = 0; i < advertised->nr; i++) + feed_object(r, &advertised->oid[i], po_in, 1); + for (size_t i = 0; i < negotiated->nr; i++) + feed_object(r, &negotiated->oid[i], po_in, 1); while (refs) { if (!is_null_oid(&refs->old_oid)) - feed_object(&refs->old_oid, po_in, 1); + feed_object(r, &refs->old_oid, po_in, 1); if (!is_null_oid(&refs->new_oid)) - feed_object(&refs->new_oid, po_in, 0); + feed_object(r, &refs->new_oid, po_in, 0); refs = refs->next; } @@ -147,10 +146,10 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *advertised, */ if (rc > 128 && rc != 141) error("pack-objects died of signal %d", rc - 128); - trace2_region_leave("send_pack", "pack_objects", the_repository); + trace2_region_leave("send_pack", "pack_objects", r); return -1; } - trace2_region_leave("send_pack", "pack_objects", the_repository); + trace2_region_leave("send_pack", "pack_objects", r); return 0; } @@ -165,7 +164,8 @@ static int receive_unpack_status(struct packet_reader *reader) return 0; } -static int receive_status(struct packet_reader *reader, struct ref *refs) +static int receive_status(struct repository *r, + struct packet_reader *reader, struct ref *refs) { struct ref *hint; int ret; @@ -173,7 +173,7 @@ static int receive_status(struct packet_reader *reader, struct ref *refs) int new_report = 0; int once = 0; - trace2_region_enter("send_pack", "receive_status", the_repository); + trace2_region_enter("send_pack", "receive_status", r); hint = NULL; ret = receive_unpack_status(reader); while (1) { @@ -222,10 +222,10 @@ static int receive_status(struct packet_reader *reader, struct ref *refs) if (!strcmp(key, "refname")) report->ref_name = xstrdup_or_null(val); else if (!strcmp(key, "old-oid") && val && - !parse_oid_hex(val, &old_oid, &val)) + !parse_oid_hex_algop(val, &old_oid, &val, r->hash_algo)) report->old_oid = oiddup(&old_oid); else if (!strcmp(key, "new-oid") && val && - !parse_oid_hex(val, &new_oid, &val)) + !parse_oid_hex_algop(val, &new_oid, &val, r->hash_algo)) report->new_oid = oiddup(&new_oid); else if (!strcmp(key, "forced-update")) report->forced_update = 1; @@ -272,7 +272,7 @@ static int receive_status(struct packet_reader *reader, struct ref *refs) new_report = 1; } } - trace2_region_leave("send_pack", "receive_status", the_repository); + trace2_region_leave("send_pack", "receive_status", r); return ret; } @@ -294,9 +294,9 @@ static int advertise_shallow_grafts_cb(const struct commit_graft *graft, void *c return 0; } -static void advertise_shallow_grafts_buf(struct strbuf *sb) +static void advertise_shallow_grafts_buf(struct repository *r, struct strbuf *sb) { - if (!is_repository_shallow(the_repository)) + if (!is_repository_shallow(r)) return; for_each_commit_graft(advertise_shallow_grafts_cb, sb); } @@ -427,13 +427,14 @@ static void reject_invalid_nonce(const char *nonce, int len) } } -static void get_commons_through_negotiation(const char *url, +static void get_commons_through_negotiation(struct repository *r, + const char *url, const struct ref *remote_refs, struct oid_array *commons) { struct child_process child = CHILD_PROCESS_INIT; const struct ref *ref; - int len = the_hash_algo->hexsz + 1; /* hash + NL */ + int len = r->hash_algo->hexsz + 1; /* hash + NL */ int nr_negotiation_tip = 0; child.git_cmd = 1; @@ -467,7 +468,7 @@ static void get_commons_through_negotiation(const char *url, break; if (read_len != len) die("invalid length read %d", read_len); - if (parse_oid_hex(hex_hash, &oid, &end) || *end != '\n') + if (parse_oid_hex_algop(hex_hash, &oid, &end, r->hash_algo) || *end != '\n') die("invalid hash"); oid_array_append(commons, &oid); } while (1); @@ -481,7 +482,8 @@ static void get_commons_through_negotiation(const char *url, } } -int send_pack(struct send_pack_args *args, +int send_pack(struct repository *r, + struct send_pack_args *args, int fd[], struct child_process *conn, struct ref *remote_refs, struct oid_array *extra_have) @@ -519,17 +521,17 @@ int send_pack(struct send_pack_args *args, goto out; } - git_config_get_bool("push.negotiate", &push_negotiate); + repo_config_get_bool(r, "push.negotiate", &push_negotiate); if (push_negotiate) { - trace2_region_enter("send_pack", "push_negotiate", the_repository); - get_commons_through_negotiation(args->url, remote_refs, &commons); - trace2_region_leave("send_pack", "push_negotiate", the_repository); + trace2_region_enter("send_pack", "push_negotiate", r); + get_commons_through_negotiation(r, args->url, remote_refs, &commons); + trace2_region_leave("send_pack", "push_negotiate", r); } - if (!git_config_get_bool("push.usebitmaps", &use_bitmaps)) + if (!repo_config_get_bool(r, "push.usebitmaps", &use_bitmaps)) args->disable_bitmaps = !use_bitmaps; - git_config_get_bool("transfer.advertisesid", &advertise_sid); + repo_config_get_bool(r, "transfer.advertisesid", &advertise_sid); /* Does the other end support the reporting? */ if (server_supports("report-status-v2")) @@ -555,7 +557,7 @@ int send_pack(struct send_pack_args *args, if (server_supports("push-options")) push_options_supported = 1; - if (!server_supports_hash(the_hash_algo->name, &object_format_supported)) + if (!server_supports_hash(r->hash_algo->name, &object_format_supported)) die(_("the receiving end does not support this repository's hash algorithm")); if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) { @@ -597,7 +599,7 @@ int send_pack(struct send_pack_args *args, if (use_push_options) strbuf_addstr(&cap_buf, " push-options"); if (object_format_supported) - strbuf_addf(&cap_buf, " object-format=%s", the_hash_algo->name); + strbuf_addf(&cap_buf, " object-format=%s", r->hash_algo->name); if (agent_supported) strbuf_addf(&cap_buf, " agent=%s", git_user_agent_sanitized()); if (advertise_sid) @@ -630,7 +632,8 @@ int send_pack(struct send_pack_args *args, reject_atomic_push(remote_refs, args->send_mirror); error("atomic push failed for ref %s. status: %d", ref->name, ref->status); - ret = args->porcelain ? 0 : -1; + ret = ERROR_SEND_PACK_BAD_REF_STATUS; + packet_flush(out); goto out; } /* else fallthrough */ @@ -647,7 +650,7 @@ int send_pack(struct send_pack_args *args, } if (!args->dry_run) - advertise_shallow_grafts_buf(&req_buf); + advertise_shallow_grafts_buf(r, &req_buf); /* * Finally, tell the other end! @@ -687,7 +690,7 @@ int send_pack(struct send_pack_args *args, } if (args->stateless_rpc) { - if (!args->dry_run && (cmds_sent || is_repository_shallow(the_repository))) { + if (!args->dry_run && (cmds_sent || is_repository_shallow(r))) { packet_buf_flush(&req_buf); send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); } @@ -712,7 +715,7 @@ int send_pack(struct send_pack_args *args, PACKET_READ_DIE_ON_ERR_PACKET); if (need_pack_data && cmds_sent) { - if (pack_objects(out, remote_refs, extra_have, &commons, args) < 0) { + if (pack_objects(r, out, remote_refs, extra_have, &commons, args) < 0) { if (args->stateless_rpc) close(out); if (git_connection_is_socket(conn)) @@ -725,7 +728,7 @@ int send_pack(struct send_pack_args *args, * we get one). */ if (status_report) - receive_status(&reader, remote_refs); + receive_status(r, &reader, remote_refs); if (use_sideband) { close(demux.out); @@ -744,7 +747,7 @@ int send_pack(struct send_pack_args *args, packet_flush(out); if (status_report && cmds_sent) - ret = receive_status(&reader, remote_refs); + ret = receive_status(r, &reader, remote_refs); else ret = 0; if (args->stateless_rpc) @@ -761,11 +764,6 @@ int send_pack(struct send_pack_args *args, if (ret < 0) goto out; - if (args->porcelain) { - ret = 0; - goto out; - } - for (ref = remote_refs; ref; ref = ref->next) { switch (ref->status) { case REF_STATUS_NONE: @@ -773,7 +771,7 @@ int send_pack(struct send_pack_args *args, case REF_STATUS_OK: break; default: - ret = -1; + ret = ERROR_SEND_PACK_BAD_REF_STATUS; goto out; } } diff --git a/send-pack.h b/send-pack.h index 7edb80596c7b0e..c5ded2d2006f13 100644 --- a/send-pack.h +++ b/send-pack.h @@ -6,12 +6,16 @@ struct child_process; struct oid_array; struct ref; +struct repository; /* Possible values for push_cert field in send_pack_args. */ #define SEND_PACK_PUSH_CERT_NEVER 0 #define SEND_PACK_PUSH_CERT_IF_ASKED 1 #define SEND_PACK_PUSH_CERT_ALWAYS 2 +/* At least one reference has been rejected by the remote side. */ +#define ERROR_SEND_PACK_BAD_REF_STATUS 1 + struct send_pack_args { const char *url; unsigned verbose:1, @@ -35,7 +39,17 @@ struct option; int option_parse_push_signed(const struct option *opt, const char *arg, int unset); -int send_pack(struct send_pack_args *args, +/* + * Compute a packfile and write it to a file descriptor. The `fd` array needs + * to contain two file descriptors: `fd[0]` is the file descriptor used as + * input for the packet reader, whereas `fd[1]` is the file descriptor the + * packfile will be written to. + * + * Returns 0 on success, non-zero otherwise. Negative return values indicate a + * generic error, whereas positive return values indicate specific error + * conditions as documented with the `ERROR_SEND_PACK_*` constants. + */ +int send_pack(struct repository *r, struct send_pack_args *args, int fd[], struct child_process *conn, struct ref *remote_refs, struct oid_array *extra_have); diff --git a/sequencer.c b/sequencer.c index 8d01cd50ac943c..ad0ab75c8d4dd7 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -662,7 +663,7 @@ static int fast_forward_to(struct repository *r, strbuf_addf(&sb, "%s: fast-forward", action_name(opts)); transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction || ref_transaction_update(transaction, "HEAD", to, unborn && !is_rebase_i(opts) ? @@ -1297,7 +1298,7 @@ int update_head_with_reflog(const struct commit *old_head, } transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - err); + 0, err); if (!transaction || ref_transaction_update(transaction, "HEAD", new_head, old_head ? &old_head->object.oid : null_oid(), @@ -1941,10 +1942,10 @@ static int seen_squash(struct replay_ctx *ctx) static void update_comment_bufs(struct strbuf *buf1, struct strbuf *buf2, int n) { - strbuf_setlen(buf1, 2); + strbuf_setlen(buf1, strlen(comment_line_str) + 1); strbuf_addf(buf1, _(nth_commit_msg_fmt), n); strbuf_addch(buf1, '\n'); - strbuf_setlen(buf2, 2); + strbuf_setlen(buf2, strlen(comment_line_str) + 1); strbuf_addf(buf2, _(skip_nth_commit_msg_fmt), n); strbuf_addch(buf2, '\n'); } @@ -1963,8 +1964,12 @@ static void update_squash_message_for_fixup(struct strbuf *msg) size_t orig_msg_len; int i = 1; - strbuf_addf(&buf1, "# %s\n", _(first_commit_msg_str)); - strbuf_addf(&buf2, "# %s\n", _(skip_first_commit_msg_str)); + strbuf_add_commented_lines(&buf1, _(first_commit_msg_str), + strlen(_(first_commit_msg_str)), + comment_line_str); + strbuf_add_commented_lines(&buf2, _(skip_first_commit_msg_str), + strlen(_(skip_first_commit_msg_str)), + comment_line_str); s = start = orig_msg = strbuf_detach(msg, &orig_msg_len); while (s) { const char *next; @@ -2341,8 +2346,8 @@ static int do_pick_commit(struct repository *r, next = parent; next_label = msg.parent_label; if (opts->commit_use_reference) { - strbuf_addstr(&ctx->message, - "# *** SAY WHY WE ARE REVERTING ON THE TITLE LINE ***"); + strbuf_commented_addf(&ctx->message, comment_line_str, + "*** SAY WHY WE ARE REVERTING ON THE TITLE LINE ***"); } else if (skip_prefix(msg.subject, "Revert \"", &orig_subject) && /* * We don't touch pre-existing repeated reverts, because @@ -2352,12 +2357,13 @@ static int do_pick_commit(struct repository *r, !starts_with(orig_subject, "Revert \"")) { strbuf_addstr(&ctx->message, "Reapply \""); strbuf_addstr(&ctx->message, orig_subject); + strbuf_addstr(&ctx->message, "\n"); } else { strbuf_addstr(&ctx->message, "Revert \""); strbuf_addstr(&ctx->message, msg.subject); - strbuf_addstr(&ctx->message, "\""); + strbuf_addstr(&ctx->message, "\"\n"); } - strbuf_addstr(&ctx->message, "\n\nThis reverts commit "); + strbuf_addstr(&ctx->message, "\nThis reverts commit "); refer_to_commit(opts, &ctx->message, commit); if (commit->parents && commit->parents->next) { @@ -2504,9 +2510,15 @@ static int do_pick_commit(struct repository *r, *check_todo = !!(flags & EDIT_MSG); if (!res && reword) { fast_forward_edit: - res = run_git_commit(NULL, opts, EDIT_MSG | - VERIFY_MSG | AMEND_MSG | - (flags & ALLOW_EMPTY)); + /* + * To reword we amend the commit we just + * picked or fast-forwarded. As the commit has + * already been picked we want to use the same + * set of commit flags regardless of how we + * got here. + */ + flags = EDIT_MSG | VERIFY_MSG | AMEND_MSG | ALLOW_EMPTY; + res = run_git_commit(NULL, opts, flags); *check_todo = 1; } } @@ -3890,7 +3902,7 @@ static int do_label(struct repository *r, const char *name, int len) strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name); strbuf_addf(&msg, "rebase (label) '%.*s'", len, name); - transaction = ref_store_transaction_begin(refs, &err); + transaction = ref_store_transaction_begin(refs, 0, &err); if (!transaction) { error("%s", err.buf); ret = -1; @@ -5819,7 +5831,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, int root_with_onto = flags & TODO_LIST_ROOT_WITH_ONTO; int skipped_commit = 0; struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT; - struct strbuf label = STRBUF_INIT; + struct strbuf label_from_message = STRBUF_INIT; struct commit_list *commits = NULL, **tail = &commits, *iter; struct commit_list *tips = NULL, **tips_tail = &tips; struct commit *commit; @@ -5842,6 +5854,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, oidmap_init(&state.commit2label, 0); hashmap_init(&state.labels, labels_cmp, NULL, 0); strbuf_init(&state.buf, 32); + load_branch_decorations(); if (revs->cmdline.nr && (revs->cmdline.rev[0].flags & BOTTOM)) { struct labels_entry *onto_label_entry; @@ -5902,18 +5915,18 @@ static int make_script_with_merges(struct pretty_print_context *pp, continue; } - /* Create a label */ - strbuf_reset(&label); + /* Create a label from the commit message */ + strbuf_reset(&label_from_message); if (skip_prefix(oneline.buf, "Merge ", &p1) && (p1 = strchr(p1, '\'')) && (p2 = strchr(++p1, '\''))) - strbuf_add(&label, p1, p2 - p1); + strbuf_add(&label_from_message, p1, p2 - p1); else if (skip_prefix(oneline.buf, "Merge pull request ", &p1) && (p1 = strstr(p1, " from "))) - strbuf_addstr(&label, p1 + strlen(" from ")); + strbuf_addstr(&label_from_message, p1 + strlen(" from ")); else - strbuf_addbuf(&label, &oneline); + strbuf_addbuf(&label_from_message, &oneline); strbuf_reset(&buf); strbuf_addf(&buf, "%s -C %s", @@ -5921,6 +5934,14 @@ static int make_script_with_merges(struct pretty_print_context *pp, /* label the tips of merged branches */ for (; to_merge; to_merge = to_merge->next) { + const char *label = label_from_message.buf; + const struct name_decoration *decoration = + get_name_decoration(&to_merge->item->object); + + if (decoration) + skip_prefix(decoration->name, "refs/heads/", + &label); + oid = &to_merge->item->object.oid; strbuf_addch(&buf, ' '); @@ -5933,7 +5954,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, tips_tail = &commit_list_insert(to_merge->item, tips_tail)->next; - strbuf_addstr(&buf, label_oid(oid, label.buf, &state)); + strbuf_addstr(&buf, label_oid(oid, label, &state)); } strbuf_addf(&buf, " # %s", oneline.buf); @@ -6041,7 +6062,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, free_commit_list(commits); free_commit_list(tips); - strbuf_release(&label); + strbuf_release(&label_from_message); strbuf_release(&oneline); strbuf_release(&buf); @@ -6373,8 +6394,9 @@ static int add_decorations_to_list(const struct commit *commit, /* If the branch is checked out, then leave a comment instead. */ if ((path = branch_checked_out(decoration->name))) { item->command = TODO_COMMENT; - strbuf_addf(ctx->buf, "# Ref %s checked out at '%s'\n", - decoration->name, path); + strbuf_commented_addf(ctx->buf, comment_line_str, + "Ref %s checked out at '%s'\n", + decoration->name, path); } else { struct string_list_item *sti; item->command = TODO_UPDATE_REF; @@ -6403,14 +6425,6 @@ static int add_decorations_to_list(const struct commit *commit, static int todo_list_add_update_ref_commands(struct todo_list *todo_list) { int i, res; - static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP; - static struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP; - static struct string_list decorate_refs_include = STRING_LIST_INIT_NODUP; - struct decoration_filter decoration_filter = { - .include_ref_pattern = &decorate_refs_include, - .exclude_ref_pattern = &decorate_refs_exclude, - .exclude_ref_config_pattern = &decorate_refs_exclude_config, - }; struct todo_add_branch_context ctx = { .buf = &todo_list->buf, .refs_to_oids = STRING_LIST_INIT_DUP, @@ -6419,8 +6433,7 @@ static int todo_list_add_update_ref_commands(struct todo_list *todo_list) ctx.items_alloc = 2 * todo_list->nr + 1; ALLOC_ARRAY(ctx.items, ctx.items_alloc); - string_list_append(&decorate_refs_include, "refs/heads/"); - load_ref_decorations(&decoration_filter, 0); + load_branch_decorations(); for (i = 0; i < todo_list->nr; ) { struct todo_item *item = &todo_list->items[i]; diff --git a/serve.c b/serve.c index d674764a25d4cd..e3ccf1505ca1a0 100644 --- a/serve.c +++ b/serve.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "repository.h" #include "config.h" @@ -12,6 +10,7 @@ #include "upload-pack.h" #include "bundle-uri.h" #include "trace2.h" +#include "promisor-remote.h" static int advertise_sid = -1; static int advertise_object_info = -1; @@ -31,6 +30,26 @@ static int agent_advertise(struct repository *r UNUSED, return 1; } +static int promisor_remote_advertise(struct repository *r, + struct strbuf *value) +{ + if (value) { + char *info = promisor_remote_info(r); + if (!info) + return 0; + strbuf_addstr(value, info); + free(info); + } + return 1; +} + +static void promisor_remote_receive(struct repository *r, + const char *remotes) +{ + mark_promisor_remotes_as_accepted(r, remotes); +} + + static int object_format_advertise(struct repository *r, struct strbuf *value) { @@ -157,21 +176,25 @@ static struct protocol_capability capabilities[] = { .advertise = bundle_uri_advertise, .command = bundle_uri_command, }, + { + .name = "promisor-remote", + .advertise = promisor_remote_advertise, + .receive = promisor_remote_receive, + }, }; -void protocol_v2_advertise_capabilities(void) +void protocol_v2_advertise_capabilities(struct repository *r) { struct strbuf capability = STRBUF_INIT; struct strbuf value = STRBUF_INIT; - int i; /* serve by default supports v2 */ packet_write_fmt(1, "version 2\n"); - for (i = 0; i < ARRAY_SIZE(capabilities); i++) { + for (size_t i = 0; i < ARRAY_SIZE(capabilities); i++) { struct protocol_capability *c = &capabilities[i]; - if (c->advertise(the_repository, &value)) { + if (c->advertise(r, &value)) { strbuf_addstr(&capability, c->name); if (value.len) { @@ -194,12 +217,10 @@ void protocol_v2_advertise_capabilities(void) static struct protocol_capability *get_capability(const char *key, const char **value) { - int i; - if (!key) return NULL; - for (i = 0; i < ARRAY_SIZE(capabilities); i++) { + for (size_t i = 0; i < ARRAY_SIZE(capabilities); i++) { struct protocol_capability *c = &capabilities[i]; const char *out; if (!skip_prefix(key, c->name, &out)) @@ -217,20 +238,20 @@ static struct protocol_capability *get_capability(const char *key, const char ** return NULL; } -static int receive_client_capability(const char *key) +static int receive_client_capability(struct repository *r, const char *key) { const char *value; const struct protocol_capability *c = get_capability(key, &value); - if (!c || c->command || !c->advertise(the_repository, NULL)) + if (!c || c->command || !c->advertise(r, NULL)) return 0; if (c->receive) - c->receive(the_repository, value); + c->receive(r, value); return 1; } -static int parse_command(const char *key, struct protocol_capability **command) +static int parse_command(struct repository *r, const char *key, struct protocol_capability **command) { const char *out; @@ -241,7 +262,7 @@ static int parse_command(const char *key, struct protocol_capability **command) if (*command) die("command '%s' requested after already requesting command '%s'", out, (*command)->name); - if (!cmd || !cmd->advertise(the_repository, NULL) || !cmd->command || value) + if (!cmd || !cmd->advertise(r, NULL) || !cmd->command || value) die("invalid command '%s'", out); *command = cmd; @@ -256,7 +277,7 @@ enum request_state { PROCESS_REQUEST_DONE, }; -static int process_request(void) +static int process_request(struct repository *r) { enum request_state state = PROCESS_REQUEST_KEYS; struct packet_reader reader; @@ -281,8 +302,8 @@ static int process_request(void) case PACKET_READ_EOF: BUG("Should have already died when seeing EOF"); case PACKET_READ_NORMAL: - if (parse_command(reader.line, &command) || - receive_client_capability(reader.line)) + if (parse_command(r, reader.line, &command) || + receive_client_capability(r, reader.line)) seen_capability_or_command = 1; else die("unknown capability '%s'", reader.line); @@ -322,30 +343,30 @@ static int process_request(void) if (!command) die("no command requested"); - if (client_hash_algo != hash_algo_by_ptr(the_repository->hash_algo)) + if (client_hash_algo != hash_algo_by_ptr(r->hash_algo)) die("mismatched object format: server %s; client %s", - the_repository->hash_algo->name, + r->hash_algo->name, hash_algos[client_hash_algo].name); - command->command(the_repository, &reader); + command->command(r, &reader); return 0; } -void protocol_v2_serve_loop(int stateless_rpc) +void protocol_v2_serve_loop(struct repository *r, int stateless_rpc) { if (!stateless_rpc) - protocol_v2_advertise_capabilities(); + protocol_v2_advertise_capabilities(r); /* * If stateless-rpc was requested then exit after * a single request/response exchange */ if (stateless_rpc) { - process_request(); + process_request(r); } else { for (;;) - if (process_request()) + if (process_request(r)) break; } } diff --git a/serve.h b/serve.h index f946cf904a242d..85bf73cfe53cb9 100644 --- a/serve.h +++ b/serve.h @@ -1,7 +1,9 @@ #ifndef SERVE_H #define SERVE_H -void protocol_v2_advertise_capabilities(void); -void protocol_v2_serve_loop(int stateless_rpc); +struct repository; + +void protocol_v2_advertise_capabilities(struct repository *r); +void protocol_v2_serve_loop(struct repository *r, int stateless_rpc); #endif /* SERVE_H */ diff --git a/server-info.c b/server-info.c index c5af4cd98a6696..1ca0e00d51e6c0 100644 --- a/server-info.c +++ b/server-info.c @@ -1,4 +1,4 @@ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "dir.h" @@ -17,6 +17,7 @@ #include "tempfile.h" struct update_info_ctx { + struct repository *repo; FILE *cur_fp; FILE *old_fp; /* becomes NULL if it differs from cur_fp */ struct strbuf cur_sb; @@ -72,7 +73,7 @@ static int uic_printf(struct update_info_ctx *uic, const char *fmt, ...) * it into place. The contents of the file come from "generate", which * should return non-zero if it encounters an error. */ -static int update_info_file(char *path, +static int update_info_file(struct repository *r, char *path, int (*generate)(struct update_info_ctx *), int force) { @@ -80,6 +81,7 @@ static int update_info_file(char *path, struct tempfile *f = NULL; int ret = -1; struct update_info_ctx uic = { + .repo = r, .cur_fp = NULL, .old_fp = NULL, .cur_sb = STRBUF_INIT, @@ -123,7 +125,7 @@ static int update_info_file(char *path, uic.cur_fp = NULL; if (uic_is_stale(&uic)) { - if (adjust_shared_perm(get_tempfile_path(f)) < 0) + if (adjust_shared_perm(r, get_tempfile_path(f)) < 0) goto out; if (rename_tempfile(&f, path) < 0) goto out; @@ -151,7 +153,7 @@ static int add_info_ref(const char *path, const char *referent UNUSED, const str void *cb_data) { struct update_info_ctx *uic = cb_data; - struct object *o = parse_object(the_repository, oid); + struct object *o = parse_object(uic->repo, oid); if (!o) return -1; @@ -159,7 +161,7 @@ static int add_info_ref(const char *path, const char *referent UNUSED, const str return -1; if (o->type == OBJ_TAG) { - o = deref_tag(the_repository, o, path, 0); + o = deref_tag(uic->repo, o, path, 0); if (o) if (uic_printf(uic, "%s %s^{}\n", oid_to_hex(&o->oid), path) < 0) @@ -170,14 +172,14 @@ static int add_info_ref(const char *path, const char *referent UNUSED, const str static int generate_info_refs(struct update_info_ctx *uic) { - return refs_for_each_ref(get_main_ref_store(the_repository), + return refs_for_each_ref(get_main_ref_store(uic->repo), add_info_ref, uic); } -static int update_info_refs(int force) +static int update_info_refs(struct repository *r, int force) { - char *path = git_pathdup("info/refs"); - int ret = update_info_file(path, generate_info_refs, force); + char *path = repo_git_path(r, "info/refs"); + int ret = update_info_file(r, path, generate_info_refs, force); free(path); return ret; } @@ -283,14 +285,14 @@ static int compare_info(const void *a_, const void *b_) return 1; } -static void init_pack_info(const char *infofile, int force) +static void init_pack_info(struct repository *r, const char *infofile, int force) { struct packed_git *p; int stale; int i; size_t alloc = 0; - for (p = get_all_packs(the_repository); p; p = p->next) { + for (p = get_all_packs(r); p; p = p->next) { /* we ignore things on alternate path since they are * not available to the pullers in general. */ @@ -339,33 +341,36 @@ static int write_pack_info_file(struct update_info_ctx *uic) return 0; } -static int update_info_packs(int force) +static int update_info_packs(struct repository *r, int force) { char *infofile = mkpathdup("%s/info/packs", - repo_get_object_directory(the_repository)); + repo_get_object_directory(r)); int ret; - init_pack_info(infofile, force); - ret = update_info_file(infofile, write_pack_info_file, force); + init_pack_info(r, infofile, force); + ret = update_info_file(r, infofile, write_pack_info_file, force); free_pack_info(); free(infofile); return ret; } /* public */ -int update_server_info(int force) +int update_server_info(struct repository *r, int force) { /* We would add more dumb-server support files later, * including index of available pack files and their * intended audiences. */ int errs = 0; + char *path; - errs = errs | update_info_refs(force); - errs = errs | update_info_packs(force); + errs = errs | update_info_refs(r, force); + errs = errs | update_info_packs(r, force); /* remove leftover rev-cache file if there is any */ - unlink_or_warn(git_path("info/rev-cache")); + path = repo_git_path(r, "info/rev-cache"); + unlink_or_warn(path); + free(path); return errs; } diff --git a/server-info.h b/server-info.h index 13bbde2c55fafe..e634d1722bdfaa 100644 --- a/server-info.h +++ b/server-info.h @@ -1,7 +1,9 @@ #ifndef SERVER_INFO_H #define SERVER_INFO_H +struct repository; + /* Dumb servers support */ -int update_server_info(int); +int update_server_info(struct repository *r, int force); #endif /* SERVER_INFO_H */ diff --git a/setup.c b/setup.c index 94e79b2e487f3f..f93bd6a24a5d9c 100644 --- a/setup.c +++ b/setup.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -683,6 +684,9 @@ static enum extension_result handle_extension(const char *var, "extensions.refstorage", value); data->ref_storage_format = format; return EXTENSION_OK; + } else if (!strcmp(ext, "relativeworktrees")) { + data->relative_worktrees = git_config_bool(var, value); + return EXTENSION_OK; } return EXTENSION_UNKNOWN; } @@ -788,7 +792,7 @@ int upgrade_repository_format(int target_version) struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT; int ret; - strbuf_git_common_path(&sb, the_repository, "config"); + repo_common_path_append(the_repository, &sb, "config"); read_repository_format(&repo_fmt, sb.buf); strbuf_release(&sb); @@ -1818,7 +1822,7 @@ const char *setup_git_directory_gently(int *nongit_ok) * * Regardless of the state of nongit_ok, startup_info->prefix and * the GIT_PREFIX environment variable must always match. For details - * see Documentation/config/alias.txt. + * see Documentation/config/alias.adoc. */ if (nongit_ok && *nongit_ok) startup_info->have_repository = 0; @@ -1854,6 +1858,8 @@ const char *setup_git_directory_gently(int *nongit_ok) repo_fmt.ref_storage_format); the_repository->repository_format_worktree_config = repo_fmt.worktree_config; + the_repository->repository_format_relative_worktrees = + repo_fmt.relative_worktrees; /* take ownership of repo_fmt.partial_clone */ the_repository->repository_format_partial_clone = repo_fmt.partial_clone; @@ -1950,6 +1956,8 @@ void check_repository_format(struct repository_format *fmt) fmt->ref_storage_format); the_repository->repository_format_worktree_config = fmt->worktree_config; + the_repository->repository_format_relative_worktrees = + fmt->relative_worktrees; the_repository->repository_format_partial_clone = xstrdup_or_null(fmt->partial_clone); clear_repository_format(&repo_fmt); @@ -2080,7 +2088,7 @@ static void copy_templates_1(struct strbuf *path, struct strbuf *template_path, * with the way the namespace under .git/ is organized, should * be really carefully chosen. */ - safe_create_dir(path->buf, 1); + safe_create_dir(the_repository, path->buf, 1); while ((de = readdir(dir)) != NULL) { struct stat st_git, st_template; int exists = 0; @@ -2204,8 +2212,8 @@ void initialize_repository_version(int hash_algo, enum ref_storage_format ref_storage_format, int reinit) { - char repo_version_string[10]; - int repo_version = GIT_REPO_VERSION; + struct strbuf repo_version = STRBUF_INIT; + int target_version = GIT_REPO_VERSION; /* * Note that we initialize the repository version to 1 when the ref @@ -2216,12 +2224,7 @@ void initialize_repository_version(int hash_algo, */ 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 */ - xsnprintf(repo_version_string, sizeof(repo_version_string), - "%d", repo_version); - git_config_set("core.repositoryformatversion", repo_version_string); + target_version = GIT_REPO_VERSION_READ; if (hash_algo != GIT_HASH_SHA1 && hash_algo != GIT_HASH_UNKNOWN) git_config_set("extensions.objectformat", @@ -2234,6 +2237,25 @@ void initialize_repository_version(int hash_algo, ref_storage_format_to_name(ref_storage_format)); else if (reinit) git_config_set_gently("extensions.refstorage", NULL); + + if (reinit) { + struct strbuf config = STRBUF_INIT; + struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT; + + repo_common_path_append(the_repository, &config, "config"); + read_repository_format(&repo_fmt, config.buf); + + if (repo_fmt.v1_only_extensions.nr) + target_version = GIT_REPO_VERSION_READ; + + strbuf_release(&config); + clear_repository_format(&repo_fmt); + } + + strbuf_addf(&repo_version, "%d", target_version); + git_config_set("core.repositoryformatversion", repo_version.buf); + + strbuf_release(&repo_version); } static int is_reinit(void) @@ -2242,7 +2264,7 @@ static int is_reinit(void) char junk[2]; int ret; - git_path_buf(&buf, "HEAD"); + repo_git_path_replace(the_repository, &buf, "HEAD"); ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1; strbuf_release(&buf); return ret; @@ -2294,8 +2316,7 @@ static int create_default_files(const char *template_path, int init_shared_repository) { struct stat st1; - struct strbuf buf = STRBUF_INIT; - char *path; + struct strbuf path = STRBUF_INIT; int reinit; int filemode; const char *work_tree = repo_get_work_tree(the_repository); @@ -2311,7 +2332,7 @@ static int create_default_files(const char *template_path, */ copy_templates(template_path); git_config_clear(); - reset_shared_repository(); + repo_settings_reset_shared_repository(the_repository); git_config(git_default_config, NULL); reinit = is_reinit(); @@ -2321,7 +2342,8 @@ static int create_default_files(const char *template_path, * values we might have just re-read from the config. */ if (init_shared_repository != -1) - set_shared_repository(init_shared_repository); + repo_settings_set_shared_repository(the_repository, + init_shared_repository); is_bare_repository_cfg = !work_tree; @@ -2329,21 +2351,21 @@ static int create_default_files(const char *template_path, * We would have created the above under user's umask -- under * shared-repository settings, we would need to fix them up. */ - if (get_shared_repository()) { - adjust_shared_perm(repo_get_git_dir(the_repository)); + if (repo_settings_get_shared_repository(the_repository)) { + adjust_shared_perm(the_repository, repo_get_git_dir(the_repository)); } - initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, 0); + initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, reinit); /* Check filemode trustability */ - path = git_path_buf(&buf, "config"); + repo_git_path_replace(the_repository, &path, "config"); filemode = TEST_FILEMODE; - if (TEST_FILEMODE && !lstat(path, &st1)) { + if (TEST_FILEMODE && !lstat(path.buf, &st1)) { struct stat st2; - filemode = (!chmod(path, st1.st_mode ^ S_IXUSR) && - !lstat(path, &st2) && + filemode = (!chmod(path.buf, st1.st_mode ^ S_IXUSR) && + !lstat(path.buf, &st2) && st1.st_mode != st2.st_mode && - !chmod(path, st1.st_mode)); + !chmod(path.buf, st1.st_mode)); if (filemode && !reinit && (st1.st_mode & S_IXUSR)) filemode = 0; } @@ -2362,24 +2384,24 @@ static int create_default_files(const char *template_path, if (!reinit) { /* Check if symlink is supported in the work tree */ - path = git_path_buf(&buf, "tXXXXXX"); - if (!close(xmkstemp(path)) && - !unlink(path) && - !symlink("testing", path) && - !lstat(path, &st1) && + repo_git_path_replace(the_repository, &path, "tXXXXXX"); + if (!close(xmkstemp(path.buf)) && + !unlink(path.buf) && + !symlink("testing", path.buf) && + !lstat(path.buf, &st1) && S_ISLNK(st1.st_mode)) - unlink(path); /* good */ + unlink(path.buf); /* good */ else git_config_set("core.symlinks", "false"); /* Check if the filesystem is case-insensitive */ - path = git_path_buf(&buf, "CoNfIg"); - if (!access(path, F_OK)) + repo_git_path_replace(the_repository, &path, "CoNfIg"); + if (!access(path.buf, F_OK)) git_config_set("core.ignorecase", "true"); probe_utf8_pathname_composition(); } - strbuf_release(&buf); + strbuf_release(&path); return reinit; } @@ -2391,15 +2413,15 @@ static void create_object_directory(void) strbuf_addstr(&path, repo_get_object_directory(the_repository)); baselen = path.len; - safe_create_dir(path.buf, 1); + safe_create_dir(the_repository, path.buf, 1); strbuf_setlen(&path, baselen); strbuf_addstr(&path, "/pack"); - safe_create_dir(path.buf, 1); + safe_create_dir(the_repository, path.buf, 1); strbuf_setlen(&path, baselen); strbuf_addstr(&path, "/info"); - safe_create_dir(path.buf, 1); + safe_create_dir(the_repository, path.buf, 1); strbuf_release(&path); } @@ -2420,7 +2442,7 @@ static void separate_git_dir(const char *git_dir, const char *git_link) if (rename(src, git_dir)) die_errno(_("unable to move %s to %s"), src, git_dir); - repair_worktrees(NULL, NULL); + repair_worktrees_after_gitdir_move(src); } write_file(git_link, "gitdir: %s", git_dir); @@ -2495,7 +2517,9 @@ static void repository_format_configure(struct repository_format *repo_fmt, int env_algo = hash_algo_by_name(env); if (env_algo == GIT_HASH_UNKNOWN) die(_("unknown hash algorithm '%s'"), env); - repo_fmt->hash_algo = env_algo; + if (repo_fmt->version < 0 || + repo_fmt->hash_algo == GIT_HASH_UNKNOWN) + repo_fmt->hash_algo = env_algo; } else if (cfg.hash != GIT_HASH_UNKNOWN) { repo_fmt->hash_algo = cfg.hash; } @@ -2512,7 +2536,9 @@ static void repository_format_configure(struct repository_format *repo_fmt, ref_format = ref_storage_format_by_name(env); if (ref_format == REF_STORAGE_FORMAT_UNKNOWN) die(_("unknown ref storage format '%s'"), env); - repo_fmt->ref_storage_format = ref_format; + if (repo_fmt->version < 0 || + repo_fmt->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN) + repo_fmt->ref_storage_format = ref_format; } else if (cfg.ref_format != REF_STORAGE_FORMAT_UNKNOWN) { repo_fmt->ref_storage_format = cfg.ref_format; } @@ -2566,7 +2592,7 @@ int init_db(const char *git_dir, const char *real_git_dir, */ git_config(platform_core_config, NULL); - safe_create_dir(git_dir, 0); + safe_create_dir(the_repository, git_dir, 0); reinit = create_default_files(template_dir, original_git_dir, &repo_fmt, init_shared_repository); @@ -2576,7 +2602,7 @@ int init_db(const char *git_dir, const char *real_git_dir, initial_branch, flags & INIT_DB_QUIET); create_object_directory(); - if (get_shared_repository()) { + if (repo_settings_get_shared_repository(the_repository)) { char buf[10]; /* We do not spell "group" and such, so that * the configuration can be read by older version @@ -2584,12 +2610,12 @@ int init_db(const char *git_dir, const char *real_git_dir, * and compatibility values for PERM_GROUP and * PERM_EVERYBODY. */ - if (get_shared_repository() < 0) + if (repo_settings_get_shared_repository(the_repository) < 0) /* force to the mode value */ - xsnprintf(buf, sizeof(buf), "0%o", -get_shared_repository()); - else if (get_shared_repository() == PERM_GROUP) + xsnprintf(buf, sizeof(buf), "0%o", -repo_settings_get_shared_repository(the_repository)); + else if (repo_settings_get_shared_repository(the_repository) == PERM_GROUP) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP); - else if (get_shared_repository() == PERM_EVERYBODY) + else if (repo_settings_get_shared_repository(the_repository) == PERM_EVERYBODY) xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY); else BUG("invalid value for shared_repository"); @@ -2601,12 +2627,12 @@ int init_db(const char *git_dir, const char *real_git_dir, int len = strlen(git_dir); if (reinit) - printf(get_shared_repository() + printf(repo_settings_get_shared_repository(the_repository) ? _("Reinitialized existing shared Git repository in %s%s\n") : _("Reinitialized existing Git repository in %s%s\n"), git_dir, len && git_dir[len-1] != '/' ? "/" : ""); else - printf(get_shared_repository() + printf(repo_settings_get_shared_repository(the_repository) ? _("Initialized empty shared Git repository in %s%s\n") : _("Initialized empty Git repository in %s%s\n"), git_dir, len && git_dir[len-1] != '/' ? "/" : ""); diff --git a/setup.h b/setup.h index e496ab3e4de580..18dc3b73686ce2 100644 --- a/setup.h +++ b/setup.h @@ -129,6 +129,7 @@ struct repository_format { int precious_objects; char *partial_clone; /* value of extensions.partialclone */ int worktree_config; + int relative_worktrees; int is_bare; int hash_algo; int compat_hash_algo; diff --git a/sha1/openssl.h b/sha1/openssl.h index 006c1f4ba541cb..1038af47dafa79 100644 --- a/sha1/openssl.h +++ b/sha1/openssl.h @@ -40,10 +40,12 @@ static inline void openssl_SHA1_Clone(struct openssl_SHA1_CTX *dst, EVP_MD_CTX_copy_ex(dst->ectx, src->ectx); } +#ifndef platform_SHA_CTX #define platform_SHA_CTX openssl_SHA1_CTX #define platform_SHA1_Init openssl_SHA1_Init #define platform_SHA1_Clone openssl_SHA1_Clone #define platform_SHA1_Update openssl_SHA1_Update #define platform_SHA1_Final openssl_SHA1_Final +#endif #endif /* SHA1_OPENSSL_H */ diff --git a/sha1dc_git.h b/sha1dc_git.h index 60e3ce84395cea..f6f880cabea382 100644 --- a/sha1dc_git.h +++ b/sha1dc_git.h @@ -18,7 +18,10 @@ void git_SHA1DCFinal(unsigned char [20], SHA1_CTX *); void git_SHA1DCUpdate(SHA1_CTX *ctx, const void *data, unsigned long len); #define platform_SHA_IS_SHA1DC /* used by "test-tool sha1-is-sha1dc" */ + +#ifndef platform_SHA_CTX #define platform_SHA_CTX SHA1_CTX #define platform_SHA1_Init git_SHA1DCInit #define platform_SHA1_Update git_SHA1DCUpdate #define platform_SHA1_Final git_SHA1DCFinal +#endif diff --git a/shallow.c b/shallow.c index dcebc263d704ce..4bd9342c9a745a 100644 --- a/shallow.c +++ b/shallow.c @@ -51,12 +51,11 @@ int unregister_shallow(const struct object_id *oid) int pos = commit_graft_pos(the_repository, oid); if (pos < 0) return -1; - if (pos + 1 < the_repository->parsed_objects->grafts_nr) { - free(the_repository->parsed_objects->grafts[pos]); + free(the_repository->parsed_objects->grafts[pos]); + if (pos + 1 < the_repository->parsed_objects->grafts_nr) MOVE_ARRAY(the_repository->parsed_objects->grafts + pos, the_repository->parsed_objects->grafts + pos + 1, the_repository->parsed_objects->grafts_nr - pos - 1); - } the_repository->parsed_objects->grafts_nr--; return 0; } @@ -134,7 +133,8 @@ static void free_depth_in_slab(int **ptr) struct commit_list *get_shallow_commits(struct object_array *heads, int depth, int shallow_flag, int not_shallow_flag) { - int i = 0, cur_depth = 0; + size_t i = 0; + int cur_depth = 0; struct commit_list *result = NULL; struct object_array stack = OBJECT_ARRAY_INIT; struct commit *commit = NULL; @@ -335,16 +335,16 @@ static int write_shallow_commits_1(struct strbuf *out, int use_pack_protocol, const struct oid_array *extra, unsigned flags) { - struct write_shallow_data data; - int i; - data.out = out; - data.use_pack_protocol = use_pack_protocol; - data.count = 0; - data.flags = flags; + struct write_shallow_data data = { + .out = out, + .use_pack_protocol = use_pack_protocol, + .flags = flags, + }; + for_each_commit_graft(write_one_shallow, &data); if (!extra) return data.count; - for (i = 0; i < extra->nr; i++) { + for (size_t i = 0; i < extra->nr; i++) { strbuf_addstr(out, oid_to_hex(extra->oid + i)); strbuf_addch(out, '\n'); data.count++; @@ -364,7 +364,9 @@ const char *setup_temporary_shallow(const struct oid_array *extra) struct strbuf sb = STRBUF_INIT; if (write_shallow_commits(&sb, 0, extra)) { - temp = xmks_tempfile(git_path("shallow_XXXXXX")); + char *path = repo_git_path(the_repository, "shallow_XXXXXX"); + temp = xmks_tempfile(path); + free(path); if (write_in_full(temp->fd, sb.buf, sb.len) < 0 || close_tempfile_gently(temp) < 0) @@ -466,7 +468,6 @@ struct trace_key trace_shallow = TRACE_KEY_INIT(SHALLOW); */ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) { - int i; trace_printf_key(&trace_shallow, "shallow: prepare_shallow_info\n"); memset(info, 0, sizeof(*info)); info->shallow = sa; @@ -474,7 +475,7 @@ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) return; ALLOC_ARRAY(info->ours, sa->nr); ALLOC_ARRAY(info->theirs, sa->nr); - for (i = 0; i < sa->nr; i++) { + for (size_t i = 0; i < sa->nr; i++) { if (repo_has_object_file(the_repository, sa->oid + i)) { struct commit_graft *graft; graft = lookup_commit_graft(the_repository, @@ -507,7 +508,7 @@ void clear_shallow_info(struct shallow_info *info) void remove_nonexistent_theirs_shallow(struct shallow_info *info) { struct object_id *oid = info->shallow->oid; - int i, dst; + size_t i, dst; trace_printf_key(&trace_shallow, "shallow: remove_nonexistent_theirs_shallow\n"); for (i = dst = 0; i < info->nr_theirs; i++) { if (i != dst) @@ -535,7 +536,7 @@ static uint32_t *paint_alloc(struct paint_info *info) unsigned nr = DIV_ROUND_UP(info->nr_bits, 32); unsigned size = nr * sizeof(uint32_t); void *p; - if (!info->pool_count || size > info->end - info->free) { + if (!info->pool_count || info->end < info->free + size) { if (size > POOL_SIZE) BUG("pool size too small for %d in paint_alloc()", size); @@ -560,7 +561,7 @@ static void paint_down(struct paint_info *info, const struct object_id *oid, { unsigned int i, nr; struct commit_list *head = NULL; - int bitmap_nr = DIV_ROUND_UP(info->nr_bits, 32); + size_t bitmap_nr = DIV_ROUND_UP(info->nr_bits, 32); size_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr); struct commit *c = lookup_commit_reference_gently(the_repository, oid, 1); @@ -660,7 +661,7 @@ void assign_shallow_commits_to_refs(struct shallow_info *info, struct object_id *oid = info->shallow->oid; struct oid_array *ref = info->ref; unsigned int i, nr; - int *shallow, nr_shallow = 0; + size_t *shallow, nr_shallow = 0; struct paint_info pi; trace_printf_key(&trace_shallow, "shallow: assign_shallow_commits_to_refs\n"); @@ -735,7 +736,7 @@ void assign_shallow_commits_to_refs(struct shallow_info *info, struct commit_array { struct commit **commits; - int nr, alloc; + size_t nr, alloc; }; static int add_ref(const char *refname UNUSED, @@ -753,12 +754,11 @@ static int add_ref(const char *refname UNUSED, return 0; } -static void update_refstatus(int *ref_status, int nr, uint32_t *bitmap) +static void update_refstatus(int *ref_status, size_t nr, uint32_t *bitmap) { - unsigned int i; if (!ref_status) return; - for (i = 0; i < nr; i++) + for (size_t i = 0; i < nr; i++) if (bitmap[i / 32] & (1U << (i % 32))) ref_status[i]++; } @@ -773,8 +773,8 @@ static void post_assign_shallow(struct shallow_info *info, struct object_id *oid = info->shallow->oid; struct commit *c; uint32_t **bitmap; - int dst, i, j; - int bitmap_nr = DIV_ROUND_UP(info->ref->nr, 32); + size_t dst, i, j; + size_t bitmap_nr = DIV_ROUND_UP(info->ref->nr, 32); struct commit_array ca; trace_printf_key(&trace_shallow, "shallow: post_assign_shallow\n"); diff --git a/shallow.h b/shallow.h index e9ca7e4bc80451..9bfeade93ead74 100644 --- a/shallow.h +++ b/shallow.h @@ -59,8 +59,8 @@ void prune_shallow(unsigned options); */ struct shallow_info { struct oid_array *shallow; - int *ours, nr_ours; - int *theirs, nr_theirs; + size_t *ours, nr_ours; + size_t *theirs, nr_theirs; struct oid_array *ref; /* for receive-pack */ @@ -69,7 +69,7 @@ struct shallow_info { int *reachable; int *shallow_ref; struct commit **commits; - int nr_commits; + size_t nr_commits; }; void prepare_shallow_info(struct shallow_info *, struct oid_array *); diff --git a/shared.mak b/shared.mak index 29bebd30d8acbc..1a99848a95174c 100644 --- a/shared.mak +++ b/shared.mak @@ -116,3 +116,14 @@ endef define libpath_template -L$(1) $(if $(filter-out -L,$(CC_LD_DYNPATH)),$(CC_LD_DYNPATH)$(1)) endef + +# Populate build information into a file via GIT-VERSION-GEN. Requires the +# absolute path to the root source directory as well as input and output files +# as arguments, in that order. +define version_gen +GIT_BUILT_FROM_COMMIT="$(GIT_BUILT_FROM_COMMIT)" \ +GIT_DATE="$(GIT_DATE)" \ +GIT_USER_AGENT="$(GIT_USER_AGENT)" \ +GIT_VERSION="$(GIT_VERSION_OVERRIDE)" \ +$(SHELL_PATH) "$(1)/GIT-VERSION-GEN" "$(1)" "$(2)" "$(3)" +endef diff --git a/shell.c b/shell.c index 2ece8b16e2e8e1..76333c80686d8f 100644 --- a/shell.c +++ b/shell.c @@ -143,6 +143,7 @@ static void run_shell(void) } free(argv); + free(split_args); free(rawargs); } while (!done); } @@ -216,9 +217,8 @@ int cmd_main(int argc, const char **argv) count = split_cmdline(prog, &user_argv); if (count >= 0) { if (is_valid_cmd_name(user_argv[0])) { - prog = make_cmd(user_argv[0]); - user_argv[0] = prog; - execv(user_argv[0], (char *const *) user_argv); + char *cmd = make_cmd(user_argv[0]); + execv(cmd, (char *const *) user_argv); } free(prog); free(user_argv); diff --git a/sideband.c b/sideband.c index 02805573fab85d..251e9615ed0239 100644 --- a/sideband.c +++ b/sideband.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "color.h" diff --git a/simple-ipc.h b/simple-ipc.h index a849d9f8411fdb..701e005cb8e5f3 100644 --- a/simple-ipc.h +++ b/simple-ipc.h @@ -2,7 +2,7 @@ #define GIT_SIMPLE_IPC_H /* - * See Documentation/technical/api-simple-ipc.txt + * See Documentation/technical/api-simple-ipc.adoc */ enum ipc_active_state { @@ -179,11 +179,20 @@ struct ipc_server_opts * When a client IPC message is received, the `application_cb` will be * called (possibly on a random thread) to handle the message and * optionally compose a reply message. + * + * This initializes all threads but no actual work will be done until + * ipc_server_start_async() is called. + */ +int ipc_server_init_async(struct ipc_server_data **returned_server_data, + const char *path, const struct ipc_server_opts *opts, + ipc_server_application_cb *application_cb, + void *application_data); + +/* + * Let an async server start running. This needs to be called only once + * after initialization. */ -int ipc_server_run_async(struct ipc_server_data **returned_server_data, - const char *path, const struct ipc_server_opts *opts, - ipc_server_application_cb *application_cb, - void *application_data); +void ipc_server_start_async(struct ipc_server_data *server_data); /* * Gently signal the IPC server pool to shutdown. No new client diff --git a/sparse-index.c b/sparse-index.c index 542ca5f411ca52..5634abafaa07ed 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -1,7 +1,9 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" +#include "ewah/ewok.h" #include "gettext.h" #include "name-hash.h" #include "read-cache-ll.h" @@ -21,9 +23,10 @@ * advice for advice.sparseIndexExpanded when expanding a sparse index to a full * one. However, this is sometimes done on purpose, such as in the sparse-checkout * builtin, even when index.sparse=false. This may be disabled in - * convert_to_sparse(). + * convert_to_sparse() or by commands that know they will lead to a full + * expansion, but this message is not actionable. */ -static int give_advice_on_expansion = 1; +int give_advice_on_expansion = 1; #define ADVICE_MSG \ "The sparse index is expanding to a full index, a slow operation.\n" \ "Your working directory likely has contents that are outside of\n" \ @@ -241,7 +244,8 @@ int convert_to_sparse(struct index_state *istate, int flags) cache_tree_update(istate, 0); istate->fsmonitor_has_run_once = 0; - FREE_AND_NULL(istate->fsmonitor_dirty); + ewah_free(istate->fsmonitor_dirty); + istate->fsmonitor_dirty = NULL; FREE_AND_NULL(istate->fsmonitor_last_update); istate->sparse_index = INDEX_COLLAPSED; @@ -437,7 +441,8 @@ void expand_index(struct index_state *istate, struct pattern_list *pl) istate->cache_nr = full->cache_nr; istate->cache_alloc = full->cache_alloc; istate->fsmonitor_has_run_once = 0; - FREE_AND_NULL(istate->fsmonitor_dirty); + ewah_free(istate->fsmonitor_dirty); + istate->fsmonitor_dirty = NULL; FREE_AND_NULL(istate->fsmonitor_last_update); strbuf_release(&base); diff --git a/sparse-index.h b/sparse-index.h index a16f3e67d75913..727034be7ca917 100644 --- a/sparse-index.h +++ b/sparse-index.h @@ -1,6 +1,13 @@ #ifndef SPARSE_INDEX_H__ #define SPARSE_INDEX_H__ +/* + * If performing an operation where the index is supposed to expand to a + * full index, then disable the advice message by setting this global to + * zero. + */ +extern int give_advice_on_expansion; + struct index_state; #define SPARSE_INDEX_MEMORY_ONLY (1 << 0) int is_sparse_index_allowed(struct index_state *istate, int flags); diff --git a/split-index.c b/split-index.c index 120c8190b187bc..4c74c4adda45d6 100644 --- a/split-index.c +++ b/split-index.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" @@ -97,7 +98,11 @@ void move_cache_to_base_index(struct index_state *istate) mem_pool_combine(istate->ce_mem_pool, istate->split_index->base->ce_mem_pool); } - ALLOC_ARRAY(si->base, 1); + if (si->base) + release_index(si->base); + else + ALLOC_ARRAY(si->base, 1); + index_state_init(si->base, istate->repo); si->base->version = istate->version; /* zero timestamp disables racy test in ce_write_index() */ diff --git a/strbuf.c b/strbuf.c index 3d2189a7f648dc..f30fdc6984310e 100644 --- a/strbuf.c +++ b/strbuf.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "gettext.h" #include "hex-ll.h" @@ -495,7 +497,9 @@ void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags) unsigned char ch = src[i]; if (ch <= 0x1F || ch >= 0x7F || (ch == '/' && (flags & STRBUF_ENCODE_SLASH)) || - strchr(URL_UNSAFE_CHARS, ch)) + ((flags & STRBUF_ENCODE_HOST_AND_PORT) ? + !isalnum(ch) && !strchr("-.:[]", ch) : + !!strchr(URL_UNSAFE_CHARS, ch))) strbuf_addf(dst, "%%%02X", (unsigned char)ch); else strbuf_addch(dst, ch); diff --git a/strbuf.h b/strbuf.h index 003f880ff7d61c..6362777c0a017d 100644 --- a/strbuf.h +++ b/strbuf.h @@ -356,6 +356,7 @@ void strbuf_expand_bad_format(const char *format, const char *command); void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src); #define STRBUF_ENCODE_SLASH 1 +#define STRBUF_ENCODE_HOST_AND_PORT 2 /** * Append the contents of a string to a strbuf, percent-encoding any characters @@ -637,28 +638,6 @@ static inline void strbuf_complete_line(struct strbuf *sb) strbuf_complete(sb, '\n'); } -/* - * Copy "name" to "sb", expanding any special @-marks as handled by - * repo_interpret_branch_name(). The result is a non-qualified branch name - * (so "foo" or "origin/master" instead of "refs/heads/foo" or - * "refs/remotes/origin/master"). - * - * Note that the resulting name may not be a syntactically valid refname. - * - * If "allowed" is non-zero, restrict the set of allowed expansions. See - * repo_interpret_branch_name() for details. - */ -void strbuf_branchname(struct strbuf *sb, const char *name, - unsigned allowed); - -/* - * Like strbuf_branchname() above, but confirm that the result is - * syntactically valid to be used as a local branch name in refs/heads/. - * - * The return value is "0" if the result is valid, and "-1" otherwise. - */ -int strbuf_check_branch_ref(struct strbuf *sb, const char *name); - typedef int (*char_predicate)(char ch); void strbuf_addstr_urlencode(struct strbuf *sb, const char *name, diff --git a/string-list.c b/string-list.c index 954569f381d8d7..bf061fec563d74 100644 --- a/string-list.c +++ b/string-list.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "string-list.h" diff --git a/strvec.c b/strvec.c index f712070f5745d5..f8de79f5579b49 100644 --- a/strvec.c +++ b/strvec.c @@ -56,6 +56,28 @@ void strvec_pushv(struct strvec *array, const char **items) strvec_push(array, *items); } +void strvec_splice(struct strvec *array, size_t idx, size_t len, + const char **replacement, size_t replacement_len) +{ + if (idx + len > array->nr) + BUG("range outside of array boundary"); + if (replacement_len > len) { + if (array->v == empty_strvec) + array->v = NULL; + ALLOC_GROW(array->v, array->nr + (replacement_len - len) + 1, + array->alloc); + array->v[array->nr + (replacement_len - len)] = NULL; + } + for (size_t i = 0; i < len; i++) + free((char *)array->v[idx + i]); + if ((replacement_len != len) && array->nr) + memmove(array->v + idx + replacement_len, array->v + idx + len, + (array->nr - idx - len + 1) * sizeof(char *)); + array->nr += replacement_len - len; + for (size_t i = 0; i < replacement_len; i++) + array->v[idx + i] = xstrdup(replacement[i]); +} + const char *strvec_replace(struct strvec *array, size_t idx, const char *replacement) { char *to_free; @@ -108,8 +130,7 @@ void strvec_split(struct strvec *array, const char *to_split) void strvec_clear(struct strvec *array) { if (array->v != empty_strvec) { - int i; - for (i = 0; i < array->nr; i++) + for (size_t i = 0; i < array->nr; i++) free((char *)array->v[i]); free(array->v); } diff --git a/strvec.h b/strvec.h index 4b73c1f092e9b0..f74e061e1419bc 100644 --- a/strvec.h +++ b/strvec.h @@ -67,6 +67,15 @@ void strvec_pushl(struct strvec *, ...); /* Push a null-terminated array of strings onto the end of the array. */ void strvec_pushv(struct strvec *, const char **); +/* + * Replace `len` values starting at `idx` with the provided replacement + * strings. If `len` is zero this is effectively an insert at the given `idx`. + * If `replacement_len` is zero this is effectively a delete of `len` items + * starting at `idx`. + */ +void strvec_splice(struct strvec *array, size_t idx, size_t len, + const char **replacement, size_t replacement_len); + /** * Replace the value at the given index with a new value. The index must be * valid. Returns a pointer to the inserted value. diff --git a/submodule-config.c b/submodule-config.c index c8f2bb2bdd3ef2..a25059ed7f8d8f 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "dir.h" @@ -95,7 +96,7 @@ static void free_one_config(struct submodule_entry *entry) free((void *) entry->config->branch); free((void *) entry->config->url); free((void *) entry->config->ignore); - free((void *) entry->config->update_strategy.command); + submodule_update_strategy_release(&entry->config->update_strategy); free(entry->config); } @@ -901,8 +902,9 @@ static void traverse_tree_submodules(struct repository *r, struct submodule_tree_entry *st_entry; struct name_entry name_entry; char *tree_path = NULL; + char *tree_buf; - fill_tree_descriptor(r, &tree, treeish_name); + tree_buf = fill_tree_descriptor(r, &tree, treeish_name); while (tree_entry(&tree, &name_entry)) { if (prefix) tree_path = @@ -930,6 +932,8 @@ static void traverse_tree_submodules(struct repository *r, &name_entry.oid, out); free(tree_path); } + + free(tree_buf); } void submodules_of_tree(struct repository *r, @@ -943,6 +947,16 @@ void submodules_of_tree(struct repository *r, traverse_tree_submodules(r, treeish_name, NULL, treeish_name, out); } +void submodule_entry_list_release(struct submodule_entry_list *list) +{ + for (size_t i = 0; i < list->entry_nr; i++) { + free(list->entries[i].name_entry); + repo_clear(list->entries[i].repo); + free(list->entries[i].repo); + } + free(list->entries); +} + void submodule_free(struct repository *r) { if (r->submodule_cache) diff --git a/submodule-config.h b/submodule-config.h index b6133af71b00d6..f55d4e3b61a59b 100644 --- a/submodule-config.h +++ b/submodule-config.h @@ -136,4 +136,7 @@ struct submodule_entry_list { void submodules_of_tree(struct repository *r, const struct object_id *treeish_name, struct submodule_entry_list *ret); + +void submodule_entry_list_release(struct submodule_entry_list *list); + #endif /* SUBMODULE_CONFIG_H */ diff --git a/submodule.c b/submodule.c index 4e71ac0dfdecea..0530e8cf24e045 100644 --- a/submodule.c +++ b/submodule.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -175,11 +176,11 @@ void stage_updated_gitmodules(struct index_state *istate) die(_("staging updated .gitmodules failed")); } -static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_NODUP; +static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_DUP; void add_submodule_odb_by_path(const char *path) { - string_list_insert(&added_submodule_odb_paths, xstrdup(path)); + string_list_insert(&added_submodule_odb_paths, path); } int register_all_submodule_odb_as_alternates(void) @@ -424,6 +425,11 @@ int parse_submodule_update_strategy(const char *value, return 0; } +void submodule_update_strategy_release(struct submodule_update_strategy *strategy) +{ + free((char *) strategy->command); +} + const char *submodule_update_type_to_string(enum submodule_update_type type) { switch (type) { @@ -530,7 +536,8 @@ static struct repository *open_submodule(const char *path) struct strbuf sb = STRBUF_INIT; struct repository *out = xmalloc(sizeof(*out)); - if (submodule_to_gitdir(&sb, path) || repo_init(out, sb.buf, NULL)) { + if (submodule_to_gitdir(the_repository, &sb, path) || + repo_init(out, sb.buf, NULL)) { strbuf_release(&sb); free(out); return NULL; @@ -1169,8 +1176,8 @@ static int push_submodule(const char *path, if (remote->origin != REMOTE_UNCONFIGURED) { int i; strvec_push(&cp.args, remote->name); - for (i = 0; i < rs->raw_nr; i++) - strvec_push(&cp.args, rs->raw[i]); + for (i = 0; i < rs->nr; i++) + strvec_push(&cp.args, rs->items[i].raw); } prepare_submodule_repo_env(&cp.env); @@ -1204,8 +1211,8 @@ static void submodule_push_check(const char *path, const char *head, strvec_push(&cp.args, head); strvec_push(&cp.args, remote->name); - for (i = 0; i < rs->raw_nr; i++) - strvec_push(&cp.args, rs->raw[i]); + for (i = 0; i < rs->nr; i++) + strvec_push(&cp.args, rs->items[i].raw); prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; @@ -1309,7 +1316,7 @@ static int repo_has_absorbed_submodules(struct repository *r) int ret; struct strbuf buf = STRBUF_INIT; - strbuf_repo_git_path(&buf, r, "modules/"); + repo_git_path_append(r, &buf, "modules/"); ret = file_exists(buf.buf) && !is_empty_dir(buf.buf); strbuf_release(&buf); return ret; @@ -1484,14 +1491,13 @@ struct fetch_task { */ static const struct submodule *get_non_gitmodules_submodule(const char *path) { - struct submodule *ret = NULL; + struct submodule *ret; const char *name = default_name_or_path(path); if (!name) return NULL; - ret = xmalloc(sizeof(*ret)); - memset(ret, 0, sizeof(*ret)); + CALLOC_ARRAY(ret, 1); ret->path = name; ret->name = name; @@ -1531,8 +1537,9 @@ static struct fetch_task *fetch_task_create(struct submodule_parallel_fetch *spf const char *path, const struct object_id *treeish_name) { - struct fetch_task *task = xmalloc(sizeof(*task)); - memset(task, 0, sizeof(*task)); + struct fetch_task *task; + + CALLOC_ARRAY(task, 1); if (validate_submodule_path(path) < 0) exit(128); @@ -2566,7 +2573,8 @@ int get_superproject_working_tree(struct strbuf *buf) * Put the gitdir for a submodule (given relative to the main * repository worktree) into `buf`, or return -1 on error. */ -int submodule_to_gitdir(struct strbuf *buf, const char *submodule) +int submodule_to_gitdir(struct repository *repo, + struct strbuf *buf, const char *submodule) { const struct submodule *sub; const char *git_dir; @@ -2586,14 +2594,13 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule) strbuf_addstr(buf, git_dir); } if (!is_git_directory(buf->buf)) { - sub = submodule_from_path(the_repository, null_oid(), - submodule); + sub = submodule_from_path(repo, null_oid(), submodule); if (!sub) { ret = -1; goto cleanup; } strbuf_reset(buf); - submodule_name_to_gitdir(buf, the_repository, sub->name); + submodule_name_to_gitdir(buf, repo, sub->name); } cleanup: @@ -2623,6 +2630,6 @@ void submodule_name_to_gitdir(struct strbuf *buf, struct repository *r, * administrators can explicitly set. Nothing has been decided, * so for now, just append the name at the end of the path. */ - strbuf_repo_git_path(buf, r, "modules/"); + repo_git_path_append(r, buf, "modules/"); strbuf_addstr(buf, submodule_name); } diff --git a/submodule.h b/submodule.h index b50d29eba4f13a..db980c1d083bc0 100644 --- a/submodule.h +++ b/submodule.h @@ -41,6 +41,10 @@ struct submodule_update_strategy { .type = SM_UPDATE_UNSPECIFIED, \ } +int parse_submodule_update_strategy(const char *value, + struct submodule_update_strategy *dst); +void submodule_update_strategy_release(struct submodule_update_strategy *strategy); + int is_gitmodules_unmerged(struct index_state *istate); int is_writing_gitmodules_ok(void); int is_staging_gitmodules_ok(struct index_state *istate); @@ -70,8 +74,6 @@ void die_in_unpopulated_submodule(struct index_state *istate, void die_path_inside_submodule(struct index_state *istate, const struct pathspec *ps); enum submodule_update_type parse_submodule_update_type(const char *value); -int parse_submodule_update_strategy(const char *value, - struct submodule_update_strategy *dst); const char *submodule_update_type_to_string(enum submodule_update_type type); void handle_ignore_submodules_arg(struct diff_options *, const char *); void show_submodule_diff_summary(struct diff_options *o, const char *path, @@ -134,7 +136,8 @@ int push_unpushed_submodules(struct repository *r, * path of that submodule in 'buf'. Return -1 on error or when the * submodule is not initialized. */ -int submodule_to_gitdir(struct strbuf *buf, const char *submodule); +int submodule_to_gitdir(struct repository *repo, + struct strbuf *buf, const char *submodule); /* * Given a submodule name, create a path to where the submodule's gitdir lives diff --git a/subprojects/.gitignore b/subprojects/.gitignore new file mode 100644 index 00000000000000..63ea916ef5f302 --- /dev/null +++ b/subprojects/.gitignore @@ -0,0 +1 @@ +/*/ diff --git a/subprojects/curl.wrap b/subprojects/curl.wrap new file mode 100644 index 00000000000000..f7e384b85cf5ee --- /dev/null +++ b/subprojects/curl.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = curl-8.10.1 +source_url = https://github.com/curl/curl/releases/download/curl-8_10_1/curl-8.10.1.tar.xz +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/curl_8.10.1-1/curl-8.10.1.tar.xz +source_filename = curl-8.10.1.tar.xz +source_hash = 73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee +patch_filename = curl_8.10.1-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/curl_8.10.1-1/get_patch +patch_hash = 707c28f35fc9b0e8d68c0c2800712007612f922a31da9637ce706a2159f3ddd8 +wrapdb_version = 8.10.1-1 + +[provide] +dependency_names = libcurl diff --git a/subprojects/expat.wrap b/subprojects/expat.wrap new file mode 100644 index 00000000000000..2e0427dcfd144c --- /dev/null +++ b/subprojects/expat.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = expat-2.6.3 +source_url = https://github.com/libexpat/libexpat/releases/download/R_2_6_3/expat-2.6.3.tar.xz +source_filename = expat-2.6.3.tar.bz2 +source_hash = 274db254a6979bde5aad404763a704956940e465843f2a9bd9ed7af22e2c0efc +patch_filename = expat_2.6.3-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/expat_2.6.3-1/get_patch +patch_hash = cf017fbe105e31428b2768360bd9be39094df4e948a1e8d1c54b6f7c76460cb1 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/expat_2.6.3-1/expat-2.6.3.tar.bz2 +wrapdb_version = 2.6.3-1 + +[provide] +expat = expat_dep diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap new file mode 100644 index 00000000000000..873d55106e9b83 --- /dev/null +++ b/subprojects/openssl.wrap @@ -0,0 +1,15 @@ +[wrap-file] +directory = openssl-3.0.8 +source_url = https://www.openssl.org/source/openssl-3.0.8.tar.gz +source_filename = openssl-3.0.8.tar.gz +source_hash = 6c13d2bf38fdf31eac3ce2a347073673f5d63263398f1f69d0df4a41253e4b3e +patch_filename = openssl_3.0.8-3_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/openssl_3.0.8-3/get_patch +patch_hash = 300da189e106942347d61a4a4295aa2edbcf06184f8d13b4cee0bed9fb936963 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/openssl_3.0.8-3/openssl-3.0.8.tar.gz +wrapdb_version = 3.0.8-3 + +[provide] +libcrypto = libcrypto_dep +libssl = libssl_dep +openssl = openssl_dep diff --git a/subprojects/pcre2.wrap b/subprojects/pcre2.wrap new file mode 100644 index 00000000000000..7e184472543bde --- /dev/null +++ b/subprojects/pcre2.wrap @@ -0,0 +1,16 @@ +[wrap-file] +directory = pcre2-10.44 +source_url = https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.44/pcre2-10.44.tar.bz2 +source_filename = pcre2-10.44.tar.bz2 +source_hash = d34f02e113cf7193a1ebf2770d3ac527088d485d4e047ed10e5d217c6ef5de96 +patch_filename = pcre2_10.44-2_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/pcre2_10.44-2/get_patch +patch_hash = 4336d422ee9043847e5e10dbbbd01940d4c9e5027f31ccdc33a7898a1ca94009 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/pcre2_10.44-2/pcre2-10.44.tar.bz2 +wrapdb_version = 10.44-2 + +[provide] +libpcre2-8 = libpcre2_8 +libpcre2-16 = libpcre2_16 +libpcre2-32 = libpcre2_32 +libpcre2-posix = libpcre2_posix diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap new file mode 100644 index 00000000000000..aa14de17740728 --- /dev/null +++ b/subprojects/zlib.wrap @@ -0,0 +1,13 @@ +[wrap-file] +directory = zlib-1.3.1 +source_url = http://zlib.net/fossils/zlib-1.3.1.tar.gz +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/zlib_1.3.1-1/zlib-1.3.1.tar.gz +source_filename = zlib-1.3.1.tar.gz +source_hash = 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23 +patch_filename = zlib_1.3.1-1_patch.zip +patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.3.1-1/get_patch +patch_hash = e79b98eb24a75392009cec6f99ca5cdca9881ff20bfa174e8b8926d5c7a47095 +wrapdb_version = 1.3.1-1 + +[provide] +zlib = zlib_dep diff --git a/symlinks.c b/symlinks.c index b29e340c2da43e..9cc090d42c089f 100644 --- a/symlinks.c +++ b/symlinks.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "gettext.h" #include "setup.h" diff --git a/t/.gitignore b/t/.gitignore index 91cf5772fe5643..3e6b0f2cc57ffe 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -2,4 +2,5 @@ /test-results /.prove /chainlinttmp +/mesontmp /out/ diff --git a/t/Makefile b/t/Makefile index 131ffd778fe008..2994eb5fa9a146 100644 --- a/t/Makefile +++ b/t/Makefile @@ -59,7 +59,7 @@ CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT all:: $(DEFAULT_TEST_TARGET) -test: pre-clean check-chainlint $(TEST_LINT) +test: pre-clean check-chainlint check-meson $(TEST_LINT) $(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup failed: @@ -103,6 +103,7 @@ clean-except-prove-cache: clean-chainlint clean: clean-except-prove-cache $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' + $(RM) -r mesontmp $(RM) .prove clean-chainlint: @@ -114,6 +115,23 @@ check-chainlint: { $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \ diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual +check-meson: + @# awk acts up when trying to match single quotes, so we use \047 instead. + @mkdir -p mesontmp && \ + printf "%s\n" \ + "integration_tests t[0-9][0-9][0-9][0-9]-*.sh" \ + "unit_test_programs unit-tests/t-*.c" \ + "clar_test_suites unit-tests/u-*.c" | \ + while read -r variable pattern; do \ + awk "/^$$variable = \[\$$/ {flag=1 ; next } /^]$$/ { flag=0 } flag { gsub(/^ \047/, \"\"); gsub(/\047,\$$/, \"\"); print }" meson.build >mesontmp/meson.txt && \ + ls $$pattern >mesontmp/actual.txt && \ + if ! cmp mesontmp/meson.txt mesontmp/actual.txt; then \ + echo "Meson tests differ from actual tests:"; \ + diff -u mesontmp/meson.txt mesontmp/actual.txt; \ + exit 1; \ + fi; \ + done + test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \ test-lint-filenames ifneq ($(GIT_TEST_CHAIN_LINT),0) @@ -159,3 +177,18 @@ perf: .PHONY: pre-clean $(T) aggregate-results clean valgrind perf \ check-chainlint clean-chainlint test-chainlint $(UNIT_TESTS) + +.PHONY: libgit-sys-test libgit-rs-test +libgit-sys-test: + $(QUIET)(\ + cd ../contrib/libgit-sys && \ + cargo test \ + ) +libgit-rs-test: + $(QUIET)(\ + cd ../contrib/libgit-rs && \ + cargo test \ + ) +ifdef INCLUDE_LIBGIT_RS +all:: libgit-sys-test libgit-rs-test +endif diff --git a/t/README b/t/README index 8dcb778e2604b9..53e5b4a7107416 100644 --- a/t/README +++ b/t/README @@ -368,27 +368,6 @@ excluded as so much relies on it, but this might change in the future. GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole test suite. Accept any boolean values that are accepted by git-config. -GIT_TEST_PASSING_SANITIZE_LEAK=true skips those tests that haven't -declared themselves as leak-free by setting -"TEST_PASSES_SANITIZE_LEAK=true" before sourcing "test-lib.sh". This -test mode is used by the "linux-leaks" CI target. - -GIT_TEST_PASSING_SANITIZE_LEAK=check checks that our -"TEST_PASSES_SANITIZE_LEAK=true" markings are current. Rather than -skipping those tests that haven't set "TEST_PASSES_SANITIZE_LEAK=true" -before sourcing "test-lib.sh" this mode runs them with -"--invert-exit-code". This is used to check that there's a one-to-one -mapping between "TEST_PASSES_SANITIZE_LEAK=true" and those tests that -pass under "SANITIZE=leak". This is especially useful when testing a -series that fixes various memory leaks with "git rebase -x". - -GIT_TEST_PASSING_SANITIZE_LEAK=check when combined with "--immediate" -will run to completion faster, and result in the same failing -tests. - -GIT_TEST_PASSING_SANITIZE_LEAK=check-failing behaves the same as "check", -but skips all tests which are already marked as leak-free. - GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version' default to n. @@ -465,8 +444,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_DEFAULT_REF_FORMAT=<format> specifies which ref storage format to use +in the test scripts. Recognized values for <format> are "files" and +"reftable". GIT_TEST_NO_WRITE_REV_INDEX=<boolean>, when true disables the 'pack.writeReverseIndex' setting. @@ -491,6 +471,10 @@ a test and then fails then the whole test run will abort. This can help to make sure the expected tests are executed and not silently skipped when their dependency breaks or is simply not present in a new environment. +GIT_TEST_NAME_HASH_VERSION=<int>, when set, causes 'git pack-objects' to +assume '--name-hash-version=<n>'. + + Naming Tests ------------ diff --git a/t/aggregate-results.sh b/t/aggregate-results.sh index 6e3bcc4aec7cb9..6cb0ff11deba76 100755 --- a/t/aggregate-results.sh +++ b/t/aggregate-results.sh @@ -44,7 +44,7 @@ then tr -s "," "\n" | grep -v '^$' | sort -u | - paste -s -d ' ') + paste -s -d ' ' -) if test -n "$unique_missing_prereq" then printf "\nmissing prereq: $unique_missing_prereq\n\n" diff --git a/t/helper/meson.build b/t/helper/meson.build new file mode 100644 index 00000000000000..d2cabaa2bcfcc9 --- /dev/null +++ b/t/helper/meson.build @@ -0,0 +1,93 @@ +test_tool_sources = [ + '../unit-tests/test-lib.c', + 'test-advise.c', + 'test-bitmap.c', + 'test-bloom.c', + 'test-bundle-uri.c', + 'test-cache-tree.c', + 'test-chmtime.c', + 'test-config.c', + 'test-crontab.c', + 'test-csprng.c', + 'test-date.c', + 'test-delete-gpgsig.c', + 'test-delta.c', + 'test-dir-iterator.c', + 'test-drop-caches.c', + 'test-dump-cache-tree.c', + 'test-dump-fsmonitor.c', + 'test-dump-split-index.c', + 'test-dump-untracked-cache.c', + 'test-env-helper.c', + 'test-example-tap.c', + 'test-find-pack.c', + 'test-fsmonitor-client.c', + 'test-genrandom.c', + 'test-genzeros.c', + 'test-getcwd.c', + 'test-hash-speed.c', + 'test-hash.c', + 'test-hashmap.c', + 'test-hexdump.c', + 'test-json-writer.c', + 'test-lazy-init-name-hash.c', + 'test-match-trees.c', + 'test-mergesort.c', + 'test-mktemp.c', + 'test-name-hash.c', + 'test-online-cpus.c', + 'test-pack-mtimes.c', + 'test-parse-options.c', + 'test-parse-pathspec-file.c', + 'test-partial-clone.c', + 'test-path-utils.c', + 'test-path-walk.c', + 'test-pcre2-config.c', + 'test-pkt-line.c', + 'test-proc-receive.c', + 'test-progress.c', + 'test-reach.c', + 'test-read-cache.c', + 'test-read-graph.c', + 'test-read-midx.c', + 'test-ref-store.c', + 'test-reftable.c', + 'test-regex.c', + 'test-repository.c', + 'test-revision-walking.c', + 'test-rot13-filter.c', + 'test-run-command.c', + 'test-scrap-cache-tree.c', + 'test-serve-v2.c', + 'test-sha1.c', + 'test-sha256.c', + 'test-sigchain.c', + 'test-simple-ipc.c', + 'test-string-list.c', + 'test-submodule-config.c', + 'test-submodule-nested-repo-config.c', + 'test-submodule.c', + 'test-subprocess.c', + 'test-tool.c', + 'test-trace2.c', + 'test-truncate.c', + 'test-userdiff.c', + 'test-wildmatch.c', + 'test-windows-named-pipe.c', + 'test-write-cache.c', + 'test-xml-encode.c', +] + +test_tool = executable('test-tool', + sources: test_tool_sources, + dependencies: [libgit_commonmain], +) +bin_wrappers += test_tool +test_dependencies += test_tool + +test_fake_ssh = executable('test-fake-ssh', + sources: 'test-fake-ssh.c', + dependencies: [libgit_commonmain], +) +bin_wrappers += test_fake_ssh +test_dependencies += test_fake_ssh diff --git a/t/helper/test-bloom.c b/t/helper/test-bloom.c index 97541daf7157b1..14e075c1a11a4e 100644 --- a/t/helper/test-bloom.c +++ b/t/helper/test-bloom.c @@ -11,30 +11,25 @@ static struct bloom_filter_settings settings = DEFAULT_BLOOM_FILTER_SETTINGS; static void add_string_to_filter(const char *data, struct bloom_filter *filter) { struct bloom_key key; - int i; fill_bloom_key(data, strlen(data), &key, &settings); printf("Hashes:"); - for (i = 0; i < settings.num_hashes; i++){ + for (size_t i = 0; i < settings.num_hashes; i++) printf("0x%08x|", key.hashes[i]); - } printf("\n"); add_key_to_filter(&key, filter, &settings); clear_bloom_key(&key); } static void print_bloom_filter(struct bloom_filter *filter) { - int i; - if (!filter) { printf("No filter.\n"); return; } printf("Filter_Length:%d\n", (int)filter->len); printf("Filter_Data:"); - for (i = 0; i < filter->len; i++) { + for (size_t i = 0; i < filter->len; i++) printf("%02x|", filter->data[i]); - } printf("\n"); } diff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c index 5cdef3ebefc628..3ae45cec3be639 100644 --- a/t/helper/test-cache-tree.c +++ b/t/helper/test-cache-tree.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "test-tool.h" #include "gettext.h" diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 33247f0e92e01d..75e028ab2a0449 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "test-tool.h" #include "config.h" diff --git a/t/helper/test-csprng.c b/t/helper/test-csprng.c index 65d14973c520ea..c86dcc4870fed8 100644 --- a/t/helper/test-csprng.c +++ b/t/helper/test-csprng.c @@ -1,7 +1,6 @@ #include "test-tool.h" #include "git-compat-util.h" - int cmd__csprng(int argc, const char **argv) { unsigned long count; @@ -12,11 +11,11 @@ int cmd__csprng(int argc, const char **argv) return 2; } - count = (argc == 2) ? strtoul(argv[1], NULL, 0) : -1L; + count = (argc == 2) ? strtoul(argv[1], NULL, 0) : ULONG_MAX; while (count) { unsigned long chunk = count < sizeof(buf) ? count : sizeof(buf); - if (csprng_bytes(buf, chunk) < 0) { + if (csprng_bytes(buf, chunk, 0) < 0) { perror("failed to read"); return 5; } diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c index 73e551cfc22269..7055d94354fbfa 100644 --- a/t/helper/test-drop-caches.c +++ b/t/helper/test-drop-caches.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-tool.h" #include "git-compat-util.h" diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c index 1b7f37a84fb2ac..efd017ca357e0b 100644 --- a/t/helper/test-dump-fsmonitor.c +++ b/t/helper/test-dump-fsmonitor.c @@ -8,7 +8,6 @@ int cmd__dump_fsmonitor(int ac UNUSED, const char **av UNUSED) { struct index_state *istate = the_repository->index; - int i; setup_git_directory(); if (do_read_index(istate, the_repository->index_file, 0) < 0) @@ -19,7 +18,7 @@ int cmd__dump_fsmonitor(int ac UNUSED, const char **av UNUSED) } printf("fsmonitor last update %s\n", istate->fsmonitor_last_update); - for (i = 0; i < istate->cache_nr; i++) + for (size_t i = 0; i < istate->cache_nr; i++) printf((istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) ? "+" : "-"); return 0; diff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c index a6720faf9ca99d..f855a3862c97bb 100644 --- a/t/helper/test-dump-split-index.c +++ b/t/helper/test-dump-split-index.c @@ -16,7 +16,6 @@ static void show_bit(size_t pos, void *data UNUSED) int cmd__dump_split_index(int ac UNUSED, const char **av) { struct split_index *si; - int i; setup_git_directory(); @@ -28,7 +27,7 @@ int cmd__dump_split_index(int ac UNUSED, const char **av) return 0; } printf("base %s\n", oid_to_hex(&si->base_oid)); - for (i = 0; i < the_repository->index->cache_nr; i++) { + for (size_t i = 0; i < the_repository->index->cache_nr; i++) { struct cache_entry *ce = the_repository->index->cache[i]; printf("%06o %s %d\t%s\n", ce->ce_mode, oid_to_hex(&ce->oid), ce_stage(ce), ce->name); diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c index 4f010d53249520..01a109496bee78 100644 --- a/t/helper/test-dump-untracked-cache.c +++ b/t/helper/test-dump-untracked-cache.c @@ -23,7 +23,7 @@ static int compare_dir(const void *a_, const void *b_) static void dump(struct untracked_cache_dir *ucd, struct strbuf *base) { - int i, len; + int len; QSORT(ucd->untracked, ucd->untracked_nr, compare_untracked); QSORT(ucd->dirs, ucd->dirs_nr, compare_dir); len = base->len; @@ -37,9 +37,9 @@ static void dump(struct untracked_cache_dir *ucd, struct strbuf *base) if (ucd->valid) fputs(" valid", stdout); printf("\n"); - for (i = 0; i < ucd->untracked_nr; i++) + for (size_t i = 0; i < ucd->untracked_nr; i++) printf("%s\n", ucd->untracked[i]); - for (i = 0; i < ucd->dirs_nr; i++) + for (size_t i = 0; i < ucd->dirs_nr; i++) dump(ucd->dirs[i], base); strbuf_setlen(base, len); } @@ -68,5 +68,7 @@ int cmd__dump_untracked_cache(int ac UNUSED, const char **av UNUSED) printf("flags %08x\n", uc->dir_flags); if (uc->root) dump(uc->root, &base); + + strbuf_release(&base); return 0; } diff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c index 14b2b0c12c0da3..85a69a4e557694 100644 --- a/t/helper/test-find-pack.c +++ b/t/helper/test-find-pack.c @@ -40,7 +40,7 @@ int cmd__find_pack(int argc, const char **argv) die("cannot parse %s as an object name", argv[0]); for (p = get_all_packs(the_repository); p; p = p->next) - if (find_pack_entry_one(oid.hash, p)) { + if (find_pack_entry_one(&oid, p)) { printf("%s\n", p->pack_name); actual_count++; } diff --git a/t/helper/test-genrandom.c b/t/helper/test-genrandom.c index 99b8dc1e2d9cdc..51b67f2f874694 100644 --- a/t/helper/test-genrandom.c +++ b/t/helper/test-genrandom.c @@ -22,7 +22,7 @@ int cmd__genrandom(int argc, const char **argv) next = next * 11 + *c; } while (*c++); - count = (argc == 3) ? strtoul(argv[2], NULL, 0) : -1L; + count = (argc == 3) ? strtoul(argv[2], NULL, 0) : ULONG_MAX; while (count--) { next = next * 1103515245 + 12345; diff --git a/t/helper/test-genzeros.c b/t/helper/test-genzeros.c index 47af843b681600..b895436a32de60 100644 --- a/t/helper/test-genzeros.c +++ b/t/helper/test-genzeros.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-tool.h" #include "git-compat-util.h" diff --git a/t/helper/test-hash-speed.c b/t/helper/test-hash-speed.c index 7de822af5168d1..fbf67fe6bd548f 100644 --- a/t/helper/test-hash-speed.c +++ b/t/helper/test-hash-speed.c @@ -3,25 +3,24 @@ #define NUM_SECONDS 3 -static inline void compute_hash(const struct git_hash_algo *algo, git_hash_ctx *ctx, uint8_t *final, const void *p, size_t len) +static inline void compute_hash(const struct git_hash_algo *algo, struct git_hash_ctx *ctx, uint8_t *final, const void *p, size_t len) { algo->init_fn(ctx); - algo->update_fn(ctx, p, len); - algo->final_fn(final, ctx); + git_hash_update(ctx, p, len); + git_hash_final(final, ctx); } int cmd__hash_speed(int ac, const char **av) { - git_hash_ctx ctx; + struct git_hash_ctx ctx; unsigned char hash[GIT_MAX_RAWSZ]; clock_t initial, start, end; unsigned bufsizes[] = { 64, 256, 1024, 8192, 16384 }; - int i; void *p; const struct git_hash_algo *algo = NULL; if (ac == 2) { - for (i = 1; i < GIT_HASH_NALGOS; i++) { + for (size_t i = 1; i < GIT_HASH_NALGOS; i++) { if (!strcmp(av[1], hash_algos[i].name)) { algo = &hash_algos[i]; break; @@ -36,7 +35,7 @@ int cmd__hash_speed(int ac, const char **av) printf("algo: %s\n", algo->name); - for (i = 0; i < ARRAY_SIZE(bufsizes); i++) { + for (size_t i = 0; i < ARRAY_SIZE(bufsizes); i++) { unsigned long j, kb; double kb_per_sec; p = xcalloc(1, bufsizes[i]); diff --git a/t/helper/test-hash.c b/t/helper/test-hash.c index 45d829c908fec9..f0ee61c8b47a65 100644 --- a/t/helper/test-hash.c +++ b/t/helper/test-hash.c @@ -1,14 +1,16 @@ #include "test-tool.h" #include "hex.h" -int cmd_hash_impl(int ac, const char **av, int algo) +int cmd_hash_impl(int ac, const char **av, int algo, int unsafe) { - git_hash_ctx ctx; + struct git_hash_ctx ctx; unsigned char hash[GIT_MAX_HEXSZ]; unsigned bufsz = 8192; int binary = 0; char *buffer; const struct git_hash_algo *algop = &hash_algos[algo]; + if (unsafe) + algop = unsafe_hash_algo(algop); if (ac == 2) { if (!strcmp(av[1], "-b")) @@ -46,9 +48,9 @@ int cmd_hash_impl(int ac, const char **av, int algo) } if (this_sz == 0) break; - algop->update_fn(&ctx, buffer, this_sz); + git_hash_update(&ctx, buffer, this_sz); } - algop->final_fn(hash, &ctx); + git_hash_final(hash, &ctx); if (binary) fwrite(hash, 1, algop->rawsz, stdout); diff --git a/t/helper/test-mergesort.c b/t/helper/test-mergesort.c index 328bfe29778c46..791e12879388de 100644 --- a/t/helper/test-mergesort.c +++ b/t/helper/test-mergesort.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-tool.h" #include "mem-pool.h" #include "mergesort.h" diff --git a/t/helper/test-name-hash.c b/t/helper/test-name-hash.c new file mode 100644 index 00000000000000..af1d52de101438 --- /dev/null +++ b/t/helper/test-name-hash.c @@ -0,0 +1,23 @@ +/* + * test-name-hash.c: Read a list of paths over stdin and report on their + * name-hash and full name-hash. + */ + +#include "test-tool.h" +#include "git-compat-util.h" +#include "pack-objects.h" +#include "strbuf.h" + +int cmd__name_hash(int argc UNUSED, const char **argv UNUSED) +{ + struct strbuf line = STRBUF_INIT; + + while (!strbuf_getline(&line, stdin)) { + printf("%10u ", pack_name_hash(line.buf)); + printf("%10u ", pack_name_hash_v2((unsigned const char *)line.buf)); + printf("%s\n", line.buf); + } + + strbuf_release(&line); + return 0; +} diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index 5250913d99eba1..bfe45ec68b01f1 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -174,7 +174,6 @@ int cmd__parse_options(int argc, const char **argv) OPT_ALIAS('Z', "alias-target", "alias-source"), OPT_END(), }; - int i; int ret = 0; trace2_cmd_name("_parse_"); @@ -198,10 +197,10 @@ int cmd__parse_options(int argc, const char **argv) show(&expect, &ret, "dry run: %s", dry_run ? "yes" : "no"); show(&expect, &ret, "file: %s", file ? file : "(not set)"); - for (i = 0; i < list.nr; i++) + for (size_t i = 0; i < list.nr; i++) show(&expect, &ret, "list: %s", list.items[i].string); - for (i = 0; i < argc; i++) + for (int i = 0; i < argc; i++) show(&expect, &ret, "arg %02d: %s", i, argv[i]); expect.strdup_strings = 1; @@ -282,14 +281,16 @@ int cmd__parse_options_flags(int argc, const char **argv) return parse_options_flags__cmd(argc, argv, test_flags); } -static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED) +static int subcmd_one(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { printf("fn: subcmd_one\n"); print_args(argc, argv); return 0; } -static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED) +static int subcmd_two(int argc, const char **argv, const char *prefix UNUSED, + struct repository *repo UNUSED) { printf("fn: subcmd_two\n"); print_args(argc, argv); @@ -319,7 +320,7 @@ static int parse_subcommand__cmd(int argc, const char **argv, printf("opt: %d\n", opt); - return fn(argc, argv, NULL); + return fn(argc, argv, NULL, NULL); } int cmd__parse_subcommand(int argc, const char **argv) diff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c index 0ead529167a1eb..a1af9710c31002 100644 --- a/t/helper/test-partial-clone.c +++ b/t/helper/test-partial-clone.c @@ -26,6 +26,8 @@ static void object_info(const char *gitdir, const char *oid_hex) if (oid_object_info_extended(&r, &oid, &oi, 0)) die("could not obtain object info"); printf("%d\n", (int) size); + + repo_clear(&r); } int cmd__partial_clone(int argc, const char **argv) diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index 3129aa28fd2859..72ac8d1b1b011d 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "test-tool.h" #include "abspath.h" diff --git a/t/helper/test-path-walk.c b/t/helper/test-path-walk.c new file mode 100644 index 00000000000000..61e845e5ec2560 --- /dev/null +++ b/t/helper/test-path-walk.c @@ -0,0 +1,132 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "test-tool.h" +#include "dir.h" +#include "environment.h" +#include "hex.h" +#include "object-name.h" +#include "object.h" +#include "pretty.h" +#include "revision.h" +#include "setup.h" +#include "parse-options.h" +#include "strbuf.h" +#include "path-walk.h" +#include "oid-array.h" + +static const char * const path_walk_usage[] = { + N_("test-tool path-walk <options> -- <revision-options>"), + NULL +}; + +struct path_walk_test_data { + uintmax_t batch_nr; + + uintmax_t commit_nr; + uintmax_t tree_nr; + uintmax_t blob_nr; + uintmax_t tag_nr; +}; + +static int emit_block(const char *path, struct oid_array *oids, + enum object_type type, void *data) +{ + struct path_walk_test_data *tdata = data; + const char *typestr; + + if (type == OBJ_TREE) + tdata->tree_nr += oids->nr; + else if (type == OBJ_BLOB) + tdata->blob_nr += oids->nr; + else if (type == OBJ_COMMIT) + tdata->commit_nr += oids->nr; + else if (type == OBJ_TAG) + tdata->tag_nr += oids->nr; + else + BUG("we do not understand this type"); + + typestr = type_name(type); + + /* This should never be output during tests. */ + if (!oids->nr) + printf("%"PRIuMAX":%s:%s:EMPTY\n", + tdata->batch_nr, typestr, path); + + for (size_t i = 0; i < oids->nr; i++) { + struct object *o = lookup_unknown_object(the_repository, + &oids->oid[i]); + printf("%"PRIuMAX":%s:%s:%s%s\n", + tdata->batch_nr, typestr, path, + oid_to_hex(&oids->oid[i]), + o->flags & UNINTERESTING ? ":UNINTERESTING" : ""); + } + + tdata->batch_nr++; + return 0; +} + +int cmd__path_walk(int argc, const char **argv) +{ + int res, stdin_pl = 0; + struct rev_info revs = REV_INFO_INIT; + struct path_walk_info info = PATH_WALK_INFO_INIT; + struct path_walk_test_data data = { 0 }; + struct option options[] = { + OPT_BOOL(0, "blobs", &info.blobs, + N_("toggle inclusion of blob objects")), + OPT_BOOL(0, "commits", &info.commits, + N_("toggle inclusion of commit objects")), + OPT_BOOL(0, "tags", &info.tags, + N_("toggle inclusion of tag objects")), + OPT_BOOL(0, "trees", &info.trees, + N_("toggle inclusion of tree objects")), + OPT_BOOL(0, "prune", &info.prune_all_uninteresting, + N_("toggle pruning of uninteresting paths")), + OPT_BOOL(0, "stdin-pl", &stdin_pl, + N_("read a pattern list over stdin")), + OPT_END(), + }; + + setup_git_directory(); + revs.repo = the_repository; + + argc = parse_options(argc, argv, NULL, + options, path_walk_usage, + PARSE_OPT_KEEP_UNKNOWN_OPT | PARSE_OPT_KEEP_ARGV0); + + if (argc > 1) + setup_revisions(argc, argv, &revs, NULL); + else + usage(path_walk_usage[0]); + + info.revs = &revs; + info.path_fn = emit_block; + info.path_fn_data = &data; + + if (stdin_pl) { + struct strbuf in = STRBUF_INIT; + CALLOC_ARRAY(info.pl, 1); + + info.pl->use_cone_patterns = 1; + + strbuf_fread(&in, 2048, stdin); + add_patterns_from_buffer(in.buf, in.len, "", 0, info.pl); + strbuf_release(&in); + } + + res = walk_objects_by_path(&info); + + printf("commits:%" PRIuMAX "\n" + "trees:%" PRIuMAX "\n" + "blobs:%" PRIuMAX "\n" + "tags:%" PRIuMAX "\n", + data.commit_nr, data.tree_nr, data.blob_nr, data.tag_nr); + + if (info.pl) { + clear_pattern_list(info.pl); + free(info.pl); + } + + release_revisions(&revs); + return res; +} diff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c index 29361c7aab7276..3703f734f3b125 100644 --- a/t/helper/test-proc-receive.c +++ b/t/helper/test-proc-receive.c @@ -196,5 +196,12 @@ int cmd__proc_receive(int argc, const char **argv) packet_flush(1); sigchain_pop(SIGPIPE); + while (commands) { + struct command *next = commands->next; + free(commands); + commands = next; + } + string_list_clear(&push_options, 0); + return 0; } diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c index 44be2645e9c7cb..1f75b7bd199aff 100644 --- a/t/helper/test-progress.c +++ b/t/helper/test-progress.c @@ -17,10 +17,14 @@ * * See 't0500-progress-display.sh' for examples. */ + +#define USE_THE_REPOSITORY_VARIABLE #define GIT_TEST_PROGRESS_ONLY + #include "test-tool.h" #include "parse-options.h" #include "progress.h" +#include "repository.h" #include "strbuf.h" #include "string-list.h" @@ -64,7 +68,7 @@ int cmd__progress(int argc, const char **argv) else die("invalid input: '%s'", line.buf); - progress = start_progress(title, total); + progress = start_progress(the_repository, title, total); } else if (skip_prefix(line.buf, "progress ", (const char **) &end)) { uint64_t item_count = strtoull(end, &end, 10); if (*end != '\0') diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c index 995e382863ac96..028ec003067828 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -13,7 +13,6 @@ static void print_sorted_commit_ids(struct commit_list *list) { - int i; struct string_list s = STRING_LIST_INIT_DUP; while (list) { @@ -23,7 +22,7 @@ static void print_sorted_commit_ids(struct commit_list *list) string_list_sort(&s); - for (i = 0; i < s.nr; i++) + for (size_t i = 0; i < s.nr; i++) printf("%s\n", s.items[i].string); string_list_clear(&s, 0); @@ -36,7 +35,7 @@ int cmd__reach(int ac, const char **av) struct commit_list *X, *Y; struct object_array X_obj = OBJECT_ARRAY_INIT; struct commit **X_array, **Y_array; - int X_nr, X_alloc, Y_nr, Y_alloc; + size_t X_nr, X_alloc, Y_nr, Y_alloc; struct strbuf buf = STRBUF_INIT; struct repository *r = the_repository; @@ -127,10 +126,12 @@ int cmd__reach(int ac, const char **av) exit(128); printf("%s(A,X):\n", av[1]); print_sorted_commit_ids(list); + free_commit_list(list); } else if (!strcmp(av[1], "reduce_heads")) { struct commit_list *list = reduce_heads(X); printf("%s(X):\n", av[1]); print_sorted_commit_ids(list); + free_commit_list(list); } else if (!strcmp(av[1], "can_all_from_reach")) { printf("%s(X,Y):%d\n", av[1], can_all_from_reach(X, Y, 1)); } else if (!strcmp(av[1], "can_all_from_reach_with_flag")) { @@ -153,9 +154,10 @@ int cmd__reach(int ac, const char **av) filter.with_commit_tag_algo = 0; printf("%s(_,A,X,_):%d\n", av[1], commit_contains(&filter, A, X, &cache)); + clear_contains_cache(&cache); } else if (!strcmp(av[1], "get_reachable_subset")) { const int reachable_flag = 1; - int i, count = 0; + int count = 0; struct commit_list *current; struct commit_list *list = get_reachable_subset(X_array, X_nr, Y_array, Y_nr, @@ -167,7 +169,7 @@ int cmd__reach(int ac, const char **av) oid_to_hex(&list->item->object.oid)); count++; } - for (i = 0; i < Y_nr; i++) { + for (size_t i = 0; i < Y_nr; i++) { if (Y_array[i]->object.flags & reachable_flag) count--; } @@ -176,7 +178,14 @@ int cmd__reach(int ac, const char **av) die(_("too many commits marked reachable")); print_sorted_commit_ids(list); + free_commit_list(list); } + object_array_clear(&X_obj); + strbuf_release(&buf); + free_commit_list(X); + free_commit_list(Y); + free(X_array); + free(Y_array); return 0; } diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c index d285c656bd3a32..e277dde8e7107a 100644 --- a/t/helper/test-read-cache.c +++ b/t/helper/test-read-cache.c @@ -11,8 +11,6 @@ int cmd__read_cache(int argc, const char **argv) int i, cnt = 1; const char *name = NULL; - initialize_repository(the_repository); - if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) { argc--; argv++; diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c index 9018c9f5412283..811dde1cb3c880 100644 --- a/t/helper/test-read-graph.c +++ b/t/helper/test-read-graph.c @@ -97,7 +97,6 @@ int cmd__read_graph(int argc, const char **argv) } done: - UNLEAK(graph); - + free_commit_graph(graph); return ret; } diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index 438fb9fc6197fc..fc632369618917 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -18,7 +18,7 @@ static int read_midx_file(const char *object_dir, const char *checksum, struct multi_pack_index *m; setup_git_directory(); - m = load_multi_pack_index(object_dir, 1); + m = load_multi_pack_index(the_repository, object_dir, 1); if (!m) return 1; @@ -82,7 +82,7 @@ static int read_midx_checksum(const char *object_dir) struct multi_pack_index *m; setup_git_directory(); - m = load_multi_pack_index(object_dir, 1); + m = load_multi_pack_index(the_repository, object_dir, 1); if (!m) return 1; printf("%s\n", hash_to_hex(get_midx_checksum(m))); @@ -98,7 +98,7 @@ static int read_midx_preferred_pack(const char *object_dir) setup_git_directory(); - midx = load_multi_pack_index(object_dir, 1); + midx = load_multi_pack_index(the_repository, object_dir, 1); if (!midx) return 1; @@ -121,7 +121,7 @@ static int read_midx_bitmapped_packs(const char *object_dir) setup_git_directory(); - midx = load_multi_pack_index(object_dir, 1); + midx = load_multi_pack_index(the_repository, object_dir, 1); if (!midx) return 1; diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 65346dee551ccd..e00fce592b10ed 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -24,14 +24,13 @@ struct flag_definition { static unsigned int parse_flags(const char *str, struct flag_definition *defs) { struct string_list masks = STRING_LIST_INIT_DUP; - int i = 0; unsigned int result = 0; if (!strcmp(str, "0")) return 0; string_list_split(&masks, str, ',', 64); - for (; i < masks.nr; i++) { + for (size_t i = 0; i < masks.nr; i++) { const char *name = masks.items[i].string; struct flag_definition *def = defs; int found = 0; @@ -76,11 +75,10 @@ static const char **get_store(const char **argv, struct ref_store **refs) *refs = get_main_ref_store(the_repository); } else if (skip_prefix(argv[0], "submodule:", &gitdir)) { struct strbuf sb = STRBUF_INIT; - int ret; - ret = strbuf_git_path_submodule(&sb, gitdir, "objects/"); - if (ret) - die("strbuf_git_path_submodule failed: %d", ret); + if (!repo_submodule_path_append(the_repository, + &sb, gitdir, "objects/")) + die("computing submodule path failed"); add_to_alternates_memory(sb.buf); strbuf_release(&sb); @@ -199,7 +197,7 @@ static int cmd_verify_ref(struct ref_store *refs, const char **argv) struct strbuf err = STRBUF_INIT; int ret; - ret = refs_verify_refname_available(refs, refname, NULL, NULL, &err); + ret = refs_verify_refname_available(refs, refname, NULL, NULL, 0, &err); if (err.len) puts(err.buf); return ret; diff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c index 29d4e9a755d6de..3c72ed985b3a44 100644 --- a/t/helper/test-reftable.c +++ b/t/helper/test-reftable.c @@ -28,7 +28,10 @@ static int dump_table(struct reftable_merged_table *mt) const struct git_hash_algo *algop; int err; - reftable_merged_table_init_ref_iterator(mt, &it); + err = reftable_merged_table_init_ref_iterator(mt, &it); + if (err < 0) + return err; + err = reftable_iterator_seek_ref(&it, ""); if (err < 0) return err; @@ -63,7 +66,10 @@ static int dump_table(struct reftable_merged_table *mt) reftable_iterator_destroy(&it); reftable_ref_record_release(&ref); - reftable_merged_table_init_log_iterator(mt, &it); + err = reftable_merged_table_init_log_iterator(mt, &it); + if (err < 0) + return err; + err = reftable_iterator_seek_log(&it, ""); if (err < 0) return err; @@ -150,7 +156,7 @@ int cmd__dump_reftable(int argc, const char **argv) int opt_dump_blocks = 0; int opt_dump_table = 0; int opt_dump_stack = 0; - uint32_t opt_hash_id = GIT_SHA1_FORMAT_ID; + uint32_t opt_hash_id = REFTABLE_HASH_SHA1; const char *arg = NULL, *argv0 = argv[0]; for (; argc > 1; argv++, argc--) @@ -161,7 +167,7 @@ int cmd__dump_reftable(int argc, const char **argv) else if (!strcmp("-t", argv[1])) opt_dump_table = 1; else if (!strcmp("-6", argv[1])) - opt_hash_id = GIT_SHA256_FORMAT_ID; + opt_hash_id = REFTABLE_HASH_SHA256; else if (!strcmp("-s", argv[1])) opt_dump_stack = 1; else if (!strcmp("-?", argv[1]) || !strcmp("-h", argv[1])) { diff --git a/t/helper/test-rot13-filter.c b/t/helper/test-rot13-filter.c index 7e1d9e0ee47303..722b1cbe7788bc 100644 --- a/t/helper/test-rot13-filter.c +++ b/t/helper/test-rot13-filter.c @@ -1,6 +1,6 @@ /* * Example implementation for the Git filter protocol version 2 - * See Documentation/gitattributes.txt, section "Filter Protocol" + * See Documentation/gitattributes.adoc, section "Filter Protocol" * * Usage: test-tool rot13-filter [--always-delay] --log=<path> <capabilities> * @@ -9,7 +9,7 @@ * ("clean", "smudge", etc). * * When --always-delay is given all pathnames with the "can-delay" flag - * that don't appear on the list bellow are delayed with a count of 1 + * that don't appear on the list below are delayed with a count of 1 * (see more below). * * This implementation supports special test cases: diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index 61eb1175fe53f4..3719f23cc2d02f 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -8,6 +8,8 @@ * published by the Free Software Foundation. */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-tool.h" #include "run-command.h" #include "strvec.h" diff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c index 054cbcf5d83946..63a200b8d46f68 100644 --- a/t/helper/test-serve-v2.c +++ b/t/helper/test-serve-v2.c @@ -1,6 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "test-tool.h" #include "gettext.h" #include "parse-options.h" +#include "repository.h" #include "serve.h" #include "setup.h" @@ -28,9 +31,9 @@ int cmd__serve_v2(int argc, const char **argv) PARSE_OPT_KEEP_UNKNOWN_OPT); if (advertise_capabilities) - protocol_v2_advertise_capabilities(); + protocol_v2_advertise_capabilities(the_repository); else - protocol_v2_serve_loop(stateless_rpc); + protocol_v2_serve_loop(the_repository, stateless_rpc); return 0; } diff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c index e60d000c0393cb..349540c4df8b6a 100644 --- a/t/helper/test-sha1.c +++ b/t/helper/test-sha1.c @@ -3,7 +3,7 @@ int cmd__sha1(int ac, const char **av) { - return cmd_hash_impl(ac, av, GIT_HASH_SHA1); + return cmd_hash_impl(ac, av, GIT_HASH_SHA1, 0); } int cmd__sha1_is_sha1dc(int argc UNUSED, const char **argv UNUSED) @@ -13,3 +13,8 @@ int cmd__sha1_is_sha1dc(int argc UNUSED, const char **argv UNUSED) #endif return 1; } + +int cmd__sha1_unsafe(int ac, const char **av) +{ + return cmd_hash_impl(ac, av, GIT_HASH_SHA1, 1); +} diff --git a/t/helper/test-sha1.sh b/t/helper/test-sha1.sh index 84594885c70388..bf387d3db14d8b 100755 --- a/t/helper/test-sha1.sh +++ b/t/helper/test-sha1.sh @@ -3,25 +3,31 @@ dd if=/dev/zero bs=1048576 count=100 2>/dev/null | /usr/bin/time t/helper/test-tool sha1 >/dev/null +dd if=/dev/zero bs=1048576 count=100 2>/dev/null | +/usr/bin/time t/helper/test-tool sha1-unsafe >/dev/null + while read expect cnt pfx do case "$expect" in '#'*) continue ;; esac - actual=$( - { - test -z "$pfx" || echo "$pfx" - dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null | - perl -pe 'y/\000/g/' - } | ./t/helper/test-tool sha1 $cnt - ) - if test "$expect" = "$actual" - then - echo "OK: $expect $cnt $pfx" - else - echo >&2 "OOPS: $cnt" - echo >&2 "expect: $expect" - echo >&2 "actual: $actual" - exit 1 - fi + for sha1 in sha1 sha1-unsafe + do + actual=$( + { + test -z "$pfx" || echo "$pfx" + dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null | + perl -pe 'y/\000/g/' + } | ./t/helper/test-tool $sha1 $cnt + ) + if test "$expect" = "$actual" + then + echo "OK ($sha1): $expect $cnt $pfx" + else + echo >&2 "OOPS ($sha1): $cnt" + echo >&2 "expect ($sha1): $expect" + echo >&2 "actual ($sha1): $actual" + exit 1 + fi + done done <<EOF da39a3ee5e6b4b0d3255bfef95601890afd80709 0 3f786850e387550fdab836ed7e6dc881de23001b 0 a diff --git a/t/helper/test-sha256.c b/t/helper/test-sha256.c index 2fb20438f3c382..7fd0aa1fcd3613 100644 --- a/t/helper/test-sha256.c +++ b/t/helper/test-sha256.c @@ -3,5 +3,5 @@ int cmd__sha256(int ac, const char **av) { - return cmd_hash_impl(ac, av, GIT_HASH_SHA256); + return cmd_hash_impl(ac, av, GIT_HASH_SHA256, 0); } diff --git a/t/helper/test-simple-ipc.c b/t/helper/test-simple-ipc.c index fb5927775daef8..03cc5eea2c2944 100644 --- a/t/helper/test-simple-ipc.c +++ b/t/helper/test-simple-ipc.c @@ -612,8 +612,8 @@ int cmd__simple_ipc(int argc, const char **argv) if (argc < 2) usage_with_options(simple_ipc_usage, options); - if (argc == 2 && !strcmp(argv[1], "-h")) - usage_with_options(simple_ipc_usage, options); + show_usage_with_options_if_asked(argc, argv, + simple_ipc_usage, options); if (argc == 2 && !strcmp(argv[1], "SUPPORTS_SIMPLE_IPC")) return 0; diff --git a/t/helper/test-string-list.c b/t/helper/test-string-list.c index e2aad611d1c8bb..6f10c5a43540b8 100644 --- a/t/helper/test-string-list.c +++ b/t/helper/test-string-list.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-tool.h" #include "strbuf.h" #include "string-list.h" diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c index 6ca069ce63370d..6dce957153112a 100644 --- a/t/helper/test-submodule-nested-repo-config.c +++ b/t/helper/test-submodule-nested-repo-config.c @@ -29,6 +29,6 @@ int cmd__submodule_nested_repo_config(int argc, const char **argv) print_config_from_gitmodules(&subrepo, argv[2]); submodule_free(the_repository); - + repo_clear(&subrepo); return 0; } diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 1ebb69a5dc4c17..50dc4dac4ed625 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -44,6 +44,7 @@ static struct test_cmd cmds[] = { { "match-trees", cmd__match_trees }, { "mergesort", cmd__mergesort }, { "mktemp", cmd__mktemp }, + { "name-hash", cmd__name_hash }, { "online-cpus", cmd__online_cpus }, { "pack-mtimes", cmd__pack_mtimes }, { "parse-options", cmd__parse_options }, @@ -52,6 +53,7 @@ static struct test_cmd cmds[] = { { "parse-subcommand", cmd__parse_subcommand }, { "partial-clone", cmd__partial_clone }, { "path-utils", cmd__path_utils }, + { "path-walk", cmd__path_walk }, { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, { "proc-receive", cmd__proc_receive }, @@ -70,6 +72,7 @@ static struct test_cmd cmds[] = { { "serve-v2", cmd__serve_v2 }, { "sha1", cmd__sha1 }, { "sha1-is-sha1dc", cmd__sha1_is_sha1dc }, + { "sha1-unsafe", cmd__sha1_unsafe }, { "sha256", cmd__sha256 }, { "sigchain", cmd__sigchain }, { "simple-ipc", cmd__simple_ipc }, @@ -101,7 +104,6 @@ static NORETURN void die_usage(void) int cmd_main(int argc, const char **argv) { - int i; const char *working_directory = NULL; struct option options[] = { OPT_STRING('C', NULL, &working_directory, "directory", @@ -120,7 +122,7 @@ int cmd_main(int argc, const char **argv) if (working_directory && chdir(working_directory) < 0) die("Could not cd to '%s'", working_directory); - for (i = 0; i < ARRAY_SIZE(cmds); i++) { + for (size_t i = 0; i < ARRAY_SIZE(cmds); i++) { if (!strcmp(cmds[i].name, argv[1])) { argv++; argc--; diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 21802ac27da37f..6d62a5b53d9596 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -37,6 +37,7 @@ int cmd__lazy_init_name_hash(int argc, const char **argv); int cmd__match_trees(int argc, const char **argv); int cmd__mergesort(int argc, const char **argv); int cmd__mktemp(int argc, const char **argv); +int cmd__name_hash(int argc, const char **argv); int cmd__online_cpus(int argc, const char **argv); int cmd__pack_mtimes(int argc, const char **argv); int cmd__parse_options(int argc, const char **argv); @@ -45,6 +46,7 @@ int cmd__parse_pathspec_file(int argc, const char** argv); int cmd__parse_subcommand(int argc, const char **argv); int cmd__partial_clone(int argc, const char **argv); int cmd__path_utils(int argc, const char **argv); +int cmd__path_walk(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__proc_receive(int argc, const char **argv); @@ -63,6 +65,7 @@ int cmd__scrap_cache_tree(int argc, const char **argv); int cmd__serve_v2(int argc, const char **argv); int cmd__sha1(int argc, const char **argv); int cmd__sha1_is_sha1dc(int argc, const char **argv); +int cmd__sha1_unsafe(int argc, const char **argv); int cmd__sha256(int argc, const char **argv); int cmd__sigchain(int argc, const char **argv); int cmd__simple_ipc(int argc, const char **argv); @@ -81,6 +84,6 @@ int cmd__windows_named_pipe(int argc, const char **argv); #endif int cmd__write_cache(int argc, const char **argv); -int cmd_hash_impl(int ac, const char **av, int algo); +int cmd_hash_impl(int ac, const char **av, int algo, int unsafe); #endif diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index c588c273ce73f1..415df078c1638a 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "test-tool.h" #include "strvec.h" diff --git a/t/interop/Makefile b/t/interop/Makefile index 6911c2915a74b1..4ff4ed0616e689 100644 --- a/t/interop/Makefile +++ b/t/interop/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + # Import tree-wide shared Makefile behavior and libraries include ../../shared.mak @@ -8,7 +11,7 @@ SHELL_PATH ?= $(SHELL) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) T = $(sort $(wildcard i[0-9][0-9][0-9][0-9]-*.sh)) -all: $(T) +all:: $(T) $(T): @echo "*** $@ ***"; '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) diff --git a/t/lib-bundle.sh b/t/lib-bundle.sh index cf7ed818b246ac..62b7bb13c81d34 100644 --- a/t/lib-bundle.sh +++ b/t/lib-bundle.sh @@ -11,7 +11,7 @@ convert_bundle_to_pack () { } # Check count of objects in a bundle file. -# We can use "--thin" opiton to check thin pack, which must be fixed by +# We can use "--thin" option to check thin pack, which must be fixed by # command `git-index-pack --fix-thin --stdin`. test_bundle_object_count () { thin= diff --git a/t/lib-credential.sh b/t/lib-credential.sh index 58b9c740605890..cc6bf9aa5f3717 100644 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -566,6 +566,21 @@ helper_test_authtype() { EOF ' + test_expect_success "helper ($HELPER) gets authtype and credential only if request has authtype capability" ' + check fill $HELPER <<-\EOF + protocol=https + host=git.example.com + -- + protocol=https + host=git.example.com + username=askpass-username + password=askpass-password + -- + askpass: Username for '\''https://git.example.com'\'': + askpass: Password for '\''https://askpass-username@git.example.com'\'': + EOF + ' + test_expect_success "helper ($HELPER) stores authtype and credential with username" ' check approve $HELPER <<-\EOF capability[]=authtype diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh index cc6bb2cdeaae7b..b3dd68b0b95850 100644 --- a/t/lib-gettext.sh +++ b/t/lib-gettext.sh @@ -6,8 +6,8 @@ . ./test-lib.sh -GIT_TEXTDOMAINDIR="$GIT_BUILD_DIR/po/build/locale" -GIT_PO_PATH="$GIT_BUILD_DIR/po" +GIT_TEXTDOMAINDIR="$GIT_TEST_TEXTDOMAINDIR" +GIT_PO_PATH="$GIT_SOURCE_DIR/po" export GIT_TEXTDOMAINDIR GIT_PO_PATH if test -n "$GIT_TEST_INSTALLED" diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index ea28971e8ee6ab..2fde2353fd3835 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -1,7 +1,3 @@ -if test -z "$TEST_FAILS_SANITIZE_LEAK" -then - TEST_PASSES_SANITIZE_LEAK=true -fi . ./test-lib.sh if test -n "$NO_SVN_TESTS" diff --git a/t/lib-gitweb.sh b/t/lib-gitweb.sh index 1f32ca66ea5128..a6e3dd11b3552a 100644 --- a/t/lib-gitweb.sh +++ b/t/lib-gitweb.sh @@ -48,8 +48,8 @@ EOF test -f "$SCRIPT_NAME" || error "Cannot find gitweb at $GITWEB_TEST_INSTALLED." say "# Testing $SCRIPT_NAME" - else # normal case, use source version of gitweb - SCRIPT_NAME="$GIT_BUILD_DIR/gitweb/gitweb.perl" + else # normal case, use built version of gitweb + SCRIPT_NAME="$GIT_BUILD_DIR/gitweb/gitweb.cgi" fi export SCRIPT_NAME } @@ -105,6 +105,11 @@ if ! test_have_prereq PERL; then test_done fi +if ! test_have_prereq GITWEB; then + skip_all='skipping gitweb tests, gitweb not available' + test_done +fi + perl -MEncode -e '$e="";decode_utf8($e, Encode::FB_CROAK)' >/dev/null 2>&1 || { skip_all='skipping gitweb tests, perl version is too old' test_done diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh index add11e88fc00d7..3845b6ac449541 100644 --- a/t/lib-gpg.sh +++ b/t/lib-gpg.sh @@ -6,7 +6,7 @@ # executed in an eval'ed subshell that changes the working directory to a # temporary one. -GNUPGHOME="$PWD/gpghome" +GNUPGHOME="$(pwd)/gpghome" export GNUPGHOME test_lazy_prereq GPG ' diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 11d2dc9fe341b6..0dd764310dbed1 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -187,7 +187,7 @@ set_reword_editor () { exit 1 fi fi && - # There should be no uncommited changes + # There should be no uncommitted changes git diff --exit-code HEAD && # The todo-list should be re-read after a reword GIT_SEQUENCE_EDITOR="\"$PWD/reword-sequence-editor.sh\"" \ diff --git a/t/lib-sudo.sh b/t/lib-sudo.sh index b4d7788f4e5924..477e0fdc049f42 100644 --- a/t/lib-sudo.sh +++ b/t/lib-sudo.sh @@ -6,7 +6,7 @@ run_with_sudo () { local RUN="$TEST_DIRECTORY/$$.sh" write_script "$RUN" "$TEST_SHELL_PATH" # avoid calling "$RUN" directly so sudo doesn't get a chance to - # override the shell, add aditional restrictions or even reject + # override the shell, add additional restrictions or even reject # running the script because its security policy deem it unsafe sudo "$TEST_SHELL_PATH" -c "\"$RUN\"" ret=$? diff --git a/t/lib-unicode-nfc-nfd.sh b/t/lib-unicode-nfc-nfd.sh index 22232247efc34d..aed0a4dd44af1c 100755 --- a/t/lib-unicode-nfc-nfd.sh +++ b/t/lib-unicode-nfc-nfd.sh @@ -74,7 +74,7 @@ test_lazy_prereq UNICODE_NFD_PRESERVED ' # Yielding: \xcf \x89 + \xcc \x94 + \xcd \x82 # # Note that I've used the canonical ordering of the -# combinining characters. It is also possible to +# combining characters. It is also possible to # swap them. My testing shows that that non-standard # ordering also causes a collision in mkdir. However, # the resulting names don't draw correctly on the diff --git a/t/meson.build b/t/meson.build new file mode 100644 index 00000000000000..19597a5d4ce9a0 --- /dev/null +++ b/t/meson.build @@ -0,0 +1,1155 @@ +clar_test_suites = [ + 'unit-tests/u-ctype.c', + 'unit-tests/u-example-decorate.c', + 'unit-tests/u-hash.c', + 'unit-tests/u-hashmap.c', + 'unit-tests/u-mem-pool.c', + 'unit-tests/u-oid-array.c', + 'unit-tests/u-oidmap.c', + 'unit-tests/u-oidtree.c', + 'unit-tests/u-prio-queue.c', + 'unit-tests/u-reftable-tree.c', + 'unit-tests/u-strbuf.c', + 'unit-tests/u-strcmp-offset.c', + 'unit-tests/u-strvec.c', +] + +clar_sources = [ + 'unit-tests/clar/clar.c', + 'unit-tests/unit-test.c', + 'unit-tests/lib-oid.c' +] + +clar_decls_h = custom_target( + input: clar_test_suites, + output: 'clar-decls.h', + command : [ + shell, + meson.current_source_dir() + '/unit-tests/generate-clar-decls.sh', + '@OUTPUT@', + '@INPUT@', + ], + env: script_environment, +) +clar_sources += clar_decls_h + +clar_sources += custom_target( + input: clar_decls_h, + output: 'clar.suite', + command : [ + shell, + meson.current_source_dir() + '/unit-tests/generate-clar-suites.sh', + '@INPUT@', + '@OUTPUT@', + ], + env: script_environment, +) + +clar_unit_tests = executable('unit-tests', + sources: clar_sources + clar_test_suites, + dependencies: [libgit_commonmain], +) +test('unit-tests', clar_unit_tests) + +unit_test_programs = [ + 'unit-tests/t-reftable-basics.c', + 'unit-tests/t-reftable-block.c', + 'unit-tests/t-reftable-merged.c', + 'unit-tests/t-reftable-pq.c', + 'unit-tests/t-reftable-reader.c', + 'unit-tests/t-reftable-readwrite.c', + 'unit-tests/t-reftable-record.c', + 'unit-tests/t-reftable-stack.c', + 'unit-tests/t-trailer.c', + 'unit-tests/t-urlmatch-normalization.c', +] + +foreach unit_test_program : unit_test_programs + unit_test_name = fs.stem(unit_test_program) + unit_test = executable(unit_test_name, + sources: [ + 'unit-tests/test-lib.c', + 'unit-tests/lib-reftable.c', + unit_test_program, + ], + dependencies: [libgit_commonmain], + ) + test(unit_test_name, unit_test, + workdir: meson.current_source_dir(), + timeout: 0, + ) +endforeach + +subdir('helper') + +integration_tests = [ + 't0000-basic.sh', + 't0001-init.sh', + 't0002-gitfile.sh', + 't0003-attributes.sh', + 't0004-unwritable.sh', + 't0005-signals.sh', + 't0006-date.sh', + 't0007-git-var.sh', + 't0008-ignores.sh', + 't0010-racy-git.sh', + 't0012-help.sh', + 't0013-sha1dc.sh', + 't0014-alias.sh', + 't0017-env-helper.sh', + 't0018-advice.sh', + 't0019-json-writer.sh', + 't0020-crlf.sh', + 't0021-conversion.sh', + 't0022-crlf-rename.sh', + 't0023-crlf-am.sh', + 't0024-crlf-archive.sh', + 't0025-crlf-renormalize.sh', + 't0026-eol-config.sh', + 't0027-auto-crlf.sh', + 't0028-working-tree-encoding.sh', + 't0029-core-unsetenvvars.sh', + 't0030-stripspace.sh', + 't0033-safe-directory.sh', + 't0034-root-safe-directory.sh', + 't0035-safe-bare-repository.sh', + 't0040-parse-options.sh', + 't0041-usage.sh', + 't0050-filesystem.sh', + 't0051-windows-named-pipe.sh', + 't0052-simple-ipc.sh', + 't0055-beyond-symlinks.sh', + 't0056-git-C.sh', + 't0060-path-utils.sh', + 't0061-run-command.sh', + 't0062-revision-walking.sh', + 't0063-string-list.sh', + 't0066-dir-iterator.sh', + 't0067-parse_pathspec_file.sh', + 't0068-for-each-repo.sh', + 't0070-fundamental.sh', + 't0071-sort.sh', + 't0080-unit-test-output.sh', + 't0081-find-pack.sh', + 't0090-cache-tree.sh', + 't0091-bugreport.sh', + 't0092-diagnose.sh', + 't0095-bloom.sh', + 't0100-previous.sh', + 't0101-at-syntax.sh', + 't0200-gettext-basic.sh', + 't0201-gettext-fallbacks.sh', + 't0202-gettext-perl.sh', + 't0203-gettext-setlocale-sanity.sh', + 't0204-gettext-reencode-sanity.sh', + 't0210-trace2-normal.sh', + 't0211-trace2-perf.sh', + 't0212-trace2-event.sh', + 't0300-credentials.sh', + 't0301-credential-cache.sh', + 't0302-credential-store.sh', + 't0303-credential-external.sh', + 't0410-partial-clone.sh', + 't0411-clone-from-partial.sh', + 't0450-txt-doc-vs-help.sh', + 't0500-progress-display.sh', + 't0600-reffiles-backend.sh', + 't0601-reffiles-pack-refs.sh', + 't0602-reffiles-fsck.sh', + 't0610-reftable-basics.sh', + 't0611-reftable-httpd.sh', + 't0612-reftable-jgit-compatibility.sh', + 't0613-reftable-write-options.sh', + 't1000-read-tree-m-3way.sh', + 't1001-read-tree-m-2way.sh', + 't1002-read-tree-m-u-2way.sh', + 't1003-read-tree-prefix.sh', + 't1004-read-tree-m-u-wf.sh', + 't1005-read-tree-reset.sh', + 't1006-cat-file.sh', + 't1007-hash-object.sh', + 't1008-read-tree-overlay.sh', + 't1009-read-tree-new-index.sh', + 't1010-mktree.sh', + 't1011-read-tree-sparse-checkout.sh', + 't1012-read-tree-df.sh', + 't1013-read-tree-submodule.sh', + 't1014-read-tree-confusing.sh', + 't1015-read-index-unmerged.sh', + 't1016-compatObjectFormat.sh', + 't1020-subdirectory.sh', + 't1021-rerere-in-workdir.sh', + 't1022-read-tree-partial-clone.sh', + 't1050-large.sh', + 't1051-large-conversion.sh', + 't1060-object-corruption.sh', + 't1090-sparse-checkout-scope.sh', + 't1091-sparse-checkout-builtin.sh', + 't1092-sparse-checkout-compatibility.sh', + 't1100-commit-tree-options.sh', + 't1300-config.sh', + 't1301-shared-repo.sh', + 't1302-repo-version.sh', + 't1303-wacky-config.sh', + 't1304-default-acl.sh', + 't1305-config-include.sh', + 't1306-xdg-files.sh', + 't1307-config-blob.sh', + 't1308-config-set.sh', + 't1309-early-config.sh', + 't1310-config-default.sh', + 't1350-config-hooks-path.sh', + 't1400-update-ref.sh', + 't1401-symbolic-ref.sh', + 't1402-check-ref-format.sh', + 't1403-show-ref.sh', + 't1404-update-ref-errors.sh', + 't1405-main-ref-store.sh', + 't1406-submodule-ref-store.sh', + 't1407-worktree-ref-store.sh', + 't1408-packed-refs.sh', + 't1409-avoid-packing-refs.sh', + 't1410-reflog.sh', + 't1411-reflog-show.sh', + 't1412-reflog-loop.sh', + 't1413-reflog-detach.sh', + 't1414-reflog-walk.sh', + 't1415-worktree-refs.sh', + 't1416-ref-transaction-hooks.sh', + 't1417-reflog-updateref.sh', + 't1418-reflog-exists.sh', + 't1419-exclude-refs.sh', + 't1420-lost-found.sh', + 't1430-bad-ref-name.sh', + 't1450-fsck.sh', + 't1451-fsck-buffer.sh', + 't1460-refs-migrate.sh', + 't1500-rev-parse.sh', + 't1501-work-tree.sh', + 't1502-rev-parse-parseopt.sh', + 't1503-rev-parse-verify.sh', + 't1504-ceiling-dirs.sh', + 't1505-rev-parse-last.sh', + 't1506-rev-parse-diagnosis.sh', + 't1507-rev-parse-upstream.sh', + 't1508-at-combinations.sh', + 't1509-root-work-tree.sh', + 't1510-repo-setup.sh', + 't1511-rev-parse-caret.sh', + 't1512-rev-parse-disambiguation.sh', + 't1513-rev-parse-prefix.sh', + 't1514-rev-parse-push.sh', + 't1515-rev-parse-outside-repo.sh', + 't1517-outside-repo.sh', + 't1600-index.sh', + 't1601-index-bogus.sh', + 't1700-split-index.sh', + 't1701-racy-split-index.sh', + 't1800-hook.sh', + 't2000-conflict-when-checking-files-out.sh', + 't2002-checkout-cache-u.sh', + 't2003-checkout-cache-mkdir.sh', + 't2004-checkout-cache-temp.sh', + 't2005-checkout-index-symlinks.sh', + 't2006-checkout-index-basic.sh', + 't2007-checkout-symlink.sh', + 't2008-checkout-subdir.sh', + 't2009-checkout-statinfo.sh', + 't2010-checkout-ambiguous.sh', + 't2011-checkout-invalid-head.sh', + 't2012-checkout-last.sh', + 't2013-checkout-submodule.sh', + 't2014-checkout-switch.sh', + 't2015-checkout-unborn.sh', + 't2016-checkout-patch.sh', + 't2017-checkout-orphan.sh', + 't2018-checkout-branch.sh', + 't2019-checkout-ambiguous-ref.sh', + 't2020-checkout-detach.sh', + 't2021-checkout-overwrite.sh', + 't2022-checkout-paths.sh', + 't2023-checkout-m.sh', + 't2024-checkout-dwim.sh', + 't2025-checkout-no-overlay.sh', + 't2026-checkout-pathspec-file.sh', + 't2027-checkout-track.sh', + 't2030-unresolve-info.sh', + 't2050-git-dir-relative.sh', + 't2060-switch.sh', + 't2070-restore.sh', + 't2071-restore-patch.sh', + 't2072-restore-pathspec-file.sh', + 't2080-parallel-checkout-basics.sh', + 't2081-parallel-checkout-collisions.sh', + 't2082-parallel-checkout-attributes.sh', + 't2100-update-cache-badpath.sh', + 't2101-update-index-reupdate.sh', + 't2102-update-index-symlinks.sh', + 't2103-update-index-ignore-missing.sh', + 't2104-update-index-skip-worktree.sh', + 't2105-update-index-gitfile.sh', + 't2106-update-index-assume-unchanged.sh', + 't2107-update-index-basic.sh', + 't2108-update-index-refresh-racy.sh', + 't2200-add-update.sh', + 't2201-add-update-typechange.sh', + 't2202-add-addremove.sh', + 't2203-add-intent.sh', + 't2204-add-ignored.sh', + 't2205-add-worktree-config.sh', + 't2300-cd-to-toplevel.sh', + 't2400-worktree-add.sh', + 't2401-worktree-prune.sh', + 't2402-worktree-list.sh', + 't2403-worktree-move.sh', + 't2404-worktree-config.sh', + 't2405-worktree-submodule.sh', + 't2406-worktree-repair.sh', + 't2407-worktree-heads.sh', + 't2500-untracked-overwriting.sh', + 't2501-cwd-empty.sh', + 't3000-ls-files-others.sh', + 't3001-ls-files-others-exclude.sh', + 't3002-ls-files-dashpath.sh', + 't3003-ls-files-exclude.sh', + 't3004-ls-files-basic.sh', + 't3005-ls-files-relative.sh', + 't3006-ls-files-long.sh', + 't3007-ls-files-recurse-submodules.sh', + 't3008-ls-files-lazy-init-name-hash.sh', + 't3009-ls-files-others-nonsubmodule.sh', + 't3010-ls-files-killed-modified.sh', + 't3011-common-prefixes-and-directory-traversal.sh', + 't3012-ls-files-dedup.sh', + 't3013-ls-files-format.sh', + 't3020-ls-files-error-unmatch.sh', + 't3040-subprojects-basic.sh', + 't3050-subprojects-fetch.sh', + 't3060-ls-files-with-tree.sh', + 't3070-wildmatch.sh', + 't3100-ls-tree-restrict.sh', + 't3101-ls-tree-dirname.sh', + 't3102-ls-tree-wildcards.sh', + 't3103-ls-tree-misc.sh', + 't3104-ls-tree-format.sh', + 't3105-ls-tree-output.sh', + 't3200-branch.sh', + 't3201-branch-contains.sh', + 't3202-show-branch.sh', + 't3203-branch-output.sh', + 't3204-branch-name-interpretation.sh', + 't3205-branch-color.sh', + 't3206-range-diff.sh', + 't3207-branch-submodule.sh', + 't3211-peel-ref.sh', + 't3300-funny-names.sh', + 't3301-notes.sh', + 't3302-notes-index-expensive.sh', + 't3303-notes-subtrees.sh', + 't3304-notes-mixed.sh', + 't3305-notes-fanout.sh', + 't3306-notes-prune.sh', + 't3307-notes-man.sh', + 't3308-notes-merge.sh', + 't3309-notes-merge-auto-resolve.sh', + 't3310-notes-merge-manual-resolve.sh', + 't3311-notes-merge-fanout.sh', + 't3320-notes-merge-worktrees.sh', + 't3321-notes-stripspace.sh', + 't3400-rebase.sh', + 't3401-rebase-and-am-rename.sh', + 't3402-rebase-merge.sh', + 't3403-rebase-skip.sh', + 't3404-rebase-interactive.sh', + 't3405-rebase-malformed.sh', + 't3406-rebase-message.sh', + 't3407-rebase-abort.sh', + 't3408-rebase-multi-line.sh', + 't3409-rebase-environ.sh', + 't3412-rebase-root.sh', + 't3413-rebase-hook.sh', + 't3415-rebase-autosquash.sh', + 't3416-rebase-onto-threedots.sh', + 't3417-rebase-whitespace-fix.sh', + 't3418-rebase-continue.sh', + 't3419-rebase-patch-id.sh', + 't3420-rebase-autostash.sh', + 't3421-rebase-topology-linear.sh', + 't3422-rebase-incompatible-options.sh', + 't3423-rebase-reword.sh', + 't3424-rebase-empty.sh', + 't3425-rebase-topology-merges.sh', + 't3426-rebase-submodule.sh', + 't3427-rebase-subtree.sh', + 't3428-rebase-signoff.sh', + 't3429-rebase-edit-todo.sh', + 't3430-rebase-merges.sh', + 't3431-rebase-fork-point.sh', + 't3432-rebase-fast-forward.sh', + 't3433-rebase-across-mode-change.sh', + 't3434-rebase-i18n.sh', + 't3435-rebase-gpg-sign.sh', + 't3436-rebase-more-options.sh', + 't3437-rebase-fixup-options.sh', + 't3438-rebase-broken-files.sh', + 't3500-cherry.sh', + 't3501-revert-cherry-pick.sh', + 't3502-cherry-pick-merge.sh', + 't3503-cherry-pick-root.sh', + 't3504-cherry-pick-rerere.sh', + 't3505-cherry-pick-empty.sh', + 't3506-cherry-pick-ff.sh', + 't3507-cherry-pick-conflict.sh', + 't3508-cherry-pick-many-commits.sh', + 't3509-cherry-pick-merge-df.sh', + 't3510-cherry-pick-sequence.sh', + 't3511-cherry-pick-x.sh', + 't3512-cherry-pick-submodule.sh', + 't3513-revert-submodule.sh', + 't3514-cherry-pick-revert-gpg.sh', + 't3600-rm.sh', + 't3601-rm-pathspec-file.sh', + 't3602-rm-sparse-checkout.sh', + 't3650-replay-basics.sh', + 't3700-add.sh', + 't3701-add-interactive.sh', + 't3702-add-edit.sh', + 't3703-add-magic-pathspec.sh', + 't3704-add-pathspec-file.sh', + 't3705-add-sparse-checkout.sh', + 't3800-mktag.sh', + 't3900-i18n-commit.sh', + 't3901-i18n-patch.sh', + 't3902-quoted.sh', + 't3903-stash.sh', + 't3904-stash-patch.sh', + 't3905-stash-include-untracked.sh', + 't3906-stash-submodule.sh', + 't3907-stash-show-config.sh', + 't3908-stash-in-worktree.sh', + 't3909-stash-pathspec-file.sh', + 't3910-mac-os-precompose.sh', + 't3920-crlf-messages.sh', + 't4000-diff-format.sh', + 't4001-diff-rename.sh', + 't4002-diff-basic.sh', + 't4003-diff-rename-1.sh', + 't4004-diff-rename-symlink.sh', + 't4005-diff-rename-2.sh', + 't4006-diff-mode.sh', + 't4007-rename-3.sh', + 't4008-diff-break-rewrite.sh', + 't4009-diff-rename-4.sh', + 't4010-diff-pathspec.sh', + 't4011-diff-symlink.sh', + 't4012-diff-binary.sh', + 't4013-diff-various.sh', + 't4014-format-patch.sh', + 't4015-diff-whitespace.sh', + 't4016-diff-quote.sh', + 't4017-diff-retval.sh', + 't4018-diff-funcname.sh', + 't4019-diff-wserror.sh', + 't4020-diff-external.sh', + 't4021-format-patch-numbered.sh', + 't4022-diff-rewrite.sh', + 't4023-diff-rename-typechange.sh', + 't4024-diff-optimize-common.sh', + 't4025-hunk-header.sh', + 't4026-color.sh', + 't4027-diff-submodule.sh', + 't4028-format-patch-mime-headers.sh', + 't4029-diff-trailing-space.sh', + 't4030-diff-textconv.sh', + 't4031-diff-rewrite-binary.sh', + 't4032-diff-inter-hunk-context.sh', + 't4033-diff-patience.sh', + 't4034-diff-words.sh', + 't4035-diff-quiet.sh', + 't4036-format-patch-signer-mime.sh', + 't4037-diff-r-t-dirs.sh', + 't4038-diff-combined.sh', + 't4039-diff-assume-unchanged.sh', + 't4040-whitespace-status.sh', + 't4041-diff-submodule-option.sh', + 't4042-diff-textconv-caching.sh', + 't4043-diff-rename-binary.sh', + 't4044-diff-index-unique-abbrev.sh', + 't4045-diff-relative.sh', + 't4046-diff-unmerged.sh', + 't4047-diff-dirstat.sh', + 't4048-diff-combined-binary.sh', + 't4049-diff-stat-count.sh', + 't4050-diff-histogram.sh', + 't4051-diff-function-context.sh', + 't4052-stat-output.sh', + 't4053-diff-no-index.sh', + 't4054-diff-bogus-tree.sh', + 't4055-diff-context.sh', + 't4056-diff-order.sh', + 't4057-diff-combined-paths.sh', + 't4058-diff-duplicates.sh', + 't4059-diff-submodule-not-initialized.sh', + 't4060-diff-submodule-option-diff-format.sh', + 't4061-diff-indent.sh', + 't4062-diff-pickaxe.sh', + 't4063-diff-blobs.sh', + 't4064-diff-oidfind.sh', + 't4065-diff-anchored.sh', + 't4066-diff-emit-delay.sh', + 't4067-diff-partial-clone.sh', + 't4068-diff-symmetric-merge-base.sh', + 't4069-remerge-diff.sh', + 't4100-apply-stat.sh', + 't4101-apply-nonl.sh', + 't4102-apply-rename.sh', + 't4103-apply-binary.sh', + 't4104-apply-boundary.sh', + 't4105-apply-fuzz.sh', + 't4106-apply-stdin.sh', + 't4107-apply-ignore-whitespace.sh', + 't4108-apply-threeway.sh', + 't4109-apply-multifrag.sh', + 't4110-apply-scan.sh', + 't4111-apply-subdir.sh', + 't4112-apply-renames.sh', + 't4113-apply-ending.sh', + 't4114-apply-typechange.sh', + 't4115-apply-symlink.sh', + 't4116-apply-reverse.sh', + 't4117-apply-reject.sh', + 't4118-apply-empty-context.sh', + 't4119-apply-config.sh', + 't4120-apply-popt.sh', + 't4121-apply-diffs.sh', + 't4122-apply-symlink-inside.sh', + 't4123-apply-shrink.sh', + 't4124-apply-ws-rule.sh', + 't4125-apply-ws-fuzz.sh', + 't4126-apply-empty.sh', + 't4127-apply-same-fn.sh', + 't4128-apply-root.sh', + 't4129-apply-samemode.sh', + 't4130-apply-criss-cross-rename.sh', + 't4131-apply-fake-ancestor.sh', + 't4132-apply-removal.sh', + 't4133-apply-filenames.sh', + 't4134-apply-submodule.sh', + 't4135-apply-weird-filenames.sh', + 't4136-apply-check.sh', + 't4137-apply-submodule.sh', + 't4138-apply-ws-expansion.sh', + 't4139-apply-escape.sh', + 't4140-apply-ita.sh', + 't4141-apply-too-large.sh', + 't4150-am.sh', + 't4151-am-abort.sh', + 't4152-am-subjects.sh', + 't4153-am-resume-override-opts.sh', + 't4200-rerere.sh', + 't4201-shortlog.sh', + 't4202-log.sh', + 't4203-mailmap.sh', + 't4204-patch-id.sh', + 't4205-log-pretty-formats.sh', + 't4206-log-follow-harder-copies.sh', + 't4207-log-decoration-colors.sh', + 't4208-log-magic-pathspec.sh', + 't4209-log-pickaxe.sh', + 't4210-log-i18n.sh', + 't4211-line-log.sh', + 't4212-log-corrupt.sh', + 't4213-log-tabexpand.sh', + 't4214-log-graph-octopus.sh', + 't4215-log-skewed-merges.sh', + 't4216-log-bloom.sh', + 't4217-log-limit.sh', + 't4252-am-options.sh', + 't4253-am-keep-cr-dos.sh', + 't4254-am-corrupt.sh', + 't4255-am-submodule.sh', + 't4256-am-format-flowed.sh', + 't4257-am-interactive.sh', + 't4258-am-quoted-cr.sh', + 't4300-merge-tree.sh', + 't4301-merge-tree-write-tree.sh', + 't5000-tar-tree.sh', + 't5001-archive-attr.sh', + 't5002-archive-attr-pattern.sh', + 't5003-archive-zip.sh', + 't5004-archive-corner-cases.sh', + 't5100-mailinfo.sh', + 't5150-request-pull.sh', + 't5200-update-server-info.sh', + 't5300-pack-object.sh', + 't5301-sliding-window.sh', + 't5302-pack-index.sh', + 't5303-pack-corruption-resilience.sh', + 't5304-prune.sh', + 't5305-include-tag.sh', + 't5306-pack-nobase.sh', + 't5307-pack-missing-commit.sh', + 't5308-pack-detect-duplicates.sh', + 't5309-pack-delta-cycles.sh', + 't5310-pack-bitmaps.sh', + 't5311-pack-bitmaps-shallow.sh', + 't5312-prune-corruption.sh', + 't5313-pack-bounds-checks.sh', + 't5314-pack-cycle-detection.sh', + 't5315-pack-objects-compression.sh', + 't5316-pack-delta-depth.sh', + 't5317-pack-objects-filter-objects.sh', + 't5318-commit-graph.sh', + 't5319-multi-pack-index.sh', + 't5320-delta-islands.sh', + 't5321-pack-large-objects.sh', + 't5322-pack-objects-sparse.sh', + 't5323-pack-redundant.sh', + 't5324-split-commit-graph.sh', + 't5325-reverse-index.sh', + 't5326-multi-pack-bitmaps.sh', + 't5327-multi-pack-bitmaps-rev.sh', + 't5328-commit-graph-64bit-time.sh', + 't5329-pack-objects-cruft.sh', + 't5330-no-lazy-fetch-with-commit-graph.sh', + 't5331-pack-objects-stdin.sh', + 't5332-multi-pack-reuse.sh', + 't5333-pseudo-merge-bitmaps.sh', + 't5334-incremental-multi-pack-index.sh', + 't5351-unpack-large-objects.sh', + 't5400-send-pack.sh', + 't5401-update-hooks.sh', + 't5402-post-merge-hook.sh', + 't5403-post-checkout-hook.sh', + 't5404-tracking-branches.sh', + 't5405-send-pack-rewind.sh', + 't5406-remote-rejects.sh', + 't5407-post-rewrite-hook.sh', + 't5408-send-pack-stdin.sh', + 't5409-colorize-remote-messages.sh', + 't5410-receive-pack-alternates.sh', + 't5411-proc-receive-hook.sh', + 't5500-fetch-pack.sh', + 't5501-fetch-push-alternates.sh', + 't5502-quickfetch.sh', + 't5503-tagfollow.sh', + 't5504-fetch-receive-strict.sh', + 't5505-remote.sh', + 't5506-remote-groups.sh', + 't5507-remote-environment.sh', + 't5509-fetch-push-namespaces.sh', + 't5510-fetch.sh', + 't5511-refspec.sh', + 't5512-ls-remote.sh', + 't5513-fetch-track.sh', + 't5514-fetch-multiple.sh', + 't5515-fetch-merge-logic.sh', + 't5516-fetch-push.sh', + 't5517-push-mirror.sh', + 't5518-fetch-exit-status.sh', + 't5519-push-alternates.sh', + 't5520-pull.sh', + 't5521-pull-options.sh', + 't5522-pull-symlink.sh', + 't5523-push-upstream.sh', + 't5524-pull-msg.sh', + 't5525-fetch-tagopt.sh', + 't5526-fetch-submodules.sh', + 't5527-fetch-odd-refs.sh', + 't5528-push-default.sh', + 't5529-push-errors.sh', + 't5530-upload-pack-error.sh', + 't5531-deep-submodule-push.sh', + 't5532-fetch-proxy.sh', + 't5533-push-cas.sh', + 't5534-push-signed.sh', + 't5535-fetch-push-symref.sh', + 't5536-fetch-conflicts.sh', + 't5537-fetch-shallow.sh', + 't5538-push-shallow.sh', + 't5539-fetch-http-shallow.sh', + 't5540-http-push-webdav.sh', + 't5541-http-push-smart.sh', + 't5542-push-http-shallow.sh', + 't5543-atomic-push.sh', + 't5544-pack-objects-hook.sh', + 't5545-push-options.sh', + 't5546-receive-limits.sh', + 't5547-push-quarantine.sh', + 't5548-push-porcelain.sh', + 't5549-fetch-push-http.sh', + 't5550-http-fetch-dumb.sh', + 't5551-http-fetch-smart.sh', + 't5552-skipping-fetch-negotiator.sh', + 't5553-set-upstream.sh', + 't5554-noop-fetch-negotiator.sh', + 't5555-http-smart-common.sh', + 't5557-http-get.sh', + 't5558-clone-bundle-uri.sh', + 't5559-http-fetch-smart-http2.sh', + 't5560-http-backend-noserver.sh', + 't5561-http-backend.sh', + 't5562-http-backend-content-length.sh', + 't5563-simple-http-auth.sh', + 't5564-http-proxy.sh', + 't5570-git-daemon.sh', + 't5571-pre-push-hook.sh', + 't5572-pull-submodule.sh', + 't5573-pull-verify-signatures.sh', + 't5574-fetch-output.sh', + 't5580-unc-paths.sh', + 't5581-http-curl-verbose.sh', + 't5582-fetch-negative-refspec.sh', + 't5583-push-branches.sh', + 't5600-clone-fail-cleanup.sh', + 't5601-clone.sh', + 't5602-clone-remote-exec.sh', + 't5603-clone-dirname.sh', + 't5604-clone-reference.sh', + 't5605-clone-local.sh', + 't5606-clone-options.sh', + 't5607-clone-bundle.sh', + 't5608-clone-2gb.sh', + 't5609-clone-branch.sh', + 't5610-clone-detached.sh', + 't5611-clone-config.sh', + 't5612-clone-refspec.sh', + 't5613-info-alternate.sh', + 't5614-clone-submodules-shallow.sh', + 't5615-alternate-env.sh', + 't5616-partial-clone.sh', + 't5617-clone-submodules-remote.sh', + 't5618-alternate-refs.sh', + 't5619-clone-local-ambiguous-transport.sh', + 't5620-backfill.sh', + 't5621-clone-revision.sh', + 't5700-protocol-v1.sh', + 't5701-git-serve.sh', + 't5702-protocol-v2.sh', + 't5703-upload-pack-ref-in-want.sh', + 't5704-protocol-violations.sh', + 't5705-session-id-in-capabilities.sh', + 't5710-promisor-remote-capability.sh', + 't5730-protocol-v2-bundle-uri-file.sh', + 't5731-protocol-v2-bundle-uri-git.sh', + 't5732-protocol-v2-bundle-uri-http.sh', + 't5750-bundle-uri-parse.sh', + 't5801-remote-helpers.sh', + 't5802-connect-helper.sh', + 't5810-proto-disable-local.sh', + 't5811-proto-disable-git.sh', + 't5812-proto-disable-http.sh', + 't5813-proto-disable-ssh.sh', + 't5814-proto-disable-ext.sh', + 't5815-submodule-protos.sh', + 't5900-repo-selection.sh', + 't6000-rev-list-misc.sh', + 't6001-rev-list-graft.sh', + 't6002-rev-list-bisect.sh', + 't6003-rev-list-topo-order.sh', + 't6004-rev-list-path-optim.sh', + 't6005-rev-list-count.sh', + 't6006-rev-list-format.sh', + 't6007-rev-list-cherry-pick-file.sh', + 't6008-rev-list-submodule.sh', + 't6009-rev-list-parent.sh', + 't6010-merge-base.sh', + 't6011-rev-list-with-bad-commit.sh', + 't6012-rev-list-simplify.sh', + 't6013-rev-list-reverse-parents.sh', + 't6014-rev-list-all.sh', + 't6016-rev-list-graph-simplify-history.sh', + 't6017-rev-list-stdin.sh', + 't6018-rev-list-glob.sh', + 't6019-rev-list-ancestry-path.sh', + 't6020-bundle-misc.sh', + 't6021-rev-list-exclude-hidden.sh', + 't6022-rev-list-missing.sh', + 't6030-bisect-porcelain.sh', + 't6040-tracking-info.sh', + 't6041-bisect-submodule.sh', + 't6050-replace.sh', + 't6060-merge-index.sh', + 't6100-rev-list-in-order.sh', + 't6101-rev-parse-parents.sh', + 't6102-rev-list-unexpected-objects.sh', + 't6110-rev-list-sparse.sh', + 't6111-rev-list-treesame.sh', + 't6112-rev-list-filters-objects.sh', + 't6113-rev-list-bitmap-filters.sh', + 't6114-keep-packs.sh', + 't6115-rev-list-du.sh', + 't6120-describe.sh', + 't6130-pathspec-noglob.sh', + 't6131-pathspec-icase.sh', + 't6132-pathspec-exclude.sh', + 't6133-pathspec-rev-dwim.sh', + 't6134-pathspec-in-submodule.sh', + 't6135-pathspec-with-attrs.sh', + 't6136-pathspec-in-bare.sh', + 't6200-fmt-merge-msg.sh', + 't6300-for-each-ref.sh', + 't6301-for-each-ref-errors.sh', + 't6302-for-each-ref-filter.sh', + 't6400-merge-df.sh', + 't6401-merge-criss-cross.sh', + 't6402-merge-rename.sh', + 't6403-merge-file.sh', + 't6404-recursive-merge.sh', + 't6405-merge-symlinks.sh', + 't6406-merge-attr.sh', + 't6407-merge-binary.sh', + 't6408-merge-up-to-date.sh', + 't6409-merge-subtree.sh', + 't6411-merge-filemode.sh', + 't6412-merge-large-rename.sh', + 't6413-merge-crlf.sh', + 't6414-merge-rename-nocruft.sh', + 't6415-merge-dir-to-symlink.sh', + 't6416-recursive-corner-cases.sh', + 't6417-merge-ours-theirs.sh', + 't6418-merge-text-auto.sh', + 't6419-merge-ignorecase.sh', + 't6421-merge-partial-clone.sh', + 't6422-merge-rename-corner-cases.sh', + 't6423-merge-rename-directories.sh', + 't6424-merge-unrelated-index-changes.sh', + 't6425-merge-rename-delete.sh', + 't6426-merge-skip-unneeded-updates.sh', + 't6427-diff3-conflict-markers.sh', + 't6428-merge-conflicts-sparse.sh', + 't6429-merge-sequence-rename-caching.sh', + 't6430-merge-recursive.sh', + 't6431-merge-criscross.sh', + 't6432-merge-recursive-space-options.sh', + 't6433-merge-toplevel.sh', + 't6434-merge-recursive-rename-options.sh', + 't6435-merge-sparse.sh', + 't6436-merge-overwrite.sh', + 't6437-submodule-merge.sh', + 't6438-submodule-directory-file-conflicts.sh', + 't6439-merge-co-error-msgs.sh', + 't6500-gc.sh', + 't6501-freshen-objects.sh', + 't6600-test-reach.sh', + 't6601-path-walk.sh', + 't6700-tree-depth.sh', + 't7001-mv.sh', + 't7002-mv-sparse-checkout.sh', + 't7003-filter-branch.sh', + 't7004-tag.sh', + 't7005-editor.sh', + 't7006-pager.sh', + 't7007-show.sh', + 't7008-filter-branch-null-sha1.sh', + 't7010-setup.sh', + 't7011-skip-worktree-reading.sh', + 't7012-skip-worktree-writing.sh', + 't7030-verify-tag.sh', + 't7031-verify-tag-signed-ssh.sh', + 't7060-wtstatus.sh', + 't7061-wtstatus-ignore.sh', + 't7062-wtstatus-ignorecase.sh', + 't7063-status-untracked-cache.sh', + 't7064-wtstatus-pv2.sh', + 't7101-reset-empty-subdirs.sh', + 't7102-reset.sh', + 't7103-reset-bare.sh', + 't7104-reset-hard.sh', + 't7105-reset-patch.sh', + 't7106-reset-unborn-branch.sh', + 't7107-reset-pathspec-file.sh', + 't7110-reset-merge.sh', + 't7111-reset-table.sh', + 't7112-reset-submodule.sh', + 't7113-post-index-change-hook.sh', + 't7201-co.sh', + 't7300-clean.sh', + 't7301-clean-interactive.sh', + 't7400-submodule-basic.sh', + 't7401-submodule-summary.sh', + 't7402-submodule-rebase.sh', + 't7403-submodule-sync.sh', + 't7406-submodule-update.sh', + 't7407-submodule-foreach.sh', + 't7408-submodule-reference.sh', + 't7409-submodule-detached-work-tree.sh', + 't7411-submodule-config.sh', + 't7412-submodule-absorbgitdirs.sh', + 't7413-submodule-is-active.sh', + 't7414-submodule-mistakes.sh', + 't7416-submodule-dash-url.sh', + 't7417-submodule-path-url.sh', + 't7418-submodule-sparse-gitmodules.sh', + 't7419-submodule-set-branch.sh', + 't7420-submodule-set-url.sh', + 't7421-submodule-summary-add.sh', + 't7422-submodule-output.sh', + 't7423-submodule-symlinks.sh', + 't7424-submodule-mixed-ref-formats.sh', + 't7450-bad-git-dotfiles.sh', + 't7500-commit-template-squash-signoff.sh', + 't7501-commit-basic-functionality.sh', + 't7502-commit-porcelain.sh', + 't7503-pre-commit-and-pre-merge-commit-hooks.sh', + 't7504-commit-msg-hook.sh', + 't7505-prepare-commit-msg-hook.sh', + 't7506-status-submodule.sh', + 't7507-commit-verbose.sh', + 't7508-status.sh', + 't7509-commit-authorship.sh', + 't7510-signed-commit.sh', + 't7511-status-index.sh', + 't7512-status-help.sh', + 't7513-interpret-trailers.sh', + 't7514-commit-patch.sh', + 't7515-status-symlinks.sh', + 't7516-commit-races.sh', + 't7517-per-repo-email.sh', + 't7518-ident-corner-cases.sh', + 't7519-status-fsmonitor.sh', + 't7520-ignored-hook-warning.sh', + 't7521-ignored-mode.sh', + 't7524-commit-summary.sh', + 't7525-status-rename.sh', + 't7526-commit-pathspec-file.sh', + 't7527-builtin-fsmonitor.sh', + 't7528-signed-commit-ssh.sh', + 't7600-merge.sh', + 't7601-merge-pull-config.sh', + 't7602-merge-octopus-many.sh', + 't7603-merge-reduce-heads.sh', + 't7604-merge-custom-message.sh', + 't7605-merge-resolve.sh', + 't7606-merge-custom.sh', + 't7607-merge-state.sh', + 't7608-merge-messages.sh', + 't7609-mergetool--lib.sh', + 't7610-mergetool.sh', + 't7611-merge-abort.sh', + 't7612-merge-verify-signatures.sh', + 't7614-merge-signoff.sh', + 't7615-diff-algo-with-mergy-operations.sh', + 't7700-repack.sh', + 't7701-repack-unpack-unreachable.sh', + 't7702-repack-cyclic-alternate.sh', + 't7703-repack-geometric.sh', + 't7704-repack-cruft.sh', + 't7800-difftool.sh', + 't7810-grep.sh', + 't7811-grep-open.sh', + 't7812-grep-icase-non-ascii.sh', + 't7813-grep-icase-iso.sh', + 't7814-grep-recurse-submodules.sh', + 't7815-grep-binary.sh', + 't7816-grep-binary-pattern.sh', + 't7817-grep-sparse-checkout.sh', + 't7900-maintenance.sh', + 't8001-annotate.sh', + 't8002-blame.sh', + 't8003-blame-corner-cases.sh', + 't8004-blame-with-conflicts.sh', + 't8005-blame-i18n.sh', + 't8006-blame-textconv.sh', + 't8007-cat-file-textconv.sh', + 't8008-blame-formats.sh', + 't8009-blame-vs-topicbranches.sh', + 't8010-cat-file-filters.sh', + 't8011-blame-split-file.sh', + 't8012-blame-colors.sh', + 't8013-blame-ignore-revs.sh', + 't8014-blame-ignore-fuzzy.sh', + 't8100-git-survey.sh', + 't9001-send-email.sh', + 't9002-column.sh', + 't9003-help-autocorrect.sh', + 't9100-git-svn-basic.sh', + 't9101-git-svn-props.sh', + 't9102-git-svn-deep-rmdir.sh', + 't9103-git-svn-tracked-directory-removed.sh', + 't9104-git-svn-follow-parent.sh', + 't9105-git-svn-commit-diff.sh', + 't9106-git-svn-commit-diff-clobber.sh', + 't9107-git-svn-migrate.sh', + 't9108-git-svn-glob.sh', + 't9109-git-svn-multi-glob.sh', + 't9110-git-svn-use-svm-props.sh', + 't9111-git-svn-use-svnsync-props.sh', + 't9112-git-svn-md5less-file.sh', + 't9113-git-svn-dcommit-new-file.sh', + 't9114-git-svn-dcommit-merge.sh', + 't9115-git-svn-dcommit-funky-renames.sh', + 't9116-git-svn-log.sh', + 't9117-git-svn-init-clone.sh', + 't9118-git-svn-funky-branch-names.sh', + 't9119-git-svn-info.sh', + 't9120-git-svn-clone-with-percent-escapes.sh', + 't9121-git-svn-fetch-renamed-dir.sh', + 't9122-git-svn-author.sh', + 't9123-git-svn-rebuild-with-rewriteroot.sh', + 't9124-git-svn-dcommit-auto-props.sh', + 't9125-git-svn-multi-glob-branch-names.sh', + 't9126-git-svn-follow-deleted-readded-directory.sh', + 't9127-git-svn-partial-rebuild.sh', + 't9128-git-svn-cmd-branch.sh', + 't9129-git-svn-i18n-commitencoding.sh', + 't9130-git-svn-authors-file.sh', + 't9131-git-svn-empty-symlink.sh', + 't9132-git-svn-broken-symlink.sh', + 't9133-git-svn-nested-git-repo.sh', + 't9134-git-svn-ignore-paths.sh', + 't9135-git-svn-moved-branch-empty-file.sh', + 't9136-git-svn-recreated-branch-empty-file.sh', + 't9137-git-svn-dcommit-clobber-series.sh', + 't9138-git-svn-authors-prog.sh', + 't9139-git-svn-non-utf8-commitencoding.sh', + 't9140-git-svn-reset.sh', + 't9141-git-svn-multiple-branches.sh', + 't9142-git-svn-shallow-clone.sh', + 't9143-git-svn-gc.sh', + 't9144-git-svn-old-rev_map.sh', + 't9145-git-svn-master-branch.sh', + 't9146-git-svn-empty-dirs.sh', + 't9147-git-svn-include-paths.sh', + 't9148-git-svn-propset.sh', + 't9150-svk-mergetickets.sh', + 't9151-svn-mergeinfo.sh', + 't9152-svn-empty-dirs-after-gc.sh', + 't9153-git-svn-rewrite-uuid.sh', + 't9154-git-svn-fancy-glob.sh', + 't9155-git-svn-fetch-deleted-tag.sh', + 't9156-git-svn-fetch-deleted-tag-2.sh', + 't9157-git-svn-fetch-merge.sh', + 't9158-git-svn-mergeinfo.sh', + 't9159-git-svn-no-parent-mergeinfo.sh', + 't9160-git-svn-preserve-empty-dirs.sh', + 't9161-git-svn-mergeinfo-push.sh', + 't9162-git-svn-dcommit-interactive.sh', + 't9163-git-svn-reset-clears-caches.sh', + 't9164-git-svn-dcommit-concurrent.sh', + 't9165-git-svn-fetch-merge-branch-of-branch.sh', + 't9166-git-svn-fetch-merge-branch-of-branch2.sh', + 't9167-git-svn-cmd-branch-subproject.sh', + 't9168-git-svn-partially-globbed-names.sh', + 't9169-git-svn-dcommit-crlf.sh', + 't9200-git-cvsexportcommit.sh', + 't9210-scalar.sh', + 't9211-scalar-clone.sh', + 't9300-fast-import.sh', + 't9301-fast-import-notes.sh', + 't9302-fast-import-unpack-limit.sh', + 't9303-fast-import-compression.sh', + 't9304-fast-import-marks.sh', + 't9350-fast-export.sh', + 't9351-fast-export-anonymize.sh', + 't9400-git-cvsserver-server.sh', + 't9401-git-cvsserver-crlf.sh', + 't9402-git-cvsserver-refs.sh', + 't9500-gitweb-standalone-no-errors.sh', + 't9501-gitweb-standalone-http-status.sh', + 't9502-gitweb-standalone-parse-output.sh', + 't9600-cvsimport.sh', + 't9601-cvsimport-vendor-branch.sh', + 't9602-cvsimport-branches-tags.sh', + 't9603-cvsimport-patchsets.sh', + 't9604-cvsimport-timestamps.sh', + 't9700-perl-git.sh', + 't9800-git-p4-basic.sh', + 't9801-git-p4-branch.sh', + 't9802-git-p4-filetype.sh', + 't9803-git-p4-shell-metachars.sh', + 't9804-git-p4-label.sh', + 't9805-git-p4-skip-submit-edit.sh', + 't9806-git-p4-options.sh', + 't9807-git-p4-submit.sh', + 't9808-git-p4-chdir.sh', + 't9809-git-p4-client-view.sh', + 't9810-git-p4-rcs.sh', + 't9811-git-p4-label-import.sh', + 't9812-git-p4-wildcards.sh', + 't9813-git-p4-preserve-users.sh', + 't9814-git-p4-rename.sh', + 't9815-git-p4-submit-fail.sh', + 't9816-git-p4-locked.sh', + 't9817-git-p4-exclude.sh', + 't9818-git-p4-block.sh', + 't9819-git-p4-case-folding.sh', + 't9820-git-p4-editor-handling.sh', + 't9821-git-p4-path-variations.sh', + 't9822-git-p4-path-encoding.sh', + 't9823-git-p4-mock-lfs.sh', + 't9824-git-p4-git-lfs.sh', + 't9825-git-p4-handle-utf16-without-bom.sh', + 't9826-git-p4-keep-empty-commits.sh', + 't9827-git-p4-change-filetype.sh', + 't9828-git-p4-map-user.sh', + 't9829-git-p4-jobs.sh', + 't9830-git-p4-symlink-dir.sh', + 't9831-git-p4-triggers.sh', + 't9832-unshelve.sh', + 't9833-errors.sh', + 't9834-git-p4-file-dir-bug.sh', + 't9835-git-p4-metadata-encoding-python2.sh', + 't9836-git-p4-metadata-encoding-python3.sh', + 't9850-shell.sh', + 't9901-git-web--browse.sh', + 't9902-completion.sh', + 't9903-bash-prompt.sh', +] + +# Sanity check that we are not missing any tests present in 't/'. This check +# only runs once at configure time and is thus best-effort, only. It is +# sufficient to catch missing test suites in our CI though. +foreach glob, tests : { + 't[0-9][0-9][0-9][0-9]-*.sh': integration_tests, + 'unit-tests/t-*.c': unit_test_programs, + 'unit-tests/u-*.c': clar_test_suites, +} + actual_tests = run_command(shell, '-c', 'ls ' + glob, + check: true, + env: script_environment, + ).stdout().strip().split('\n') + + if tests != actual_tests + missing_tests = [ ] + foreach actual_test : actual_tests + if actual_test not in tests + missing_tests += actual_test + endif + endforeach + if missing_tests.length() > 0 + error('Test files found, but not configured:\n\n - ' + '\n - '.join(missing_tests)) + endif + + superfluous_tests = [ ] + foreach integration_test : tests + if integration_test not in actual_tests + superfluous_tests += integration_test + endif + endforeach + if superfluous_tests.length() > 0 + error('Test files configured, but not found:\n\n - ' + '\n - '.join(superfluous_tests)) + endif + endif +endforeach + +# GIT_BUILD_DIR needs to be Unix-style without drive prefixes as it get added +# to the PATH variable. And given that drive prefixes contain a colon we'd +# otherwise end up with a broken PATH if we didn't convert it. +git_build_dir = meson.project_build_root() +if cygpath.found() + git_build_dir = run_command(cygpath, git_build_dir, check: true).stdout().strip() +endif + +test_environment = script_environment +test_environment.set('GIT_BUILD_DIR', git_build_dir) + +foreach integration_test : integration_tests + test(fs.stem(integration_test), shell, + args: [ integration_test ], + workdir: meson.current_source_dir(), + env: test_environment, + depends: test_dependencies + bin_wrappers, + timeout: 0, + ) +endforeach diff --git a/t/perf/Makefile b/t/perf/Makefile index e4808aebed08bf..9b3090c4edeca4 100644 --- a/t/perf/Makefile +++ b/t/perf/Makefile @@ -1,10 +1,13 @@ +# The default target of this Makefile is... +all:: + # Import tree-wide shared Makefile behavior and libraries include ../../shared.mak -include ../../config.mak export GIT_TEST_OPTIONS -all: test-lint perf +all:: test-lint perf perf: pre-clean ./run diff --git a/t/perf/p5311-pack-bitmaps-fetch.sh b/t/perf/p5311-pack-bitmaps-fetch.sh index 426fab87e3293e..047efb995d647b 100755 --- a/t/perf/p5311-pack-bitmaps-fetch.sh +++ b/t/perf/p5311-pack-bitmaps-fetch.sh @@ -39,7 +39,7 @@ test_fetch_bitmaps () { ' test_size "size $title" ' - wc -c <tmp.pack + test_file_size tmp.pack ' test_perf "client $title (lookup=$1)" ' diff --git a/t/perf/p5313-pack-objects.sh b/t/perf/p5313-pack-objects.sh new file mode 100755 index 00000000000000..be5229a0ecdcf5 --- /dev/null +++ b/t/perf/p5313-pack-objects.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +test_description='Tests pack performance using bitmaps' +. ./perf-lib.sh + +GIT_TEST_PASSING_SANITIZE_LEAK=0 +export GIT_TEST_PASSING_SANITIZE_LEAK + +test_perf_large_repo + +test_expect_success 'create rev input' ' + cat >in-thin <<-EOF && + $(git rev-parse HEAD) + ^$(git rev-parse HEAD~1) + EOF + + cat >in-big <<-EOF && + $(git rev-parse HEAD) + ^$(git rev-parse HEAD~1000) + EOF + + cat >in-shallow <<-EOF + $(git rev-parse HEAD) + --shallow $(git rev-parse HEAD) + EOF +' + +for version in 1 2 +do + export version + + test_perf "thin pack with version $version" ' + git pack-objects --thin --stdout --revs --sparse \ + --name-hash-version=$version <in-thin >out + ' + + test_size "thin pack size with version $version" ' + test_file_size out + ' + + test_perf "big pack with version $version" ' + git pack-objects --stdout --revs --sparse \ + --name-hash-version=$version <in-big >out + ' + + test_size "big pack size with version $version" ' + test_file_size out + ' + + test_perf "shallow fetch pack with version $version" ' + git pack-objects --stdout --revs --sparse --shallow \ + --name-hash-version=$version <in-shallow >out + ' + + test_size "shallow pack size with version $version" ' + test_file_size out + ' + + test_perf "repack with version $version" ' + git repack -adf --name-hash-version=$version + ' + + test_size "repack size with version $version" ' + gitdir=$(git rev-parse --git-dir) && + pack=$(ls $gitdir/objects/pack/pack-*.pack) && + test_file_size "$pack" + ' +done + +test_done diff --git a/t/perf/p5314-name-hash.sh b/t/perf/p5314-name-hash.sh new file mode 100755 index 00000000000000..4ef0ba771143d8 --- /dev/null +++ b/t/perf/p5314-name-hash.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +test_description='Tests pack performance using bitmaps' +. ./perf-lib.sh + +GIT_TEST_PASSING_SANITIZE_LEAK=0 +export GIT_TEST_PASSING_SANITIZE_LEAK + +test_perf_large_repo + +test_size 'paths at head' ' + git ls-tree -r --name-only HEAD >path-list && + wc -l <path-list && + test-tool name-hash <path-list >name-hashes +' + +for version in 1 2 +do + test_size "distinct hash value: v$version" ' + awk "{ print \$$version; }" <name-hashes | sort | \ + uniq -c >name-hash-count && + wc -l <name-hash-count + ' + + test_size "maximum multiplicity: v$version" ' + sort -nr <name-hash-count | head -n 1 | \ + awk "{ print \$1; }" + ' +done + +test_done diff --git a/t/perf/p5332-multi-pack-reuse.sh b/t/perf/p5332-multi-pack-reuse.sh index 5c6c575d62c64b..d1c89a8b7dbd5b 100755 --- a/t/perf/p5332-multi-pack-reuse.sh +++ b/t/perf/p5332-multi-pack-reuse.sh @@ -73,7 +73,7 @@ do " test_size "clone size for $nr_packs-pack scenario ($reuse-pack reuse)" ' - wc -c <result + test_file_size result ' done done diff --git a/t/perf/p6100-describe.sh b/t/perf/p6100-describe.sh new file mode 100755 index 00000000000000..069f91ce493a70 --- /dev/null +++ b/t/perf/p6100-describe.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='performance of git-describe' +. ./perf-lib.sh + +test_perf_default_repo + +# clear out old tags and give us a known state +test_expect_success 'set up tags' ' + git for-each-ref --format="delete %(refname)" refs/tags >to-delete && + git update-ref --stdin <to-delete && + new=$(git rev-list -1000 HEAD | tail -n 1) && + git tag -m new new $new && + old=$(git rev-list HEAD | tail -n 1) && + git tag -m old old $old +' + +test_perf 'describe HEAD' ' + git describe HEAD +' + +test_perf 'describe HEAD with one max candidate' ' + git describe --candidates=1 HEAD +' + +test_perf 'describe HEAD with one tag' ' + git describe --match=new HEAD +' + +test_done diff --git a/t/perf/p7527-builtin-fsmonitor.sh b/t/perf/p7527-builtin-fsmonitor.sh index c3f9a4caa4caad..90164327e82a01 100755 --- a/t/perf/p7527-builtin-fsmonitor.sh +++ b/t/perf/p7527-builtin-fsmonitor.sh @@ -95,7 +95,7 @@ test_expect_success "Setup borrowed repo (fsm+uc)" " # time is not useful. # # Create a temp branch and do all work relative to it so that we don't -# accidentially alter the real ballast branch. +# accidentally alter the real ballast branch. # test_expect_success "Setup borrowed repo (temp ballast branch)" " test_might_fail git -C $REPO checkout $BALLAST_BR && diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index ab0c7634119282..8ab6d9c469477a 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -282,7 +282,7 @@ test_perf_ () { # Run the performance test script specified in perf-test with # optional prerequisite and setup steps. # Options: -# --prereq prerequisites: Skip the test if prequisites aren't met +# --prereq prerequisites: Skip the test if prerequisites aren't met # --setup "setup-steps": Run setup steps prior to each measured iteration # test_perf () { @@ -309,7 +309,7 @@ test_size_ () { # prerequisites and setup steps. Returns the numeric value # returned by size-test. # Options: -# --prereq prerequisites: Skip the test if prequisites aren't met +# --prereq prerequisites: Skip the test if prerequisites aren't met # --setup "setup-steps": Run setup steps prior to the size measurement test_size () { diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 98b81e4d63fa4c..35c5c2b4f9beb4 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -684,7 +684,7 @@ test_expect_success 'subtest: tests respect lazy prerequisites' ' write_and_run_sub_test_lib_test lazy-prereqs <<-\EOF && test_lazy_prereq LAZY_TRUE true - test_expect_success LAZY_TRUE "lazy prereq is satisifed" "true" + test_expect_success LAZY_TRUE "lazy prereq is satisfied" "true" test_expect_success !LAZY_TRUE "negative lazy prereq" "false" test_lazy_prereq LAZY_FALSE false @@ -695,7 +695,7 @@ test_expect_success 'subtest: tests respect lazy prerequisites' ' EOF check_sub_test_lib_test lazy-prereqs <<-\EOF - ok 1 - lazy prereq is satisifed + ok 1 - lazy prereq is satisfied ok 2 # skip negative lazy prereq (missing !LAZY_TRUE) ok 3 # skip lazy prereq not satisfied (missing LAZY_FALSE) ok 4 - negative false prereq diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 0178aa62a41f16..c49d9e0d382990 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -2,7 +2,6 @@ test_description='git init' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_config () { @@ -434,6 +433,12 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' ' sep_git_dir_worktree () { test_when_finished "rm -rf mainwt linkwt seprepo" && git init mainwt && + if test "relative" = $2 + then + test_config -C mainwt worktree.useRelativePaths true + else + test_config -C mainwt worktree.useRelativePaths false + fi test_commit -C mainwt gumby && git -C mainwt worktree add --detach ../linkwt && git -C "$1" init --separate-git-dir ../seprepo && @@ -442,12 +447,20 @@ sep_git_dir_worktree () { test_cmp expect actual } -test_expect_success 're-init to move gitdir with linked worktrees' ' - sep_git_dir_worktree mainwt +test_expect_success 're-init to move gitdir with linked worktrees (absolute)' ' + sep_git_dir_worktree mainwt absolute +' + +test_expect_success 're-init to move gitdir within linked worktree (absolute)' ' + sep_git_dir_worktree linkwt absolute +' + +test_expect_success 're-init to move gitdir with linked worktrees (relative)' ' + sep_git_dir_worktree mainwt relative ' -test_expect_success 're-init to move gitdir within linked worktree' ' - sep_git_dir_worktree linkwt +test_expect_success 're-init to move gitdir within linked worktree (relative)' ' + sep_git_dir_worktree linkwt relative ' test_expect_success MINGW '.git hidden' ' @@ -573,6 +586,18 @@ test_expect_success 'GIT_DEFAULT_HASH overrides init.defaultObjectFormat' ' echo sha256 >expected ' +for hash in sha1 sha256 +do + test_expect_success "reinit repository with GIT_DEFAULT_HASH=$hash does not change format" ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo rev-parse --show-object-format >expect && + GIT_DEFAULT_HASH=$hash git init repo && + git -C repo rev-parse --show-object-format >actual && + test_cmp expect actual + ' +done + test_expect_success 'extensions.objectFormat is not allowed with repo version 0' ' test_when_finished "rm -rf explicit-v0" && git init --object-format=sha256 explicit-v0 && @@ -684,6 +709,15 @@ do git -C refformat rev-parse --show-ref-format >actual && test_cmp expect actual ' + + test_expect_success "reinit repository with GIT_DEFAULT_REF_FORMAT=$format does not change format" ' + test_when_finished "rm -rf refformat" && + git init refformat && + git -C refformat rev-parse --show-ref-format >expect && + GIT_DEFAULT_REF_FORMAT=$format git init refformat && + git -C refformat rev-parse --show-ref-format >actual && + test_cmp expect actual + ' done test_expect_success "--ref-format= overrides GIT_DEFAULT_REF_FORMAT" ' @@ -848,15 +882,6 @@ test_expect_success 're-init with includeIf.onbranch condition' ' test_cmp expect actual ' -test_expect_success 're-init with includeIf.onbranch condition' ' - test_when_finished "rm -rf repo" && - git init repo && - git -c includeIf.onbranch:nonexistent.path=/does/not/exist init repo && - echo $GIT_DEFAULT_REF_FORMAT >expect && - git -C repo rev-parse --show-ref-format >actual && - test_cmp expect actual -' - test_expect_success 're-init skips non-matching includeIf.onbranch' ' test_when_finished "rm -rf repo config" && cat >config <<-EOF && diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index bf3bf604abe347..dfbcdddbcc1f0f 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -7,7 +7,6 @@ Verify that plumbing commands work when .git is a file GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh objpath() { diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 66ccb5889d1e02..3c98b622f25b76 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -2,7 +2,6 @@ test_description=gitattributes -TEST_PASSES_SANITIZE_LEAK=true TEST_CREATE_REPO_NO_TEMPLATE=1 . ./test-lib.sh diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh index 8114fac73b320b..3bdafbae0f0038 100755 --- a/t/t0004-unwritable.sh +++ b/t/t0004-unwritable.sh @@ -2,7 +2,6 @@ test_description='detect unwritable repository and fail correctly' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0005-signals.sh b/t/t0005-signals.sh index eba75a2490ce7e..afba0fc3fc673e 100755 --- a/t/t0005-signals.sh +++ b/t/t0005-signals.sh @@ -2,7 +2,6 @@ test_description='signals work as we expect' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect <<EOF diff --git a/t/t0006-date.sh b/t/t0006-date.sh index fd373e1b391854..53ced36df448f1 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -2,7 +2,6 @@ test_description='test date parsing and printing' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # arbitrary reference time: 2009-08-30 19:20:00 diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh index 9fc5882387390a..2b60317758c415 100755 --- a/t/t0007-git-var.sh +++ b/t/t0007-git-var.sh @@ -2,7 +2,6 @@ test_description='basic sanity checks for git var' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sane_unset_all_editors () { diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 02a18d4fdbd244..c9376dffb58872 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -2,7 +2,6 @@ test_description=check-ignore -TEST_PASSES_SANITIZE_LEAK=true TEST_CREATE_REPO_NO_TEMPLATE=1 . ./test-lib.sh diff --git a/t/t0010-racy-git.sh b/t/t0010-racy-git.sh index 84172a3739094a..45229f57b821d7 100755 --- a/t/t0010-racy-git.sh +++ b/t/t0010-racy-git.sh @@ -2,7 +2,6 @@ test_description='racy GIT' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test can give false success if your machine is sufficiently diff --git a/t/t0012-help.sh b/t/t0012-help.sh index 1d273d91c2125a..d3a0967e9d0752 100755 --- a/t/t0012-help.sh +++ b/t/t0012-help.sh @@ -255,8 +255,9 @@ do ( GIT_CEILING_DIRECTORIES=$(pwd) && export GIT_CEILING_DIRECTORIES && - test_expect_code 129 git -C sub $builtin -h >output 2>&1 + test_expect_code 129 git -C sub $builtin -h >output 2>err ) && + test_must_be_empty err && test_grep usage output ' done <builtins diff --git a/t/t0013-sha1dc.sh b/t/t0013-sha1dc.sh index 08814173cb111c..ce3d81227a0f0c 100755 --- a/t/t0013-sha1dc.sh +++ b/t/t0013-sha1dc.sh @@ -2,7 +2,6 @@ test_description='test sha1 collision detection' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh TEST_DATA="$TEST_DIRECTORY/t0013" diff --git a/t/t0017-env-helper.sh b/t/t0017-env-helper.sh index f3a16859cc20f1..32fe8481792325 100755 --- a/t/t0017-env-helper.sh +++ b/t/t0017-env-helper.sh @@ -2,7 +2,6 @@ test_description='test test-tool env-helper' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t0018-advice.sh b/t/t0018-advice.sh index fac52322a7f673..f68e08d0b14ec9 100755 --- a/t/t0018-advice.sh +++ b/t/t0018-advice.sh @@ -5,13 +5,12 @@ test_description='Test advise_if_enabled functionality' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=trunk export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'advice should be printed when config variable is unset' ' cat >expect <<-\EOF && hint: This is a piece of advice - hint: Disable this message with "git config advice.nestedTag false" + hint: Disable this message with "git config set advice.nestedTag false" EOF test-tool advise "This is a piece of advice" 2>actual && test_cmp expect actual diff --git a/t/t0019-json-writer.sh b/t/t0019-json-writer.sh index 19a730c29ed8f7..3a4e1cc7e388ab 100755 --- a/t/t0019-json-writer.sh +++ b/t/t0019-json-writer.sh @@ -2,7 +2,6 @@ test_description='test json-writer JSON generation' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'unit test of json-writer routines' ' diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 81946e87ccb9b4..fd1cae09edcc26 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -5,7 +5,6 @@ test_description='CRLF conversion' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh has_cr() { diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index eeb2714d9d9204..3f6433d3045826 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -5,7 +5,6 @@ test_description='blob conversion via gitattributes' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -1116,11 +1115,11 @@ do test_delayed_checkout_progress test_terminal git checkout $opt ' - test_expect_success PERL "delayed checkout ommits progress on non-tty ($mode checkout)" ' + test_expect_success PERL "delayed checkout omits progress on non-tty ($mode checkout)" ' test_delayed_checkout_progress ! git checkout $opt ' - test_expect_success PERL,TTY "delayed checkout ommits progress with --quiet ($mode checkout)" ' + test_expect_success PERL,TTY "delayed checkout omits progress with --quiet ($mode checkout)" ' test_delayed_checkout_progress ! test_terminal git checkout --quiet $opt ' diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh index 9fe98912511d3b..9bd863a970d2b1 100755 --- a/t/t0022-crlf-rename.sh +++ b/t/t0022-crlf-rename.sh @@ -2,7 +2,6 @@ test_description='ignore CR in CRLF sequence while computing similiarity' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0023-crlf-am.sh b/t/t0023-crlf-am.sh index 575805513a3d7f..f9bbb91f64e35d 100755 --- a/t/t0023-crlf-am.sh +++ b/t/t0023-crlf-am.sh @@ -2,7 +2,6 @@ test_description='Test am with auto.crlf' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >patchfile <<\EOF diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh index a7f4de4a43ffa0..44958cb2c2d946 100755 --- a/t/t0024-crlf-archive.sh +++ b/t/t0024-crlf-archive.sh @@ -2,7 +2,6 @@ test_description='respect crlf in git archive' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0025-crlf-renormalize.sh b/t/t0025-crlf-renormalize.sh index f7202c192e7b63..2e28feb69c9fea 100755 --- a/t/t0025-crlf-renormalize.sh +++ b/t/t0025-crlf-renormalize.sh @@ -2,7 +2,6 @@ test_description='CRLF renormalization' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0026-eol-config.sh b/t/t0026-eol-config.sh index f426a185bb9b32..493b01a0e7c6a0 100755 --- a/t/t0026-eol-config.sh +++ b/t/t0026-eol-config.sh @@ -2,7 +2,6 @@ test_description='CRLF conversion' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh has_cr() { diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh index 2f57c8669cb5af..49dbf09da77386 100755 --- a/t/t0027-auto-crlf.sh +++ b/t/t0027-auto-crlf.sh @@ -2,7 +2,6 @@ test_description='CRLF conversion all combinations' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh compare_files () { diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh index ad151a346708a5..50b3b4649b614f 100755 --- a/t/t0028-working-tree-encoding.sh +++ b/t/t0028-working-tree-encoding.sh @@ -5,13 +5,18 @@ test_description='working-tree-encoding conversion via gitattributes' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true TEST_CREATE_REPO_NO_TEMPLATE=1 . ./test-lib.sh . "$TEST_DIRECTORY/lib-encoding.sh" GIT_TRACE_WORKING_TREE_ENCODING=1 && export GIT_TRACE_WORKING_TREE_ENCODING +if ! test_have_prereq ICONV +then + skip_all='skipping working tree encoding tests; iconv not available' + test_done +fi + test_expect_success 'setup test files' ' git config core.eol lf && diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh index 4e8e90dd9824b3..baa1b7e85b10b4 100755 --- a/t/t0029-core-unsetenvvars.sh +++ b/t/t0029-core-unsetenvvars.sh @@ -2,7 +2,6 @@ test_description='test the Windows-only core.unsetenvvars setting' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq MINGW diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh index f10f42ff1e4a87..43155f6bd86bf4 100755 --- a/t/t0030-stripspace.sh +++ b/t/t0030-stripspace.sh @@ -5,7 +5,6 @@ test_description='git stripspace' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh t40='A quick brown fox jumps over the lazy do' diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh index e97a84764f7867..e103fe710927ce 100755 --- a/t/t0033-safe-directory.sh +++ b/t/t0033-safe-directory.sh @@ -2,7 +2,6 @@ test_description='verify safe.directory checks' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_TEST_ASSUME_DIFFERENT_OWNER=1 diff --git a/t/t0035-safe-bare-repository.sh b/t/t0035-safe-bare-repository.sh index d3cb2a1cb9edb8..ae7ef092abf6d9 100755 --- a/t/t0035-safe-bare-repository.sh +++ b/t/t0035-safe-bare-repository.sh @@ -2,7 +2,6 @@ test_description='verify safe.bareRepository checks' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pwd="$(pwd)" diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 45a773642fd167..2fe3522305f64d 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -5,7 +5,6 @@ test_description='our own option parser' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect <<\EOF diff --git a/t/t0041-usage.sh b/t/t0041-usage.sh index 1464294bd1bfc3..a0f6f134c71822 100755 --- a/t/t0041-usage.sh +++ b/t/t0041-usage.sh @@ -5,7 +5,6 @@ test_description='Test commands behavior when given invalid argument value' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ' ' diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh index 325eb1c3cd0add..5c9dc90d0b096d 100755 --- a/t/t0050-filesystem.sh +++ b/t/t0050-filesystem.sh @@ -5,7 +5,6 @@ test_description='Various filesystem issues' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh auml=$(printf '\303\244') diff --git a/t/t0052-simple-ipc.sh b/t/t0052-simple-ipc.sh index 1a36a535743c14..ff98be31a51b36 100755 --- a/t/t0052-simple-ipc.sh +++ b/t/t0052-simple-ipc.sh @@ -2,7 +2,6 @@ test_description='simple command server' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test-tool simple-ipc SUPPORTS_SIMPLE_IPC || { diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh index c3eb1158ef9ae2..d0740038b8778e 100755 --- a/t/t0055-beyond-symlinks.sh +++ b/t/t0055-beyond-symlinks.sh @@ -2,7 +2,6 @@ test_description='update-index and add refuse to add beyond symlinks' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success SYMLINKS setup ' diff --git a/t/t0056-git-C.sh b/t/t0056-git-C.sh index 752aa8c945431b..2630e756dab732 100755 --- a/t/t0056-git-C.sh +++ b/t/t0056-git-C.sh @@ -2,7 +2,6 @@ test_description='"-C <path>" option and its effects on other path-related options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success '"git -C <path>" runs git from the directory <path>' ' diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 0afa3d0d312ca6..8545cdfab559b4 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -5,7 +5,6 @@ test_description='Test various path utilities' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh norm_path() { @@ -593,17 +592,19 @@ test_lazy_prereq CAN_EXEC_IN_PWD ' ./git rev-parse ' +test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'setup runtime prefix' ' + mkdir -p pretend/bin && + cp "$GIT_EXEC_PATH"/git$X pretend/bin/ +' + test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' - mkdir -p pretend/bin pretend/libexec/git-core && + mkdir -p pretend/libexec/git-core && echo "echo HERE" | write_script pretend/libexec/git-core/git-here && - cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && GIT_EXEC_PATH= ./pretend/bin/git here >actual && echo HERE >expect && test_cmp expect actual' test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' ' - mkdir -p pretend/bin && - cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && git config yes.path "%(prefix)/yes" && GIT_EXEC_PATH= ./pretend/bin/git config --path yes.path >actual && echo "$(pwd)/pretend/yes" >expect && diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 20986b693cfbe8..76d4936a879afd 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -5,7 +5,6 @@ test_description='Test run command' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >hello-script <<-EOF diff --git a/t/t0062-revision-walking.sh b/t/t0062-revision-walking.sh index b9480c8178193e..8e215867b8c197 100755 --- a/t/t0062-revision-walking.sh +++ b/t/t0062-revision-walking.sh @@ -5,7 +5,6 @@ test_description='Test revision walking api' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >run_twice_expected <<-EOF diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh index 1fee6d90102cc6..aac63ba5064b78 100755 --- a/t/t0063-string-list.sh +++ b/t/t0063-string-list.sh @@ -5,7 +5,6 @@ test_description='Test string list functionality' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_split () { diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh index 7d0a0da8c01b8b..df3e9f5fa5d4b5 100755 --- a/t/t0066-dir-iterator.sh +++ b/t/t0066-dir-iterator.sh @@ -2,7 +2,6 @@ test_description='Test the dir-iterator functionality' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t0067-parse_pathspec_file.sh b/t/t0067-parse_pathspec_file.sh index 0188d0423a0aa2..7bab49f361a9bf 100755 --- a/t/t0067-parse_pathspec_file.sh +++ b/t/t0067-parse_pathspec_file.sh @@ -2,7 +2,6 @@ test_description='Test parse_pathspec_file()' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'one item from stdin' ' diff --git a/t/t0068-for-each-repo.sh b/t/t0068-for-each-repo.sh index 95019e01ed3328..f2f3e500312916 100755 --- a/t/t0068-for-each-repo.sh +++ b/t/t0068-for-each-repo.sh @@ -2,7 +2,6 @@ test_description='git for-each-repo builtin' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'run based on configured value' ' diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh index 0ecec2ba711169..6b9dcf984bcb54 100755 --- a/t/t0070-fundamental.sh +++ b/t/t0070-fundamental.sh @@ -6,7 +6,6 @@ test_description='check that the most basic functions work Verify wrappers and compatibility functions. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'mktemp to nonexistent directory prints filename' ' diff --git a/t/t0071-sort.sh b/t/t0071-sort.sh index ba8ad1d1ca0ade..2236a7e9563ab1 100755 --- a/t/t0071-sort.sh +++ b/t/t0071-sort.sh @@ -2,7 +2,6 @@ test_description='verify sort functions' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'DEFINE_LIST_SORT_DEBUG' ' diff --git a/t/t0080-unit-test-output.sh b/t/t0080-unit-test-output.sh index 3c369c88e2a416..3db10f095c2edc 100755 --- a/t/t0080-unit-test-output.sh +++ b/t/t0080-unit-test-output.sh @@ -2,7 +2,6 @@ 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' - <<\EOT diff --git a/t/t0081-find-pack.sh b/t/t0081-find-pack.sh index 67b11216a3e541..5a628bf7356445 100755 --- a/t/t0081-find-pack.sh +++ b/t/t0081-find-pack.sh @@ -2,7 +2,6 @@ test_description='test `test-tool find-pack`' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh index d8e2fc42e15c73..ab80c9ef1358f0 100755 --- a/t/t0090-cache-tree.sh +++ b/t/t0090-cache-tree.sh @@ -6,7 +6,6 @@ Tests whether various commands properly update and/or rewrite the cache-tree extension. " -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cmp_cache_tree () { diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh index fca39048fe8840..e38ca7a9018751 100755 --- a/t/t0091-bugreport.sh +++ b/t/t0091-bugreport.sh @@ -2,7 +2,6 @@ test_description='git bugreport' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create a report' ' @@ -48,7 +47,8 @@ test_expect_success 'sanity check "System Info" section' ' # This is bound to differ from environment to environment, # so we just do some rather high-level checks. grep "uname: ." system && - grep "compiler info: ." system + grep "compiler info: ." system && + grep "zlib." system ' test_expect_success 'dies if file with same name as report already exists' ' diff --git a/t/t0092-diagnose.sh b/t/t0092-diagnose.sh index 133e5747d613e5..6cabd6e67b9a14 100755 --- a/t/t0092-diagnose.sh +++ b/t/t0092-diagnose.sh @@ -2,7 +2,6 @@ test_description='git diagnose' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success UNZIP 'creates diagnostics zip archive' ' diff --git a/t/t0095-bloom.sh b/t/t0095-bloom.sh index c8d84ab6061a9d..8f0c3b7325b8bd 100755 --- a/t/t0095-bloom.sh +++ b/t/t0095-bloom.sh @@ -2,7 +2,6 @@ test_description='Testing the various Bloom filter computations in bloom.c' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'compute unseeded murmur3 hash for empty string' ' @@ -77,7 +76,7 @@ test_expect_success 'compute bloom key for test string 2' ' test_cmp expect actual ' -test_expect_success !SANITIZE_LEAK 'get bloom filters for commit with no changes' ' +test_expect_success 'get bloom filters for commit with no changes' ' git init && git commit --allow-empty -m "c0" && cat >expect <<-\EOF && diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh index 70a3223f2199b0..dd5d9b4e5ebdf2 100755 --- a/t/t0100-previous.sh +++ b/t/t0100-previous.sh @@ -5,7 +5,6 @@ test_description='previous branch syntax @{-n}' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'branch -d @{-1}' ' diff --git a/t/t0101-at-syntax.sh b/t/t0101-at-syntax.sh index 878aadd64c9517..023b4c6f0b3a0c 100755 --- a/t/t0101-at-syntax.sh +++ b/t/t0101-at-syntax.sh @@ -2,7 +2,6 @@ test_description='various @{whatever} syntax tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t0200-gettext-basic.sh b/t/t0200-gettext-basic.sh index 522fb2ae696da9..8853d8afb923e6 100755 --- a/t/t0200-gettext-basic.sh +++ b/t/t0200-gettext-basic.sh @@ -5,7 +5,6 @@ test_description='Gettext support for Git' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success "sanity: \$GIT_INTERNAL_GETTEXT_SH_SCHEME is set (to $GIT_INTERNAL_GETTEXT_SH_SCHEME)" ' diff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh index 8724ce1052ddbf..6c74df0dc67e57 100755 --- a/t/t0201-gettext-fallbacks.sh +++ b/t/t0201-gettext-fallbacks.sh @@ -8,7 +8,6 @@ test_description='Gettext Shell fallbacks' GIT_INTERNAL_GETTEXT_TEST_FALLBACKS=YesPlease export GIT_INTERNAL_GETTEXT_TEST_FALLBACKS -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success "sanity: \$GIT_INTERNAL_GETTEXT_SH_SCHEME is set (to $GIT_INTERNAL_GETTEXT_SH_SCHEME)" ' diff --git a/t/t0202-gettext-perl.sh b/t/t0202-gettext-perl.sh index 5a6f28051bd275..b15cb65d5d7900 100755 --- a/t/t0202-gettext-perl.sh +++ b/t/t0202-gettext-perl.sh @@ -5,7 +5,6 @@ test_description='Perl gettext interface (Git::I18N)' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh . "$TEST_DIRECTORY"/lib-perl.sh skip_all_if_no_Test_More diff --git a/t/t0202/test.pl b/t/t0202/test.pl index 47d96a2a13f93b..5085a0eda519bb 100755 --- a/t/t0202/test.pl +++ b/t/t0202/test.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -use 5.008001; +require v5.26; use lib (split(/:/, $ENV{GITPERLLIB})); use strict; use warnings; diff --git a/t/t0203-gettext-setlocale-sanity.sh b/t/t0203-gettext-setlocale-sanity.sh index 86cff324ff1811..0ce1f22eff6628 100755 --- a/t/t0203-gettext-setlocale-sanity.sh +++ b/t/t0203-gettext-setlocale-sanity.sh @@ -5,7 +5,6 @@ test_description="The Git C functions aren't broken by setlocale(3)" -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success 'git show a ISO-8859-1 commit under C locale' ' diff --git a/t/t0204-gettext-reencode-sanity.sh b/t/t0204-gettext-reencode-sanity.sh index 310a4500125f4a..28d92bb9b7cade 100755 --- a/t/t0204-gettext-reencode-sanity.sh +++ b/t/t0204-gettext-reencode-sanity.sh @@ -5,7 +5,6 @@ test_description="Gettext reencoding of our *.po/*.mo files works" -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh # The constants used in a tricky observation for undefined behaviour diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh index b9adc94aab4165..4287ed3fbb3d41 100755 --- a/t/t0210-trace2-normal.sh +++ b/t/t0210-trace2-normal.sh @@ -2,7 +2,6 @@ test_description='test trace2 facility (normal target)' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Turn off any inherited trace2 settings for this test. @@ -244,6 +243,15 @@ test_expect_success 'bug messages followed by BUG() are written to trace2' ' test_cmp expect actual ' +test_expect_success 'a valueless true configuration variable is handled' ' + test_when_finished "rm -f trace2.normal actual expect" && + echo >expect && + GIT_TRACE2="$(pwd)/trace2.normal" \ + GIT_TRACE2_CONFIG_PARAMS=foo.true \ + git -c foo.true config foo.true >actual && + test_cmp expect actual +' + sane_unset GIT_TRACE2_BRIEF # Now test without environment variables and get all Trace2 settings diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index dddc130560ba61..bac90465406d94 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -2,7 +2,6 @@ test_description='test trace2 facility (perf target)' -TEST_PASSES_SANITIZE_LEAK=false . ./test-lib.sh # Turn off any inherited trace2 settings for this test. diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh index 147643d582643e..1211db9f468717 100755 --- a/t/t0212-trace2-event.sh +++ b/t/t0212-trace2-event.sh @@ -2,7 +2,6 @@ test_description='test trace2 facility' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Turn off any inherited trace2 settings for this test. diff --git a/t/t0212/parse_events.perl b/t/t0212/parse_events.perl index 30a9f51e9f1ecc..7146476c69fe44 100644 --- a/t/t0212/parse_events.perl +++ b/t/t0212/parse_events.perl @@ -204,7 +204,7 @@ } # A series of potentially nested and threaded region and data events - # is fundamentally incompatibile with the type of summary record we + # is fundamentally incompatible with the type of summary record we # are building in this script. Since they are intended for # perf-trace-like analysis rather than a result summary, we ignore # most of them here. diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh index 6a76b7fdbd4557..cb3a85c7ff1bcc 100755 --- a/t/t0300-credentials.sh +++ b/t/t0300-credentials.sh @@ -2,7 +2,6 @@ test_description='basic credential helper tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-credential.sh @@ -77,6 +76,10 @@ test_expect_success 'setup helper scripts' ' test -z "$pexpiry" || echo password_expiry_utc=$pexpiry EOF + write_script git-credential-cntrl-in-username <<-\EOF && + printf "username=\\007latrix Lestrange\\n" + EOF + PATH="$PWD:$PATH" ' @@ -697,6 +700,19 @@ test_expect_success 'match percent-encoded values in username' ' EOF ' +test_expect_success 'match percent-encoded values in hostname' ' + test_config "credential.https://a%20b%20c/.helper" "$HELPER" && + check fill <<-\EOF + url=https://a b c/ + -- + protocol=https + host=a b c + username=foo + password=bar + -- + EOF +' + test_expect_success 'fetch with multiple path components' ' test_unconfig credential.helper && test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" && @@ -886,6 +902,22 @@ test_expect_success 'url parser rejects embedded newlines' ' test_cmp expect stderr ' +test_expect_success 'url parser rejects embedded carriage returns' ' + test_config credential.helper "!true" && + test_must_fail git credential fill 2>stderr <<-\EOF && + url=https://example%0d.com/ + EOF + cat >expect <<-\EOF && + fatal: credential value for host contains carriage return + If this is intended, set `credential.protectProtocol=false` + EOF + test_cmp expect stderr && + GIT_ASKPASS=true \ + git -c credential.protectProtocol=false credential fill <<-\EOF + url=https://example%0d.com/ + EOF +' + test_expect_success 'host-less URLs are parsed as empty host' ' check fill "verbatim foo bar" <<-\EOF url=cert:///path/to/cert.pem @@ -995,4 +1027,20 @@ test_expect_success 'credential config with partial URLs' ' test_grep "skipping credential lookup for key" stderr ' +BEL="$(printf '\007')" + +test_expect_success 'interactive prompt is sanitized' ' + check fill cntrl-in-username <<-EOF + protocol=https + host=example.org + -- + protocol=https + host=example.org + username=${BEL}latrix Lestrange + password=askpass-password + -- + askpass: Password for ${SQ}https://%07latrix%20Lestrange@example.org${SQ}: + EOF +' + test_done diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh index 5d5b64205ffe35..dc30289f7539ee 100755 --- a/t/t0301-credential-cache.sh +++ b/t/t0301-credential-cache.sh @@ -2,7 +2,6 @@ test_description='credential-cache tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-credential.sh diff --git a/t/t0302-credential-store.sh b/t/t0302-credential-store.sh index f83db659e25814..c1cd60edd019a0 100755 --- a/t/t0302-credential-store.sh +++ b/t/t0302-credential-store.sh @@ -2,7 +2,6 @@ test_description='credential-store tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-credential.sh diff --git a/t/t0303-credential-external.sh b/t/t0303-credential-external.sh index 8aadbe86c45856..72ae405c3ed979 100755 --- a/t/t0303-credential-external.sh +++ b/t/t0303-credential-external.sh @@ -29,7 +29,6 @@ you can set GIT_TEST_CREDENTIAL_HELPER_SETUP to a sequence of shell commands. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-credential.sh diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index 34bdb3ab1f23b7..2a5bdbeeb87f6e 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -240,7 +240,7 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled' grep "fetch< fetch=.*ref-in-want" trace ' -test_expect_success 'fetching of missing objects from another promisor remote' ' +test_expect_success 'fetching from another promisor remote' ' git clone "file://$(pwd)/server" server2 && test_commit -C server2 bar && git -C server2 repack -a -d --write-bitmap-index && @@ -263,8 +263,8 @@ test_expect_success 'fetching of missing objects from another promisor remote' ' grep "$HASH2" out ' -test_expect_success 'fetching of missing objects configures a promisor remote' ' - git clone "file://$(pwd)/server" server3 && +test_expect_success 'fetching with --filter configures a promisor remote' ' + test_create_repo server3 && test_commit -C server3 baz && git -C server3 repack -a -d --write-bitmap-index && HASH3=$(git -C server3 rev-parse baz) && diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh index 932bf2067daaeb..196fc617843cb9 100755 --- a/t/t0411-clone-from-partial.sh +++ b/t/t0411-clone-from-partial.sh @@ -2,7 +2,6 @@ test_description='check that local clone does not fetch from promisor remotes' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create evil repo' ' @@ -29,7 +28,6 @@ test_expect_success 'local clone must not fetch from promisor remote and execute test_must_fail git clone \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ evil clone1 2>err && - test_grep "detected dubious ownership" err && test_grep ! "fake-upload-pack running" err && test_path_is_missing script-executed ' @@ -39,7 +37,6 @@ test_expect_success 'clone from file://... must not fetch from promisor remote a test_must_fail git clone \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ "file://$(pwd)/evil" clone2 2>err && - test_grep "detected dubious ownership" err && test_grep ! "fake-upload-pack running" err && test_path_is_missing script-executed ' @@ -49,7 +46,6 @@ test_expect_success 'fetch from file://... must not fetch from promisor remote a test_must_fail git fetch \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ "file://$(pwd)/evil" 2>err && - test_grep "detected dubious ownership" err && test_grep ! "fake-upload-pack running" err && test_path_is_missing script-executed ' diff --git a/t/t0450-txt-doc-vs-help.sh b/t/t0450-txt-doc-vs-help.sh index 69917d7b8459c6..2f7504ae7e9090 100755 --- a/t/t0450-txt-doc-vs-help.sh +++ b/t/t0450-txt-doc-vs-help.sh @@ -1,22 +1,21 @@ #!/bin/sh -test_description='assert (unbuilt) Documentation/*.txt and -h output +test_description='assert (unbuilt) Documentation/*.adoc and -h output Run this with --debug to see a summary of where we still fail to make the two versions consistent with one another.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: list of builtins' ' git --list-cmds=builtins >builtins ' -test_expect_success 'list of txt and help mismatches is sorted' ' - sort -u "$TEST_DIRECTORY"/t0450/txt-help-mismatches >expect && - if ! test_cmp expect "$TEST_DIRECTORY"/t0450/txt-help-mismatches +test_expect_success 'list of adoc and help mismatches is sorted' ' + sort -u "$TEST_DIRECTORY"/t0450/adoc-help-mismatches >expect && + if ! test_cmp expect "$TEST_DIRECTORY"/t0450/adoc-help-mismatches then - BUG "please keep the list of txt and help mismatches sorted" + BUG "please keep the list of adoc and help mismatches sorted" fi ' @@ -41,29 +40,26 @@ help_to_synopsis () { echo "$out" } -builtin_to_txt () { - echo "$GIT_BUILD_DIR/Documentation/git-$1.txt" +builtin_to_adoc () { + echo "$GIT_BUILD_DIR/Documentation/git-$1.adoc" } -txt_to_synopsis () { +adoc_to_synopsis () { builtin="$1" && out_dir="out/$builtin" && - out="$out_dir/txt.synopsis" && + out="$out_dir/adoc.synopsis" && if test -f "$out" then echo "$out" && return 0 fi && - b2t="$(builtin_to_txt "$builtin")" && + b2t="$(builtin_to_adoc "$builtin")" && sed -n \ - -e '/^\[verse\]$/,/^$/ { + -E '/^\[(verse|synopsis)\]$/,/^$/ { /^$/d; - /^\[verse\]$/d; - s/_//g; - s/++//g; - s/`//g; - s/{litdd}/--/g; - s/'\''\(git[ a-z-]*\)'\''/\1/g; + /^\[(verse|synopsis)\]$/d; + s/\{litdd\}/--/g; + s/'\''(git[ a-z-]*)'\''/\1/g; p; }' \ @@ -113,29 +109,29 @@ do fi ' - txt="$(builtin_to_txt "$builtin")" && - preq="$(echo BUILTIN_TXT_$builtin | tr '[:lower:]-' '[:upper:]_')" && + adoc="$(builtin_to_adoc "$builtin")" && + preq="$(echo BUILTIN_ADOC_$builtin | tr '[:lower:]-' '[:upper:]_')" && - if test -f "$txt" + if test -f "$adoc" then test_set_prereq "$preq" fi && - # *.txt output assertions - test_expect_success "$preq" "$builtin *.txt SYNOPSIS has dashed labels" ' - check_dashed_labels "$(txt_to_synopsis "$builtin")" + # *.adoc output assertions + test_expect_success "$preq" "$builtin *.adoc SYNOPSIS has dashed labels" ' + check_dashed_labels "$(adoc_to_synopsis "$builtin")" ' - # *.txt output consistency assertions + # *.adoc output consistency assertions result= - if grep -q "^$builtin$" "$TEST_DIRECTORY"/t0450/txt-help-mismatches + if grep -q "^$builtin$" "$TEST_DIRECTORY"/t0450/adoc-help-mismatches then result=failure else result=success fi && test_expect_$result "$preq" "$builtin -h output and SYNOPSIS agree" ' - t2s="$(txt_to_synopsis "$builtin")" && + t2s="$(adoc_to_synopsis "$builtin")" && if test "$builtin" = "merge-tree" then test_when_finished "rm -f t2s.new" && @@ -144,17 +140,17 @@ do fi && h2s="$(help_to_synopsis "$builtin")" && - # The *.txt and -h use different spacing for the + # The *.adoc and -h use different spacing for the # alignment of continued usage output, normalize it. - align_after_nl "$builtin" <"$t2s" >txt && + align_after_nl "$builtin" <"$t2s" >adoc && align_after_nl "$builtin" <"$h2s" >help && - test_cmp txt help + test_cmp adoc help ' - if test_have_prereq "$preq" && test -e txt && test -e help + if test_have_prereq "$preq" && test -e adoc && test -e help then test_debug ' - if test_cmp txt help >cmp 2>/dev/null + if test_cmp adoc help >cmp 2>/dev/null then echo "=== DONE: $builtin ===" else @@ -165,7 +161,7 @@ do # Not in test_expect_success in case --run is being # used with --debug - rm -f txt help tmp 2>/dev/null + rm -f adoc help tmp 2>/dev/null fi done <builtins diff --git a/t/t0450/txt-help-mismatches b/t/t0450/adoc-help-mismatches similarity index 98% rename from t/t0450/txt-help-mismatches rename to t/t0450/adoc-help-mismatches index 28003f18c924bb..c4a15fd0cb885a 100644 --- a/t/t0450/txt-help-mismatches +++ b/t/t0450/adoc-help-mismatches @@ -45,7 +45,6 @@ rebase remote remote-ext remote-fd -repack reset restore rev-parse diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh index 1eb3a8306ba15b..d1a498a216fb52 100755 --- a/t/t0500-progress-display.sh +++ b/t/t0500-progress-display.sh @@ -2,7 +2,6 @@ test_description='progress display' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh show_cr () { diff --git a/t/t0600-reffiles-backend.sh b/t/t0600-reffiles-backend.sh index 20df336cc37486..1e62c791d97250 100755 --- a/t/t0600-reffiles-backend.sh +++ b/t/t0600-reffiles-backend.sh @@ -7,7 +7,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_DEFAULT_REF_FORMAT=files export GIT_TEST_DEFAULT_REF_FORMAT -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -271,7 +270,7 @@ test_expect_success 'setup worktree' ' # 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 +# multiple reasons: 1) it creates invalidly formatted log entries. 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()' ' diff --git a/t/t0601-reffiles-pack-refs.sh b/t/t0601-reffiles-pack-refs.sh index d8cbd3f202b5f0..aa7f6ecd813c44 100755 --- a/t/t0601-reffiles-pack-refs.sh +++ b/t/t0601-reffiles-pack-refs.sh @@ -15,7 +15,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_DEFAULT_REF_FORMAT=files export GIT_TEST_DEFAULT_REF_FORMAT -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'enable reflogs' ' diff --git a/t/t0602-reffiles-fsck.sh b/t/t0602-reffiles-fsck.sh index 71a4d1a5ae4bab..d4a08b823b7db7 100755 --- a/t/t0602-reffiles-fsck.sh +++ b/t/t0602-reffiles-fsck.sh @@ -6,7 +6,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_DEFAULT_REF_FORMAT=files export GIT_TEST_DEFAULT_REF_FORMAT -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh @@ -17,76 +16,584 @@ test_expect_success 'ref name should be checked' ' tag_dir_prefix=.git/refs/tags && cd repo && + git commit --allow-empty -m initial && + git checkout -b default-branch && + git tag default-tag && + git tag multi_hierarchy/default-tag && + + cp $branch_dir_prefix/default-branch $branch_dir_prefix/@ && + git refs verify 2>err && + test_must_be_empty err && + rm $branch_dir_prefix/@ && + + cp $tag_dir_prefix/default-tag $tag_dir_prefix/tag-1.lock && + git refs verify 2>err && + rm $tag_dir_prefix/tag-1.lock && + test_must_be_empty err && + + cp $tag_dir_prefix/default-tag $tag_dir_prefix/.lock && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/.lock: badRefName: invalid refname format + EOF + rm $tag_dir_prefix/.lock && + test_cmp expect err && + + for refname in ".refname-starts-with-dot" "~refname-has-stride" + do + cp $branch_dir_prefix/default-branch "$branch_dir_prefix/$refname" && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/$refname: badRefName: invalid refname format + EOF + rm "$branch_dir_prefix/$refname" && + test_cmp expect err || return 1 + done && + + for refname in ".refname-starts-with-dot" "~refname-has-stride" + do + cp $tag_dir_prefix/default-tag "$tag_dir_prefix/$refname" && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/$refname: badRefName: invalid refname format + EOF + rm "$tag_dir_prefix/$refname" && + test_cmp expect err || return 1 + done && + + for refname in ".refname-starts-with-dot" "~refname-has-stride" + do + cp $tag_dir_prefix/multi_hierarchy/default-tag "$tag_dir_prefix/multi_hierarchy/$refname" && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/tags/multi_hierarchy/$refname: badRefName: invalid refname format + EOF + rm "$tag_dir_prefix/multi_hierarchy/$refname" && + test_cmp expect err || return 1 + done && + + for refname in ".refname-starts-with-dot" "~refname-has-stride" + do + mkdir "$branch_dir_prefix/$refname" && + cp $branch_dir_prefix/default-branch "$branch_dir_prefix/$refname/default-branch" && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/$refname/default-branch: badRefName: invalid refname format + EOF + rm -r "$branch_dir_prefix/$refname" && + test_cmp expect err || return 1 + done +' + +test_expect_success 'ref name check should be adapted into fsck messages' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + cd repo && git commit --allow-empty -m initial && git checkout -b branch-1 && - git tag tag-1 && - git commit --allow-empty -m second && - git checkout -b branch-2 && - git tag tag-2 && - git tag multi_hierarchy/tag-2 && cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 && - test_must_fail git refs verify 2>err && + git -c fsck.badRefName=warn refs verify 2>err && cat >expect <<-EOF && - error: refs/heads/.branch-1: badRefName: invalid refname format + warning: refs/heads/.branch-1: badRefName: invalid refname format EOF rm $branch_dir_prefix/.branch-1 && test_cmp expect err && - cp $branch_dir_prefix/branch-1 $branch_dir_prefix/@ && + cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 && + git -c fsck.badRefName=ignore refs verify 2>err && + test_must_be_empty err +' + +test_expect_success 'ref name check should work for multiple worktrees' ' + test_when_finished "rm -rf repo" && + git init repo && + + cd repo && + test_commit initial && + git checkout -b branch-1 && + test_commit second && + git checkout -b branch-2 && + test_commit third && + git checkout -b branch-3 && + git worktree add ./worktree-1 branch-1 && + git worktree add ./worktree-2 branch-2 && + worktree1_refdir_prefix=.git/worktrees/worktree-1/refs/worktree && + worktree2_refdir_prefix=.git/worktrees/worktree-2/refs/worktree && + + ( + cd worktree-1 && + git update-ref refs/worktree/branch-4 refs/heads/branch-3 + ) && + ( + cd worktree-2 && + git update-ref refs/worktree/branch-4 refs/heads/branch-3 + ) && + + cp $worktree1_refdir_prefix/branch-4 $worktree1_refdir_prefix/'\'' branch-5'\'' && + cp $worktree2_refdir_prefix/branch-4 $worktree2_refdir_prefix/'\''~branch-6'\'' && + test_must_fail git refs verify 2>err && cat >expect <<-EOF && - error: refs/heads/@: badRefName: invalid refname format + error: worktrees/worktree-1/refs/worktree/ branch-5: badRefName: invalid refname format + error: worktrees/worktree-2/refs/worktree/~branch-6: badRefName: invalid refname format EOF - rm $branch_dir_prefix/@ && + sort err >sorted_err && + test_cmp expect sorted_err && + + for worktree in "worktree-1" "worktree-2" + do + ( + cd $worktree && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: worktrees/worktree-1/refs/worktree/ branch-5: badRefName: invalid refname format + error: worktrees/worktree-2/refs/worktree/~branch-6: badRefName: invalid refname format + EOF + sort err >sorted_err && + test_cmp expect sorted_err || return 1 + ) + done +' + +test_expect_success 'regular ref content should be checked (individual)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + git refs verify 2>err && + test_must_be_empty err && + + for bad_content in "$(git rev-parse main)x" "xfsazqfxcadas" "Xfsazqfxcadas" + do + printf "%s" $bad_content >$branch_dir_prefix/branch-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-bad: badRefContent: $bad_content + EOF + rm $branch_dir_prefix/branch-bad && + test_cmp expect err || return 1 + done && + + for bad_content in "$(git rev-parse main)x" "xfsazqfxcadas" "Xfsazqfxcadas" + do + printf "%s" $bad_content >$branch_dir_prefix/a/b/branch-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/a/b/branch-bad: badRefContent: $bad_content + EOF + rm $branch_dir_prefix/a/b/branch-bad && + test_cmp expect err || return 1 + done && + + printf "%s" "$(git rev-parse main)" >$branch_dir_prefix/branch-no-newline && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-no-newline: refMissingNewline: misses LF at the end + EOF + rm $branch_dir_prefix/branch-no-newline && test_cmp expect err && - cp $tag_dir_prefix/multi_hierarchy/tag-2 $tag_dir_prefix/multi_hierarchy/@ && - test_must_fail git refs verify 2>err && + for trailing_content in " garbage" " more garbage" + do + printf "%s" "$(git rev-parse main)$trailing_content" >$branch_dir_prefix/branch-garbage && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-garbage: trailingRefContent: has trailing garbage: '\''$trailing_content'\'' + EOF + rm $branch_dir_prefix/branch-garbage && + test_cmp expect err || return 1 + done && + + printf "%s\n\n\n" "$(git rev-parse main)" >$branch_dir_prefix/branch-garbage-special && + git refs verify 2>err && cat >expect <<-EOF && - error: refs/tags/multi_hierarchy/@: badRefName: invalid refname format + warning: refs/heads/branch-garbage-special: trailingRefContent: has trailing garbage: '\'' + + + '\'' EOF - rm $tag_dir_prefix/multi_hierarchy/@ && + rm $branch_dir_prefix/branch-garbage-special && test_cmp expect err && - cp $tag_dir_prefix/tag-1 $tag_dir_prefix/tag-1.lock && + printf "%s\n\n\n garbage" "$(git rev-parse main)" >$branch_dir_prefix/branch-garbage-special && git refs verify 2>err && - rm $tag_dir_prefix/tag-1.lock && - test_must_be_empty err && + cat >expect <<-EOF && + warning: refs/heads/branch-garbage-special: trailingRefContent: has trailing garbage: '\'' + + + garbage'\'' + EOF + rm $branch_dir_prefix/branch-garbage-special && + test_cmp expect err +' + +test_expect_success 'regular ref content should be checked (aggregate)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + bad_content_1=$(git rev-parse main)x && + bad_content_2=xfsazqfxcadas && + bad_content_3=Xfsazqfxcadas && + printf "%s" $bad_content_1 >$tag_dir_prefix/tag-bad-1 && + printf "%s" $bad_content_2 >$tag_dir_prefix/tag-bad-2 && + printf "%s" $bad_content_3 >$branch_dir_prefix/a/b/branch-bad && + printf "%s" "$(git rev-parse main)" >$branch_dir_prefix/branch-no-newline && + printf "%s garbage" "$(git rev-parse main)" >$branch_dir_prefix/branch-garbage && - cp $tag_dir_prefix/tag-1 $tag_dir_prefix/.lock && test_must_fail git refs verify 2>err && cat >expect <<-EOF && - error: refs/tags/.lock: badRefName: invalid refname format + error: refs/heads/a/b/branch-bad: badRefContent: $bad_content_3 + error: refs/tags/tag-bad-1: badRefContent: $bad_content_1 + error: refs/tags/tag-bad-2: badRefContent: $bad_content_2 + warning: refs/heads/branch-garbage: trailingRefContent: has trailing garbage: '\'' garbage'\'' + warning: refs/heads/branch-no-newline: refMissingNewline: misses LF at the end EOF - rm $tag_dir_prefix/.lock && + sort err >sorted_err && + test_cmp expect sorted_err +' + +test_expect_success 'textual symref content should be checked (individual)' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + for good_referent in "refs/heads/branch" "HEAD" + do + printf "ref: %s\n" $good_referent >$branch_dir_prefix/branch-good && + git refs verify 2>err && + rm $branch_dir_prefix/branch-good && + test_must_be_empty err || return 1 + done && + + for bad_referent in "refs/heads/.branch" "refs/heads/~branch" "refs/heads/?branch" + do + printf "ref: %s\n" $bad_referent >$branch_dir_prefix/branch-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: refs/heads/branch-bad: badReferentName: points to invalid refname '\''$bad_referent'\'' + EOF + rm $branch_dir_prefix/branch-bad && + test_cmp expect err || return 1 + done && + + printf "ref: refs/heads/branch" >$branch_dir_prefix/branch-no-newline && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-no-newline: refMissingNewline: misses LF at the end + EOF + rm $branch_dir_prefix/branch-no-newline && + test_cmp expect err && + + printf "ref: refs/heads/branch " >$branch_dir_prefix/a/b/branch-trailing-1 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-trailing-1: refMissingNewline: misses LF at the end + warning: refs/heads/a/b/branch-trailing-1: trailingRefContent: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-trailing-1 && + test_cmp expect err && + + printf "ref: refs/heads/branch\n\n" >$branch_dir_prefix/a/b/branch-trailing-2 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-trailing-2: trailingRefContent: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-trailing-2 && + test_cmp expect err && + + printf "ref: refs/heads/branch \n" >$branch_dir_prefix/a/b/branch-trailing-3 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-trailing-3: trailingRefContent: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-trailing-3 && + test_cmp expect err && + + printf "ref: refs/heads/branch \n " >$branch_dir_prefix/a/b/branch-complicated && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/a/b/branch-complicated: refMissingNewline: misses LF at the end + warning: refs/heads/a/b/branch-complicated: trailingRefContent: has trailing whitespaces or newlines + EOF + rm $branch_dir_prefix/a/b/branch-complicated && test_cmp expect err ' -test_expect_success 'ref name check should be adapted into fsck messages' ' +test_expect_success 'textual symref content should be checked (aggregate)' ' test_when_finished "rm -rf repo" && git init repo && branch_dir_prefix=.git/refs/heads && tag_dir_prefix=.git/refs/tags && cd repo && - git commit --allow-empty -m initial && - git checkout -b branch-1 && - git tag tag-1 && - git commit --allow-empty -m second && - git checkout -b branch-2 && - git tag tag-2 && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && - cp $branch_dir_prefix/branch-1 $branch_dir_prefix/.branch-1 && - git -c fsck.badRefName=warn refs verify 2>err && + printf "ref: refs/heads/branch\n" >$branch_dir_prefix/branch-good && + printf "ref: HEAD\n" >$branch_dir_prefix/branch-head && + printf "ref: refs/heads/branch" >$branch_dir_prefix/branch-no-newline-1 && + printf "ref: refs/heads/branch " >$branch_dir_prefix/a/b/branch-trailing-1 && + printf "ref: refs/heads/branch\n\n" >$branch_dir_prefix/a/b/branch-trailing-2 && + printf "ref: refs/heads/branch \n" >$branch_dir_prefix/a/b/branch-trailing-3 && + printf "ref: refs/heads/branch \n " >$branch_dir_prefix/a/b/branch-complicated && + printf "ref: refs/heads/.branch\n" >$branch_dir_prefix/branch-bad-1 && + + test_must_fail git refs verify 2>err && cat >expect <<-EOF && - warning: refs/heads/.branch-1: badRefName: invalid refname format + error: refs/heads/branch-bad-1: badReferentName: points to invalid refname '\''refs/heads/.branch'\'' + warning: refs/heads/a/b/branch-complicated: refMissingNewline: misses LF at the end + warning: refs/heads/a/b/branch-complicated: trailingRefContent: has trailing whitespaces or newlines + warning: refs/heads/a/b/branch-trailing-1: refMissingNewline: misses LF at the end + warning: refs/heads/a/b/branch-trailing-1: trailingRefContent: has trailing whitespaces or newlines + warning: refs/heads/a/b/branch-trailing-2: trailingRefContent: has trailing whitespaces or newlines + warning: refs/heads/a/b/branch-trailing-3: trailingRefContent: has trailing whitespaces or newlines + warning: refs/heads/branch-no-newline-1: refMissingNewline: misses LF at the end EOF - rm $branch_dir_prefix/.branch-1 && + sort err >sorted_err && + test_cmp expect sorted_err +' + +test_expect_success 'the target of the textual symref should be checked' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + for good_referent in "refs/heads/branch" "HEAD" "refs/tags/tag" + do + printf "ref: %s\n" $good_referent >$branch_dir_prefix/branch-good && + git refs verify 2>err && + rm $branch_dir_prefix/branch-good && + test_must_be_empty err || return 1 + done && + + for nonref_referent in "refs-back/heads/branch" "refs-back/tags/tag" "reflogs/refs/heads/branch" + do + printf "ref: %s\n" $nonref_referent >$branch_dir_prefix/branch-bad-1 && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-bad-1: symrefTargetIsNotARef: points to non-ref target '\''$nonref_referent'\'' + EOF + rm $branch_dir_prefix/branch-bad-1 && + test_cmp expect err || return 1 + done +' + +test_expect_success SYMLINKS 'symlink symref content should be checked' ' + test_when_finished "rm -rf repo" && + git init repo && + branch_dir_prefix=.git/refs/heads && + tag_dir_prefix=.git/refs/tags && + cd repo && + test_commit default && + mkdir -p "$branch_dir_prefix/a/b" && + + ln -sf ./main $branch_dir_prefix/branch-symbolic-good && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic-good: symlinkRef: use deprecated symbolic link for symref + EOF + rm $branch_dir_prefix/branch-symbolic-good && test_cmp expect err && - cp $branch_dir_prefix/branch-1 $branch_dir_prefix/@ && - git -c fsck.badRefName=ignore refs verify 2>err && - test_must_be_empty err + ln -sf ../../logs/branch-escape $branch_dir_prefix/branch-symbolic && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic: symlinkRef: use deprecated symbolic link for symref + warning: refs/heads/branch-symbolic: symrefTargetIsNotARef: points to non-ref target '\''logs/branch-escape'\'' + EOF + rm $branch_dir_prefix/branch-symbolic && + test_cmp expect err && + + ln -sf ./"branch " $branch_dir_prefix/branch-symbolic-bad && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic-bad: symlinkRef: use deprecated symbolic link for symref + error: refs/heads/branch-symbolic-bad: badReferentName: points to invalid refname '\''refs/heads/branch '\'' + EOF + rm $branch_dir_prefix/branch-symbolic-bad && + test_cmp expect err && + + ln -sf ./".tag" $tag_dir_prefix/tag-symbolic-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/tags/tag-symbolic-1: symlinkRef: use deprecated symbolic link for symref + error: refs/tags/tag-symbolic-1: badReferentName: points to invalid refname '\''refs/tags/.tag'\'' + EOF + rm $tag_dir_prefix/tag-symbolic-1 && + test_cmp expect err +' + +test_expect_success SYMLINKS 'symlink symref content should be checked (worktree)' ' + test_when_finished "rm -rf repo" && + git init repo && + cd repo && + test_commit default && + git branch branch-1 && + git branch branch-2 && + git branch branch-3 && + git worktree add ./worktree-1 branch-2 && + git worktree add ./worktree-2 branch-3 && + main_worktree_refdir_prefix=.git/refs/heads && + worktree1_refdir_prefix=.git/worktrees/worktree-1/refs/worktree && + worktree2_refdir_prefix=.git/worktrees/worktree-2/refs/worktree && + + ( + cd worktree-1 && + git update-ref refs/worktree/branch-4 refs/heads/branch-1 + ) && + ( + cd worktree-2 && + git update-ref refs/worktree/branch-4 refs/heads/branch-1 + ) && + + ln -sf ../../../../refs/heads/good-branch $worktree1_refdir_prefix/branch-symbolic-good && + git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-1/refs/worktree/branch-symbolic-good: symlinkRef: use deprecated symbolic link for symref + EOF + rm $worktree1_refdir_prefix/branch-symbolic-good && + test_cmp expect err && + + ln -sf ../../../../worktrees/worktree-1/good-branch $worktree2_refdir_prefix/branch-symbolic-good && + git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-2/refs/worktree/branch-symbolic-good: symlinkRef: use deprecated symbolic link for symref + EOF + rm $worktree2_refdir_prefix/branch-symbolic-good && + test_cmp expect err && + + ln -sf ../../worktrees/worktree-2/good-branch $main_worktree_refdir_prefix/branch-symbolic-good && + git refs verify 2>err && + cat >expect <<-EOF && + warning: refs/heads/branch-symbolic-good: symlinkRef: use deprecated symbolic link for symref + EOF + rm $main_worktree_refdir_prefix/branch-symbolic-good && + test_cmp expect err && + + ln -sf ../../../../logs/branch-escape $worktree1_refdir_prefix/branch-symbolic && + git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-1/refs/worktree/branch-symbolic: symlinkRef: use deprecated symbolic link for symref + warning: worktrees/worktree-1/refs/worktree/branch-symbolic: symrefTargetIsNotARef: points to non-ref target '\''logs/branch-escape'\'' + EOF + rm $worktree1_refdir_prefix/branch-symbolic && + test_cmp expect err && + + for bad_referent_name in ".tag" "branch " + do + ln -sf ./"$bad_referent_name" $worktree1_refdir_prefix/bad-symbolic && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-1/refs/worktree/bad-symbolic: symlinkRef: use deprecated symbolic link for symref + error: worktrees/worktree-1/refs/worktree/bad-symbolic: badReferentName: points to invalid refname '\''worktrees/worktree-1/refs/worktree/$bad_referent_name'\'' + EOF + rm $worktree1_refdir_prefix/bad-symbolic && + test_cmp expect err && + + ln -sf ../../../../refs/heads/"$bad_referent_name" $worktree1_refdir_prefix/bad-symbolic && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-1/refs/worktree/bad-symbolic: symlinkRef: use deprecated symbolic link for symref + error: worktrees/worktree-1/refs/worktree/bad-symbolic: badReferentName: points to invalid refname '\''refs/heads/$bad_referent_name'\'' + EOF + rm $worktree1_refdir_prefix/bad-symbolic && + test_cmp expect err && + + ln -sf ./"$bad_referent_name" $worktree2_refdir_prefix/bad-symbolic && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-2/refs/worktree/bad-symbolic: symlinkRef: use deprecated symbolic link for symref + error: worktrees/worktree-2/refs/worktree/bad-symbolic: badReferentName: points to invalid refname '\''worktrees/worktree-2/refs/worktree/$bad_referent_name'\'' + EOF + rm $worktree2_refdir_prefix/bad-symbolic && + test_cmp expect err && + + ln -sf ../../../../refs/heads/"$bad_referent_name" $worktree2_refdir_prefix/bad-symbolic && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-2/refs/worktree/bad-symbolic: symlinkRef: use deprecated symbolic link for symref + error: worktrees/worktree-2/refs/worktree/bad-symbolic: badReferentName: points to invalid refname '\''refs/heads/$bad_referent_name'\'' + EOF + rm $worktree2_refdir_prefix/bad-symbolic && + test_cmp expect err || return 1 + done +' + +test_expect_success 'ref content checks should work with worktrees' ' + test_when_finished "rm -rf repo" && + git init repo && + cd repo && + test_commit default && + git branch branch-1 && + git branch branch-2 && + git branch branch-3 && + git worktree add ./worktree-1 branch-2 && + git worktree add ./worktree-2 branch-3 && + worktree1_refdir_prefix=.git/worktrees/worktree-1/refs/worktree && + worktree2_refdir_prefix=.git/worktrees/worktree-2/refs/worktree && + + ( + cd worktree-1 && + git update-ref refs/worktree/branch-4 refs/heads/branch-1 + ) && + ( + cd worktree-2 && + git update-ref refs/worktree/branch-4 refs/heads/branch-1 + ) && + + for bad_content in "$(git rev-parse HEAD)x" "xfsazqfxcadas" "Xfsazqfxcadas" + do + printf "%s" $bad_content >$worktree1_refdir_prefix/bad-branch-1 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: worktrees/worktree-1/refs/worktree/bad-branch-1: badRefContent: $bad_content + EOF + rm $worktree1_refdir_prefix/bad-branch-1 && + test_cmp expect err || return 1 + done && + + for bad_content in "$(git rev-parse HEAD)x" "xfsazqfxcadas" "Xfsazqfxcadas" + do + printf "%s" $bad_content >$worktree2_refdir_prefix/bad-branch-2 && + test_must_fail git refs verify 2>err && + cat >expect <<-EOF && + error: worktrees/worktree-2/refs/worktree/bad-branch-2: badRefContent: $bad_content + EOF + rm $worktree2_refdir_prefix/bad-branch-2 && + test_cmp expect err || return 1 + done && + + printf "%s" "$(git rev-parse HEAD)" >$worktree1_refdir_prefix/branch-no-newline && + git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-1/refs/worktree/branch-no-newline: refMissingNewline: misses LF at the end + EOF + rm $worktree1_refdir_prefix/branch-no-newline && + test_cmp expect err && + + printf "%s garbage" "$(git rev-parse HEAD)" >$worktree1_refdir_prefix/branch-garbage && + git refs verify 2>err && + cat >expect <<-EOF && + warning: worktrees/worktree-1/refs/worktree/branch-garbage: trailingRefContent: has trailing garbage: '\'' garbage'\'' + EOF + rm $worktree1_refdir_prefix/branch-garbage && + test_cmp expect err ' test_done diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh index 2d951c8ceb6baf..4618ffc108edd8 100755 --- a/t/t0610-reftable-basics.sh +++ b/t/t0610-reftable-basics.sh @@ -10,7 +10,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_DEFAULT_REF_FORMAT=reftable export GIT_TEST_DEFAULT_REF_FORMAT -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh INVALID_OID=$(test_oid 001) @@ -450,15 +449,24 @@ test_expect_success 'ref transaction: retry acquiring tables.list lock' ' ) ' -test_expect_success 'ref transaction: many concurrent writers' ' +# This test fails most of the time on Cygwin systems. The root cause is +# that Windows does not allow us to rename the "tables.list.lock" file into +# place when "tables.list" is open for reading by a concurrent process. We have +# worked around that in our MinGW-based rename emulation, but the Cygwin +# emulation seems to be insufficient. +test_expect_success !CYGWIN 'ref transaction: many concurrent writers' ' test_when_finished "rm -rf repo" && git init repo && ( cd repo && - # Set a high timeout such that a busy CI machine will not abort - # early. 10 seconds should hopefully be ample of time to make - # this non-flaky. - git config set reftable.lockTimeout 10000 && + # Set a high timeout. While a couple of seconds should be + # plenty, using the address sanitizer will significantly slow + # us down here. So we are aiming way higher than you would ever + # think is necessary just to keep us from flaking. We could + # also lock indefinitely by passing -1, but that could + # potentially block CI jobs indefinitely if there was a bug + # here. + git config set reftable.lockTimeout 300000 && test_commit --no-tag initial && head=$(git rev-parse HEAD) && diff --git a/t/t0611-reftable-httpd.sh b/t/t0611-reftable-httpd.sh index 2805995cc8c698..5e05b9c1f2ac73 100755 --- a/t/t0611-reftable-httpd.sh +++ b/t/t0611-reftable-httpd.sh @@ -2,7 +2,6 @@ test_description='reftable HTTPD tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t0612-reftable-jgit-compatibility.sh b/t/t0612-reftable-jgit-compatibility.sh index 84922153ab6a6d..d0d7e80b492091 100755 --- a/t/t0612-reftable-jgit-compatibility.sh +++ b/t/t0612-reftable-jgit-compatibility.sh @@ -11,7 +11,6 @@ export GIT_TEST_DEFAULT_REF_FORMAT GIT_TEST_SPLIT_INDEX=0 export GIT_TEST_SPLIT_INDEX -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq JGIT diff --git a/t/t0613-reftable-write-options.sh b/t/t0613-reftable-write-options.sh index b1c6c97524f16c..e2708e11d5b941 100755 --- a/t/t0613-reftable-write-options.sh +++ b/t/t0613-reftable-write-options.sh @@ -16,7 +16,6 @@ export GIT_TEST_DEFAULT_HASH GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'default write options' ' diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh index 0e8c0dfbbee643..b9dd21cfb6b1d5 100755 --- a/t/t1000-read-tree-m-3way.sh +++ b/t/t1000-read-tree-m-3way.sh @@ -72,7 +72,6 @@ In addition: ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 48a1550371a14b..4a88bb9ef0c401 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -21,7 +21,6 @@ In the test, these paths are used: yomin - not in H or M ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index a7c2ed0d7c0a31..df6ef537258780 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -9,7 +9,6 @@ This is identical to t1001, but uses -u to update the work tree as well. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh index c860c08ecb46a3..66e2bf4aec3d7a 100755 --- a/t/t1003-read-tree-prefix.sh +++ b/t/t1003-read-tree-prefix.sh @@ -6,7 +6,6 @@ test_description='git read-tree --prefix test. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh index 2b9720b0feb465..11bf10424f1620 100755 --- a/t/t1004-read-tree-m-u-wf.sh +++ b/t/t1004-read-tree-m-u-wf.sh @@ -5,7 +5,6 @@ test_description='read-tree -m -u checks working tree files' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh index 26be4a2b5a007a..6b5033d0ce3b34 100755 --- a/t/t1005-read-tree-reset.sh +++ b/t/t1005-read-tree-reset.sh @@ -2,7 +2,6 @@ test_description='read-tree -u --reset' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index d36cd7c0863591..398865d6ebe9c6 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -2,7 +2,6 @@ test_description='git cat-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_cmdmode_usage () { @@ -241,7 +240,8 @@ test_expect_success "setup" ' git config extensions.objectformat $test_hash_algo && git config extensions.compatobjectformat $test_compat_hash_algo && echo_without_newline "$hello_content" > hello && - git update-index --add hello + git update-index --add hello && + git commit -m "add hello file" ' run_blob_tests () { @@ -603,6 +603,34 @@ test_expect_success FUNNYNAMES '--batch-check, -Z with newline in input' ' test_cmp expect actual ' +test_expect_success 'setup with curly braches in input' ' + git branch "foo{bar" HEAD && + git branch "foo@" HEAD +' + +test_expect_success 'object reference with curly brace' ' + git cat-file -p "foo{bar:hello" >actual && + git cat-file -p HEAD:hello >expect && + test_cmp expect actual +' + +test_expect_success 'object reference with at-sign' ' + git cat-file -p "foo@@{0}:hello" >actual && + git cat-file -p HEAD:hello >expect && + test_cmp expect actual +' + +test_expect_success 'setup with commit with colon' ' + git commit-tree -m "testing: just a bunch of junk" HEAD^{tree} >out && + git branch other $(cat out) +' + +test_expect_success 'object reference via commit text search' ' + git cat-file -p "other^{/testing:}:hello" >actual && + git cat-file -p HEAD:hello >expect && + test_cmp expect actual +' + test_expect_success 'setup blobs which are likely to delta' ' test-tool genrandom foo 10240 >foo && { cat foo && echo plus; } >foo-plus && diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh index d73a5cc23705e2..a0481139de5519 100755 --- a/t/t1007-hash-object.sh +++ b/t/t1007-hash-object.sh @@ -2,7 +2,6 @@ test_description="git hash-object" -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh echo_without_newline() { diff --git a/t/t1008-read-tree-overlay.sh b/t/t1008-read-tree-overlay.sh index ad5936e54d1f73..4512fb0b6e68b4 100755 --- a/t/t1008-read-tree-overlay.sh +++ b/t/t1008-read-tree-overlay.sh @@ -5,7 +5,6 @@ test_description='test multi-tree read-tree without merging' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1009-read-tree-new-index.sh b/t/t1009-read-tree-new-index.sh index fc179ac5dd604a..2935f68f8d2152 100755 --- a/t/t1009-read-tree-new-index.sh +++ b/t/t1009-read-tree-new-index.sh @@ -5,7 +5,6 @@ test_description='test read-tree into a fresh index file' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index 22875ba598c2a8..c291a2b33d79b7 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -2,7 +2,6 @@ test_description='git mktree' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 595b24c0adb308..742f0fa909fd6e 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -12,7 +12,6 @@ test_description='sparse checkout tests ' TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1012-read-tree-df.sh b/t/t1012-read-tree-df.sh index cde93d22cde4ab..57f0770df1410e 100755 --- a/t/t1012-read-tree-df.sh +++ b/t/t1012-read-tree-df.sh @@ -2,7 +2,6 @@ test_description='read-tree D/F conflict corner cases' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1013-read-tree-submodule.sh b/t/t1013-read-tree-submodule.sh index cf8b94ebedbdd2..bfc90d4cf272e8 100755 --- a/t/t1013-read-tree-submodule.sh +++ b/t/t1013-read-tree-submodule.sh @@ -2,7 +2,6 @@ test_description='read-tree can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t1014-read-tree-confusing.sh b/t/t1014-read-tree-confusing.sh index 8ea8d36818bea1..0c0e6da5cf5b20 100755 --- a/t/t1014-read-tree-confusing.sh +++ b/t/t1014-read-tree-confusing.sh @@ -2,7 +2,6 @@ test_description='check that read-tree rejects confusing paths' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create base tree' ' diff --git a/t/t1015-read-index-unmerged.sh b/t/t1015-read-index-unmerged.sh index da737a32a27118..9b965d0294309f 100755 --- a/t/t1015-read-index-unmerged.sh +++ b/t/t1015-read-index-unmerged.sh @@ -2,7 +2,6 @@ test_description='Test various callers of read_index_unmerged' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup modify/delete + directory/file conflict' ' diff --git a/t/t1016-compatObjectFormat.sh b/t/t1016-compatObjectFormat.sh index be3206a16f6e30..e88362fbe4286b 100755 --- a/t/t1016-compatObjectFormat.sh +++ b/t/t1016-compatObjectFormat.sh @@ -5,7 +5,6 @@ test_description='Test how well compatObjectFormat works' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh @@ -24,84 +23,83 @@ TEST_PASSES_SANITIZE_LEAK=true # the commit is identical to the commit in the other repository. compat_hash () { - case "$1" in - "sha1") - echo "sha256" - ;; - "sha256") - echo "sha1" - ;; - esac + case "$1" in + "sha1") + echo "sha256" + ;; + "sha256") + echo "sha1" + ;; + esac } hello_oid () { - case "$1" in - "sha1") - echo "$hello_sha1_oid" - ;; - "sha256") - echo "$hello_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$hello_sha1_oid" + ;; + "sha256") + echo "$hello_sha256_oid" + ;; + esac } tree_oid () { - case "$1" in - "sha1") - echo "$tree_sha1_oid" - ;; - "sha256") - echo "$tree_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$tree_sha1_oid" + ;; + "sha256") + echo "$tree_sha256_oid" + ;; + esac } commit_oid () { - case "$1" in - "sha1") - echo "$commit_sha1_oid" - ;; - "sha256") - echo "$commit_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$commit_sha1_oid" + ;; + "sha256") + echo "$commit_sha256_oid" + ;; + esac } commit2_oid () { - case "$1" in - "sha1") - echo "$commit2_sha1_oid" - ;; - "sha256") - echo "$commit2_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$commit2_sha1_oid" + ;; + "sha256") + echo "$commit2_sha256_oid" + ;; + esac } del_sigcommit () { - local delete="$1" - - if test "$delete" = "sha256" ; then - local pattern="gpgsig-sha256" - else - local pattern="gpgsig" - fi - test-tool delete-gpgsig "$pattern" + local delete="$1" + + if test "$delete" = "sha256" ; then + local pattern="gpgsig-sha256" + else + local pattern="gpgsig" + fi + test-tool delete-gpgsig "$pattern" } - del_sigtag () { - local storage="$1" - local delete="$2" - - if test "$storage" = "$delete" ; then - local pattern="trailer" - elif test "$storage" = "sha256" ; then - local pattern="gpgsig" - else - local pattern="gpgsig-sha256" - fi - test-tool delete-gpgsig "$pattern" + local storage="$1" + local delete="$2" + + if test "$storage" = "$delete" ; then + local pattern="trailer" + elif test "$storage" = "sha256" ; then + local pattern="gpgsig" + else + local pattern="gpgsig-sha256" + fi + test-tool delete-gpgsig "$pattern" } base=$(pwd) @@ -116,8 +114,8 @@ do git config core.repositoryformatversion 1 && git config extensions.objectformat $hash && git config extensions.compatobjectformat $(compat_hash $hash) && - git config gpg.program $TEST_DIRECTORY/t1016/gpg && - echo "Hellow World!" > hello && + test_config gpg.program $TEST_DIRECTORY/t1016/gpg && + echo "Hello World!" >hello && eval hello_${hash}_oid=$(git hash-object hello) && git update-index --add hello && git commit -m "Initial commit" && @@ -146,9 +144,9 @@ do ' test_expect_success "create a $hash branch" ' git checkout -b branch $(commit_oid $hash) && - echo "More more more give me more!" > more && + echo "More more more give me more!" >more && eval more_${hash}_oid=$(git hash-object more) && - echo "Another and another and another" > another && + echo "Another and another and another" >another && eval another_${hash}_oid=$(git hash-object another) && git update-index --add more another && git commit -m "Add more files!" && @@ -165,15 +163,15 @@ do ' test_expect_success GPG2 "create additional $hash signed commits" ' git commit --gpg-sign --allow-empty -m "This is an additional signed commit" && - git cat-file commit HEAD | del_sigcommit sha256 > "../${hash}_signedcommit3" && - git cat-file commit HEAD | del_sigcommit sha1 > "../${hash}_signedcommit4" && + git cat-file commit HEAD | del_sigcommit sha256 >"../${hash}_signedcommit3" && + git cat-file commit HEAD | del_sigcommit sha1 >"../${hash}_signedcommit4" && eval signedcommit3_${hash}_oid=$(git hash-object -t commit -w ../${hash}_signedcommit3) && eval signedcommit4_${hash}_oid=$(git hash-object -t commit -w ../${hash}_signedcommit4) ' test_expect_success GPG2 "create additional $hash signed tags" ' git tag -s -m "This is an additional signed tag" signedtag34 HEAD && - git cat-file tag signedtag34 | del_sigtag "${hash}" sha256 > ../${hash}_signedtag3 && - git cat-file tag signedtag34 | del_sigtag "${hash}" sha1 > ../${hash}_signedtag4 && + git cat-file tag signedtag34 | del_sigtag "${hash}" sha256 >../${hash}_signedtag3 && + git cat-file tag signedtag34 | del_sigtag "${hash}" sha1 >../${hash}_signedtag4 && eval signedtag3_${hash}_oid=$(git hash-object -t tag -w ../${hash}_signedtag3) && eval signedtag4_${hash}_oid=$(git hash-object -t tag -w ../${hash}_signedtag4) ' @@ -181,81 +179,80 @@ done cd "$base" compare_oids () { - test "$#" = 5 && { local PREREQ="$1"; shift; } || PREREQ= - local type="$1" - local name="$2" - local sha1_oid="$3" - local sha256_oid="$4" - - echo ${sha1_oid} > ${name}_sha1_expected - echo ${sha256_oid} > ${name}_sha256_expected - echo ${type} > ${name}_type_expected - - git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} > ${name}_sha1_sha256_found - git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} > ${name}_sha256_sha1_found - local sha1_sha256_oid="$(cat ${name}_sha1_sha256_found)" - local sha256_sha1_oid="$(cat ${name}_sha256_sha1_found)" - - test_expect_success $PREREQ "Verify ${type} ${name}'s sha1 oid" ' - git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} > ${name}_sha1 && - test_cmp ${name}_sha1 ${name}_sha1_expected -' - - test_expect_success $PREREQ "Verify ${type} ${name}'s sha256 oid" ' - git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} > ${name}_sha256 && - test_cmp ${name}_sha256 ${name}_sha256_expected -' + test "$#" = 5 && { local PREREQ="$1"; shift; } || PREREQ= + local type="$1" + local name="$2" + local sha1_oid="$3" + local sha256_oid="$4" + + echo ${sha1_oid} >${name}_sha1_expected + echo ${sha256_oid} >${name}_sha256_expected + echo ${type} >${name}_type_expected + + git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} >${name}_sha1_sha256_found + git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} >${name}_sha256_sha1_found + local sha1_sha256_oid="$(cat ${name}_sha1_sha256_found)" + local sha256_sha1_oid="$(cat ${name}_sha256_sha1_found)" + + test_expect_success $PREREQ "Verify ${type} ${name}'s sha1 oid" ' + git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} >${name}_sha1 && + test_cmp ${name}_sha1 ${name}_sha1_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 type" ' - git --git-dir=repo-sha1/.git cat-file -t ${sha1_oid} > ${name}_type1 && - git --git-dir=repo-sha256/.git cat-file -t ${sha256_sha1_oid} > ${name}_type2 && - test_cmp ${name}_type1 ${name}_type2 && - test_cmp ${name}_type1 ${name}_type_expected -' + test_expect_success $PREREQ "Verify ${type} ${name}'s sha256 oid" ' + git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} >${name}_sha256 && + test_cmp ${name}_sha256 ${name}_sha256_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 type" ' - git --git-dir=repo-sha256/.git cat-file -t ${sha256_oid} > ${name}_type3 && - git --git-dir=repo-sha1/.git cat-file -t ${sha1_sha256_oid} > ${name}_type4 && - test_cmp ${name}_type3 ${name}_type4 && - test_cmp ${name}_type3 ${name}_type_expected -' + test_expect_success $PREREQ "Verify ${name}'s sha1 type" ' + git --git-dir=repo-sha1/.git cat-file -t ${sha1_oid} >${name}_type1 && + git --git-dir=repo-sha256/.git cat-file -t ${sha256_sha1_oid} >${name}_type2 && + test_cmp ${name}_type1 ${name}_type2 && + test_cmp ${name}_type1 ${name}_type_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 size" ' - git --git-dir=repo-sha1/.git cat-file -s ${sha1_oid} > ${name}_size1 && - git --git-dir=repo-sha256/.git cat-file -s ${sha256_sha1_oid} > ${name}_size2 && - test_cmp ${name}_size1 ${name}_size2 -' + test_expect_success $PREREQ "Verify ${name}'s sha256 type" ' + git --git-dir=repo-sha256/.git cat-file -t ${sha256_oid} >${name}_type3 && + git --git-dir=repo-sha1/.git cat-file -t ${sha1_sha256_oid} >${name}_type4 && + test_cmp ${name}_type3 ${name}_type4 && + test_cmp ${name}_type3 ${name}_type_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 size" ' - git --git-dir=repo-sha256/.git cat-file -s ${sha256_oid} > ${name}_size3 && - git --git-dir=repo-sha1/.git cat-file -s ${sha1_sha256_oid} > ${name}_size4 && - test_cmp ${name}_size3 ${name}_size4 -' + test_expect_success $PREREQ "Verify ${name}'s sha1 size" ' + git --git-dir=repo-sha1/.git cat-file -s ${sha1_oid} >${name}_size1 && + git --git-dir=repo-sha256/.git cat-file -s ${sha256_sha1_oid} >${name}_size2 && + test_cmp ${name}_size1 ${name}_size2 + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 pretty content" ' - git --git-dir=repo-sha1/.git cat-file -p ${sha1_oid} > ${name}_content1 && - git --git-dir=repo-sha256/.git cat-file -p ${sha256_sha1_oid} > ${name}_content2 && - test_cmp ${name}_content1 ${name}_content2 -' + test_expect_success $PREREQ "Verify ${name}'s sha256 size" ' + git --git-dir=repo-sha256/.git cat-file -s ${sha256_oid} >${name}_size3 && + git --git-dir=repo-sha1/.git cat-file -s ${sha1_sha256_oid} >${name}_size4 && + test_cmp ${name}_size3 ${name}_size4 + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 pretty content" ' - git --git-dir=repo-sha256/.git cat-file -p ${sha256_oid} > ${name}_content3 && - git --git-dir=repo-sha1/.git cat-file -p ${sha1_sha256_oid} > ${name}_content4 && - test_cmp ${name}_content3 ${name}_content4 -' + test_expect_success $PREREQ "Verify ${name}'s sha1 pretty content" ' + git --git-dir=repo-sha1/.git cat-file -p ${sha1_oid} >${name}_content1 && + git --git-dir=repo-sha256/.git cat-file -p ${sha256_sha1_oid} >${name}_content2 && + test_cmp ${name}_content1 ${name}_content2 + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 content" ' - git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_oid} > ${name}_content5 && - git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_sha1_oid} > ${name}_content6 && - test_cmp ${name}_content5 ${name}_content6 -' + test_expect_success $PREREQ "Verify ${name}'s sha256 pretty content" ' + git --git-dir=repo-sha256/.git cat-file -p ${sha256_oid} >${name}_content3 && + git --git-dir=repo-sha1/.git cat-file -p ${sha1_sha256_oid} >${name}_content4 && + test_cmp ${name}_content3 ${name}_content4 + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 content" ' - git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_oid} > ${name}_content7 && - git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_sha256_oid} > ${name}_content8 && - test_cmp ${name}_content7 ${name}_content8 -' + test_expect_success $PREREQ "Verify ${name}'s sha1 content" ' + git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_oid} >${name}_content5 && + git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_sha1_oid} >${name}_content6 && + test_cmp ${name}_content5 ${name}_content6 + ' + test_expect_success $PREREQ "Verify ${name}'s sha256 content" ' + git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_oid} >${name}_content7 && + git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_sha256_oid} >${name}_content8 && + test_cmp ${name}_content7 ${name}_content8 + ' } compare_oids 'blob' hello "$hello_sha1_oid" "$hello_sha256_oid" diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index 45eef9457fe13d..9fdbb2af80e0a8 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -6,7 +6,6 @@ test_description='Try various core-level commands in subdirectory. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1021-rerere-in-workdir.sh b/t/t1021-rerere-in-workdir.sh index 69bf9476cbf65d..0b892894eb9031 100755 --- a/t/t1021-rerere-in-workdir.sh +++ b/t/t1021-rerere-in-workdir.sh @@ -4,7 +4,6 @@ test_description='rerere run in a workdir' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success SYMLINKS setup ' diff --git a/t/t1022-read-tree-partial-clone.sh b/t/t1022-read-tree-partial-clone.sh index cca4380e4319a0..d390d7d5f857bb 100755 --- a/t/t1022-read-tree-partial-clone.sh +++ b/t/t1022-read-tree-partial-clone.sh @@ -3,7 +3,6 @@ test_description='git read-tree in partial clones' TEST_NO_CREATE_REPO=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'read-tree in partial clone prefetches in one batch' ' diff --git a/t/t1050-large.sh b/t/t1050-large.sh index ed638f664479bd..c71932b0242373 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -3,7 +3,6 @@ test_description='adding and checking out large blobs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'core.bigFileThreshold must be non-negative' ' diff --git a/t/t1051-large-conversion.sh b/t/t1051-large-conversion.sh index f6709c9f569ec7..361afb679b0af7 100755 --- a/t/t1051-large-conversion.sh +++ b/t/t1051-large-conversion.sh @@ -2,7 +2,6 @@ test_description='test conversion filters on large files' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh set_attr() { diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh index 5e0f0a334f4d43..502a5ea1c51e3a 100755 --- a/t/t1060-object-corruption.sh +++ b/t/t1060-object-corruption.sh @@ -2,7 +2,6 @@ test_description='see how we handle various forms of corruption' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # convert "1234abcd" to ".git/objects/12/34abcd" diff --git a/t/t1090-sparse-checkout-scope.sh b/t/t1090-sparse-checkout-scope.sh index da0e7714d5ac5c..3a14218b245d4c 100755 --- a/t/t1090-sparse-checkout-scope.sh +++ b/t/t1090-sparse-checkout-scope.sh @@ -6,7 +6,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 8c5cd651b4b80b..ab3a105ffff253 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_SPLIT_INDEX=false export GIT_TEST_SPLIT_INDEX -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh list_files() { diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index eb32da2a7f2ad6..a4c7c41fc00aa3 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -707,7 +707,7 @@ test_expect_success 'reset with wildcard pathspec' ' test_all_match git ls-files -s -- deep && # The following `git reset`s result in updating the index on files with - # `skip-worktree` enabled. To avoid failing due to discrepencies in reported + # `skip-worktree` enabled. To avoid failing due to discrepancies in reported # "modified" files, `test_sparse_match` reset is performed separately from # "full-checkout" reset, then the index contents of all repos are verified. @@ -823,7 +823,7 @@ test_expect_success 'update-index --remove outside sparse definition' ' # Reset the state test_all_match git reset --hard && - # --force-remove supercedes --ignore-skip-worktree-entries, removing + # --force-remove supersedes --ignore-skip-worktree-entries, removing # a skip-worktree file from the index (and disk) when both are specified # with --remove test_sparse_match git update-index --force-remove --ignore-skip-worktree-entries folder1/a && @@ -2080,7 +2080,7 @@ test_expect_success 'grep is not expanded' ' test_expect_failure 'grep within submodules is not expanded' ' init_repos_as_submodules && - # do not use ensure_not_expanded() here, becasue `grep` should be + # do not use ensure_not_expanded() here, because `grep` should be # run in the superproject, not in "./sparse-index" GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ git grep --cached --recurse-submodules a -- "*/folder1/*" && @@ -2355,7 +2355,10 @@ test_expect_success 'advice.sparseIndexExpanded' ' mkdir -p sparse-index/deep/deeper2/deepest && touch sparse-index/deep/deeper2/deepest/bogus && git -C sparse-index status 2>err && - grep "The sparse index is expanding to a full index" err + grep "The sparse index is expanding to a full index" err && + + git -C sparse-index sparse-checkout disable 2>err && + test_line_count = 0 err ' test_expect_success 'cat-file -p' ' diff --git a/t/t1100-commit-tree-options.sh b/t/t1100-commit-tree-options.sh index 0f37a43fd3c5b2..ae66ba5babf347 100755 --- a/t/t1100-commit-tree-options.sh +++ b/t/t1100-commit-tree-options.sh @@ -12,7 +12,6 @@ Also make sure that command line parser understands the normal "flags first and then non flag arguments" command line. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expected <<EOF diff --git a/t/t1300-config.sh b/t/t1300-config.sh index f13277c8f3e3c4..51a85e83c27b13 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -8,7 +8,6 @@ test_description='Test git config in different settings' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh for mode in legacy subcommands diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh index 29cf8a966133a7..630a47af21e655 100755 --- a/t/t1301-shared-repo.sh +++ b/t/t1301-shared-repo.sh @@ -9,7 +9,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Remove a default ACL from the test dir if possible. diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index 42caa0d2978b58..69723b88ff8961 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -5,7 +5,6 @@ test_description='Test repository version check' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh index 0506f3d6bba6cb..d971925ed021cc 100755 --- a/t/t1303-wacky-config.sh +++ b/t/t1303-wacky-config.sh @@ -2,7 +2,6 @@ test_description='Test wacky input to git config' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Leaving off the newline is intentional! diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh index 31b89dd9693afc..c69ae41306c90d 100755 --- a/t/t1304-default-acl.sh +++ b/t/t1304-default-acl.sh @@ -9,7 +9,6 @@ test_description='Test repository with default ACL' # => this must come before . ./test-lib.sh umask 077 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # We need an arbitrary other user give permission to using ACLs. root diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index 517d6c869379bf..8ff2b0c232b485 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -1,7 +1,6 @@ #!/bin/sh test_description='test config file include directives' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Force setup_explicit_git_dir() to run until the end. This is needed diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh index 53e5b290b9bcab..40d3c42618c04f 100755 --- a/t/t1306-xdg-files.sh +++ b/t/t1306-xdg-files.sh @@ -7,7 +7,6 @@ test_description='Compatibility with $XDG_CONFIG_HOME/git/ files' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'read config: xdg file exists and ~/.gitconfig doesn'\''t' ' diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh index b9852fe40e4a04..5cb546dd00c665 100755 --- a/t/t1307-config-blob.sh +++ b/t/t1307-config-blob.sh @@ -2,7 +2,6 @@ test_description='support for reading config from a blob' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create config blob' ' diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh index 3bfec07f1abcc1..e0e49053f07fbc 100755 --- a/t/t1308-config-set.sh +++ b/t/t1308-config-set.sh @@ -2,7 +2,6 @@ test_description='Test git config-set API in different settings' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # 'check_config get_* section.key value' verifies that the entry for diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh index 523aa99a1e2646..9710ee0ca4571d 100755 --- a/t/t1309-early-config.sh +++ b/t/t1309-early-config.sh @@ -2,7 +2,6 @@ test_description='Test read_early_config()' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'read early config' ' diff --git a/t/t1310-config-default.sh b/t/t1310-config-default.sh index 1a90d31201a612..69e64c6c8686fb 100755 --- a/t/t1310-config-default.sh +++ b/t/t1310-config-default.sh @@ -2,7 +2,6 @@ test_description='Test git config in different settings (with --default)' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'uses --default when entry missing' ' diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh index ceeb7ac3a4745f..45a04929170640 100755 --- a/t/t1350-config-hooks-path.sh +++ b/t/t1350-config-hooks-path.sh @@ -2,7 +2,6 @@ test_description='Test the core.hooksPath configuration variable' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up a pre-commit hook in core.hooksPath' ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index eb1691860dabad..29045aad43906f 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -5,7 +5,6 @@ test_description='Test git update-ref and basic ref logging' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh Z=$ZERO_OID @@ -1838,10 +1837,10 @@ do test_expect_success "stdin $type create dangling symref ref works" ' test_when_finished "git symbolic-ref -d refs/heads/symref" && - format_command $type "symref-create refs/heads/symref" "refs/heads/unkown" >stdin && + format_command $type "symref-create refs/heads/symref" "refs/heads/unknown" >stdin && git update-ref --stdin $type --no-deref <stdin && git symbolic-ref refs/heads/symref >expect && - echo refs/heads/unkown >actual && + echo refs/heads/unknown >actual && test_cmp expect actual ' @@ -2069,4 +2068,13 @@ do done +test_expect_success 'update-ref should also create reflog for HEAD' ' + test_commit to-rewind && + git rev-parse HEAD >expect && + head=$(git symbolic-ref HEAD) && + git update-ref --create-reflog "$head" HEAD~ && + git rev-parse HEAD@{1} >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 5c60d6f812dc20..a2a7e947164c2a 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -2,7 +2,6 @@ test_description='basic symbolic-ref tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # If the tests munging HEAD fail, they can break detection of @@ -16,7 +15,7 @@ reset_to_sane() { test_expect_success 'setup' ' git symbolic-ref HEAD refs/heads/foo && test_commit file && - "$TAR" cf .git.tar .git/ + "$TAR" cf .git.tar .git ' test_expect_success 'symbolic-ref read/write roundtrip' ' diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh index 5ed9d7318e0cc9..cabc516ae9a4fa 100755 --- a/t/t1402-check-ref-format.sh +++ b/t/t1402-check-ref-format.sh @@ -2,7 +2,6 @@ test_description='Test git check-ref-format' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh valid_ref() { diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh index 403f6b8f7daf00..9d698b3cc35a7f 100755 --- a/t/t1403-show-ref.sh +++ b/t/t1403-show-ref.sh @@ -4,7 +4,6 @@ test_description='show-ref' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh index df90112618c106..28e6c380d76db1 100755 --- a/t/t1404-update-ref-errors.sh +++ b/t/t1404-update-ref-errors.sh @@ -2,7 +2,6 @@ test_description='Test git update-ref error handling' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Create some references, perhaps run pack-refs --all, then try to diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index a6bcd62ab658ee..6d8f401a2a9827 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -5,7 +5,6 @@ test_description='test main ref store api' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh RUN="test-tool ref-store main" diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh index c01f0f14a1266f..9b9e5d0766f38d 100755 --- a/t/t1406-submodule-ref-store.sh +++ b/t/t1406-submodule-ref-store.sh @@ -5,7 +5,6 @@ test_description='test submodule ref store api' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh RUN="test-tool ref-store submodule:sub" diff --git a/t/t1407-worktree-ref-store.sh b/t/t1407-worktree-ref-store.sh index 48b1c92a41450b..9d8e1a13432b83 100755 --- a/t/t1407-worktree-ref-store.sh +++ b/t/t1407-worktree-ref-store.sh @@ -5,7 +5,6 @@ test_description='test worktree ref store api' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh RWT="test-tool ref-store worktree:wt" diff --git a/t/t1408-packed-refs.sh b/t/t1408-packed-refs.sh index 9469c79a585f05..41ba1f1d7fca94 100755 --- a/t/t1408-packed-refs.sh +++ b/t/t1408-packed-refs.sh @@ -5,7 +5,6 @@ test_description='packed-refs entries are covered by loose refs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1409-avoid-packing-refs.sh b/t/t1409-avoid-packing-refs.sh index 7748973733e6ad..e3c501848a494c 100755 --- a/t/t1409-avoid-packing-refs.sh +++ b/t/t1409-avoid-packing-refs.sh @@ -2,7 +2,6 @@ test_description='avoid rewriting packed-refs unnecessarily' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test_have_prereq !REFFILES diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 246a3f46abafdf..388fdf9ae57dac 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -7,7 +7,6 @@ test_description='Test prune and reflog expiration' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_have () { diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index da581ec19ac619..975c4ea83a877b 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -4,7 +4,6 @@ test_description='Test reflog display routines' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh index ff30874f940439..f7d69b66ff33e8 100755 --- a/t/t1412-reflog-loop.sh +++ b/t/t1412-reflog-loop.sh @@ -2,7 +2,6 @@ test_description='reflog walk shows repeated commits again' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commits' ' diff --git a/t/t1413-reflog-detach.sh b/t/t1413-reflog-detach.sh index d2a4822d46fd05..934688a1ee82e2 100755 --- a/t/t1413-reflog-detach.sh +++ b/t/t1413-reflog-detach.sh @@ -4,7 +4,6 @@ test_description='Test reflog interaction with detached HEAD' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh reset_state () { diff --git a/t/t1415-worktree-refs.sh b/t/t1415-worktree-refs.sh index eb4eec8becbfa6..51d79bae83b429 100755 --- a/t/t1415-worktree-refs.sh +++ b/t/t1415-worktree-refs.sh @@ -2,7 +2,6 @@ test_description='per-worktree refs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh index 5a812ca3c0b5d3..8c777f7cf8704d 100755 --- a/t/t1416-ref-transaction-hooks.sh +++ b/t/t1416-ref-transaction-hooks.sh @@ -5,7 +5,6 @@ test_description='reference transaction hooks' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -53,7 +52,6 @@ test_expect_success 'hook gets all queued updates in prepared state' ' fi EOF cat >expect <<-EOF && - $ZERO_OID $POST_OID HEAD $ZERO_OID $POST_OID refs/heads/main EOF git update-ref HEAD POST <<-EOF && @@ -76,7 +74,6 @@ test_expect_success 'hook gets all queued updates in committed state' ' fi EOF cat >expect <<-EOF && - $ZERO_OID $POST_OID HEAD $ZERO_OID $POST_OID refs/heads/main EOF git update-ref HEAD POST && diff --git a/t/t1417-reflog-updateref.sh b/t/t1417-reflog-updateref.sh index 0eb5e674bc1f0d..2f37402536743e 100755 --- a/t/t1417-reflog-updateref.sh +++ b/t/t1417-reflog-updateref.sh @@ -2,7 +2,6 @@ test_description='git reflog --updateref' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1418-reflog-exists.sh b/t/t1418-reflog-exists.sh index 2268bca3c11ac8..d51ecd5e9250f0 100755 --- a/t/t1418-reflog-exists.sh +++ b/t/t1418-reflog-exists.sh @@ -4,7 +4,6 @@ test_description='Test reflog display routines' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1419-exclude-refs.sh b/t/t1419-exclude-refs.sh index 3256e4462f96db..c04eeb72111662 100755 --- a/t/t1419-exclude-refs.sh +++ b/t/t1419-exclude-refs.sh @@ -5,7 +5,6 @@ test_description='test exclude_patterns functionality in main ref store' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh for_each_ref__exclude () { diff --git a/t/t1420-lost-found.sh b/t/t1420-lost-found.sh index dbe15a0be10516..2fb2f44f021ea3 100755 --- a/t/t1420-lost-found.sh +++ b/t/t1420-lost-found.sh @@ -5,7 +5,6 @@ test_description='Test fsck --lost-found' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index 0c00118c2b3f79..3ab65f72cdec88 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -4,7 +4,6 @@ test_description='Test handling of ref names that check-ref-format rejects' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 280cbf3e031e1a..8a456b1142d1cc 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -6,7 +6,6 @@ test_description='git fsck random collection of tests * (main) A ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1451-fsck-buffer.sh b/t/t1451-fsck-buffer.sh index 3413da40e4ae0c..3a3d33f4054895 100755 --- a/t/t1451-fsck-buffer.sh +++ b/t/t1451-fsck-buffer.sh @@ -15,7 +15,6 @@ These tests _might_ catch such overruns in normal use, but should be run with ASan or valgrind for more confidence. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # the general idea for tags and commits is to build up the "base" file diff --git a/t/t1460-refs-migrate.sh b/t/t1460-refs-migrate.sh index f7c0783d30ccd6..2ab97e1b7dfa7e 100755 --- a/t/t1460-refs-migrate.sh +++ b/t/t1460-refs-migrate.sh @@ -5,26 +5,53 @@ test_description='migration of ref storage backends' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +# Migrate the provided repository from one format to the other and +# verify that the references and logs are migrated over correctly. +# Usage: test_migration <repo> <format> [<skip_reflog_verify> [<options...>]] +# <repo> is the relative path to the repo to be migrated. +# <format> is the ref format to be migrated to. +# <skip_reflog_verify> (default: false) whether to skip reflog verification. +# <options...> are other options be passed directly to 'git refs migrate'. test_migration () { - git -C "$1" for-each-ref --include-root-refs \ + repo=$1 && + format=$2 && + shift 2 && + skip_reflog_verify=false && + if test $# -ge 1 + then + skip_reflog_verify=$1 + shift + fi && + git -C "$repo" for-each-ref --include-root-refs \ --format='%(refname) %(objectname) %(symref)' >expect && - git -C "$1" refs migrate --ref-format="$2" && - git -C "$1" for-each-ref --include-root-refs \ + if ! $skip_reflog_verify + then + git -C "$repo" reflog --all >expect_logs && + git -C "$repo" reflog list >expect_log_list + fi && + + git -C "$repo" refs migrate --ref-format="$format" "$@" && + + git -C "$repo" for-each-ref --include-root-refs \ --format='%(refname) %(objectname) %(symref)' >actual && test_cmp expect actual && + if ! $skip_reflog_verify + then + git -C "$repo" reflog --all >actual_logs && + git -C "$repo" reflog list >actual_log_list && + test_cmp expect_logs actual_logs && + test_cmp expect_log_list actual_log_list + fi && - git -C "$1" rev-parse --show-ref-format >actual && - echo "$2" >expect && + git -C "$repo" rev-parse --show-ref-format >actual && + echo "$format" >expect && test_cmp expect actual } test_expect_success 'setup' ' - rm -rf .git && - # The migration does not yet support reflogs. - git config --global core.logAllRefUpdates false + rm -rf .git ' test_expect_success "superfluous arguments" ' @@ -79,19 +106,6 @@ do test_cmp expect err ' - test_expect_success "$from_format -> $to_format: migration with reflog fails" ' - test_when_finished "rm -rf repo" && - git init --ref-format=$from_format repo && - test_config -C repo core.logAllRefUpdates true && - test_commit -C repo logged && - test_must_fail git -C repo refs migrate \ - --ref-format=$to_format 2>err && - cat >expect <<-EOF && - error: migrating reflogs is not supported yet - EOF - test_cmp expect err - ' - test_expect_success "$from_format -> $to_format: migration with worktree fails" ' test_when_finished "rm -rf repo" && git init --ref-format=$from_format repo && @@ -142,7 +156,7 @@ do test_commit -C repo initial && test-tool -C repo ref-store main update-ref "" refs/heads/broken \ "$(test_oid 001)" "$ZERO_OID" REF_SKIP_CREATE_REFLOG,REF_SKIP_OID_VERIFICATION && - test_migration repo "$to_format" && + test_migration repo "$to_format" true && test_oid 001 >expect && git -C repo rev-parse refs/heads/broken >actual && test_cmp expect actual @@ -196,9 +210,72 @@ do git -C repo rev-parse --show-ref-format >actual && test_cmp expect actual ' + + test_expect_success "$from_format -> $to_format: reflogs of symrefs with target deleted" ' + test_when_finished "rm -rf repo" && + git init --ref-format=$from_format repo && + test_commit -C repo initial && + git -C repo branch branch-1 HEAD && + git -C repo symbolic-ref refs/heads/symref refs/heads/branch-1 && + cat >input <<-EOF && + delete refs/heads/branch-1 + EOF + git -C repo update-ref --stdin <input && + test_migration repo "$to_format" + ' + + test_expect_success "$from_format -> $to_format: reflogs order is retained" ' + test_when_finished "rm -rf repo" && + git init --ref-format=$from_format repo && + test_commit --date "100005000 +0700" --no-tag -C repo initial && + test_commit --date "100003000 +0700" --no-tag -C repo second && + test_migration repo "$to_format" + ' + + test_expect_success "$from_format -> $to_format: stash is retained" ' + test_when_finished "rm -rf repo" && + git init --ref-format=$from_format repo && + ( + cd repo && + test_commit initial A && + echo foo >A && + git stash push && + echo bar >A && + git stash push && + git stash list >expect.reflog && + test_migration . "$to_format" && + git stash list >actual.reflog && + test_cmp expect.reflog actual.reflog + ) + ' + + test_expect_success "$from_format -> $to_format: skip reflog with --skip-reflog" ' + test_when_finished "rm -rf repo" && + git init --ref-format=$from_format repo && + test_commit -C repo initial && + # we see that the repository contains reflogs. + git -C repo reflog --all >reflogs && + test_line_count = 2 reflogs && + test_migration repo "$to_format" true --no-reflog && + # there should be no reflogs post migration. + git -C repo reflog --all >reflogs && + test_must_be_empty reflogs + ' done done +test_expect_success 'multiple reftable blocks with multiple entries' ' + test_when_finished "rm -rf repo" && + git init --ref-format=files repo && + test_commit -C repo first && + printf "create refs/heads/ref-%d HEAD\n" $(test_seq 5000) >stdin && + git -C repo update-ref --stdin <stdin && + test_commit -C repo second && + printf "update refs/heads/ref-%d HEAD\n" $(test_seq 3000) >stdin && + git -C repo update-ref --stdin <stdin && + test_migration repo reftable +' + test_expect_success 'migrating from files format deletes backend files' ' test_when_finished "rm -rf repo" && git init --ref-format=files repo && @@ -237,7 +314,7 @@ test_expect_success 'migrating from reftable format deletes backend files' ' test_path_is_missing repo/.git/reftable && echo "ref: refs/heads/main" >expect && test_cmp expect repo/.git/HEAD && - test_path_is_file repo/.git/refs/heads/main + test_path_is_file repo/.git/packed-refs ' test_done diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 30c31918fde653..58a4583088b859 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -4,7 +4,6 @@ test_description='test git rev-parse' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_one () { @@ -310,4 +309,19 @@ test_expect_success '--short= truncates to the actual hash length' ' test_cmp expect actual ' +test_expect_success ':/ and HEAD^{/} favor more recent matching commits' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit common-old && + test_commit --no-tag common-new && + git rev-parse HEAD >expect && + git rev-parse :/common >actual && + test_cmp expect actual && + git rev-parse HEAD^{/common} >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t1501-work-tree.sh b/t/t1501-work-tree.sh index ae6528aecea7d3..8c94ac2e70bdc6 100755 --- a/t/t1501-work-tree.sh +++ b/t/t1501-work-tree.sh @@ -2,7 +2,6 @@ test_description='test separate work tree' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index 5eaa6428c43917..3962f1d2882a1f 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -2,7 +2,6 @@ test_description='test git rev-parse --parseopt' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_invalid_long_option () { diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index 79df65ec7f619b..75a708f9ba5f22 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -9,7 +9,6 @@ exec </dev/null GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh add_line_into_file() diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh index c1679e31d8afca..e04420f4368b93 100755 --- a/t/t1504-ceiling-dirs.sh +++ b/t/t1504-ceiling-dirs.sh @@ -2,7 +2,6 @@ test_description='test GIT_CEILING_DIRECTORIES' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_prefix() { diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh index 4a5758f08a8b2f..2803ca9489c7c6 100755 --- a/t/t1505-rev-parse-last.sh +++ b/t/t1505-rev-parse-last.sh @@ -5,7 +5,6 @@ test_description='test @{-N} syntax' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index ef40511d897292..722884e65f4587 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -7,7 +7,6 @@ exec </dev/null GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_did_you_mean () @@ -195,7 +194,7 @@ test_expect_success 'dotdot is not an empty set' ' ' test_expect_success 'dotdot does not peel endpoints' ' - git tag -a -m "annote" annotated HEAD && + git tag -a -m "annotate" annotated HEAD && A=$(git rev-parse annotated) && H=$(git rev-parse annotated^0) && { diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index b9af6b3ac035a0..cb9ef7e329eb06 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -5,7 +5,6 @@ test_description='test <branch>@{upstream} syntax' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t1508-at-combinations.sh b/t/t1508-at-combinations.sh index e841309d0eab10..87a42864145f85 100755 --- a/t/t1508-at-combinations.sh +++ b/t/t1508-at-combinations.sh @@ -4,7 +4,6 @@ test_description='test various @{X} syntax combinations together' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check() { diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index 591505a39c0278..bbfe05b8e4a5c4 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -43,7 +43,6 @@ A few rules for repo setup: # This test heavily relies on the standard error of nested function calls. test_untraceable=UnfortunatelyYes -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh here=$(pwd) diff --git a/t/t1511-rev-parse-caret.sh b/t/t1511-rev-parse-caret.sh index e7e78a40281336..6ecfed86bc0d6a 100755 --- a/t/t1511-rev-parse-caret.sh +++ b/t/t1511-rev-parse-caret.sh @@ -5,7 +5,6 @@ test_description='tests for ref^{stuff}' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh index f9d68ce74ea095..70f1e0a998e103 100755 --- a/t/t1512-rev-parse-disambiguation.sh +++ b/t/t1512-rev-parse-disambiguation.sh @@ -23,7 +23,6 @@ one tagged as v1.0.0. They all have one regular file each. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_cmp_failed_rev_parse () { diff --git a/t/t1513-rev-parse-prefix.sh b/t/t1513-rev-parse-prefix.sh index ba43387bf167b5..5f437be8c9e8c9 100755 --- a/t/t1513-rev-parse-prefix.sh +++ b/t/t1513-rev-parse-prefix.sh @@ -5,7 +5,6 @@ test_description='Tests for rev-parse --prefix' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1514-rev-parse-push.sh b/t/t1514-rev-parse-push.sh index a835a196aa81be..d868a0811056c8 100755 --- a/t/t1514-rev-parse-push.sh +++ b/t/t1514-rev-parse-push.sh @@ -4,7 +4,6 @@ test_description='test <branch>@{push} syntax' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh resolve () { diff --git a/t/t1515-rev-parse-outside-repo.sh b/t/t1515-rev-parse-outside-repo.sh index cdb26a30d726bb..75e89c4b6e23c2 100755 --- a/t/t1515-rev-parse-outside-repo.sh +++ b/t/t1515-rev-parse-outside-repo.sh @@ -2,7 +2,6 @@ test_description='check that certain rev-parse options work outside repo' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up non-repo directory' ' diff --git a/t/t1517-outside-repo.sh b/t/t1517-outside-repo.sh index 342defbb617628..dbd8cd6906338d 100755 --- a/t/t1517-outside-repo.sh +++ b/t/t1517-outside-repo.sh @@ -2,7 +2,6 @@ test_description='check random commands outside repo' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up a non-repo directory and test file' ' diff --git a/t/t1600-index.sh b/t/t1600-index.sh index 62e7fd15964bba..03239e9faa4b7e 100755 --- a/t/t1600-index.sh +++ b/t/t1600-index.sh @@ -2,7 +2,6 @@ test_description='index file specific tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sane_unset GIT_TEST_SPLIT_INDEX diff --git a/t/t1601-index-bogus.sh b/t/t1601-index-bogus.sh index 5dcc10188280b2..a45a8b4eb046f6 100755 --- a/t/t1601-index-bogus.sh +++ b/t/t1601-index-bogus.sh @@ -2,7 +2,6 @@ test_description='test handling of bogus index entries' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create tree with null sha1' ' diff --git a/t/t1701-racy-split-index.sh b/t/t1701-racy-split-index.sh index d8fa489998acc5..5dc221ef382df1 100755 --- a/t/t1701-racy-split-index.sh +++ b/t/t1701-racy-split-index.sh @@ -5,7 +5,6 @@ test_description='racy split index' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh index 8b0234cf2d5d96..4feaf0d7bef71f 100755 --- a/t/t1800-hook.sh +++ b/t/t1800-hook.sh @@ -2,7 +2,6 @@ test_description='git-hook command' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t2000-conflict-when-checking-files-out.sh b/t/t2000-conflict-when-checking-files-out.sh index 79fc97f1d7eb42..f18616ad2be3ea 100755 --- a/t/t2000-conflict-when-checking-files-out.sh +++ b/t/t2000-conflict-when-checking-files-out.sh @@ -21,7 +21,6 @@ test_description='git conflicts when checking files out test.' # path1 is occupied by a non-directory. With "-f" flag, it should remove # the conflicting paths and succeed. -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh show_files() { diff --git a/t/t2002-checkout-cache-u.sh b/t/t2002-checkout-cache-u.sh index fc95cf90485366..70361c806e1baf 100755 --- a/t/t2002-checkout-cache-u.sh +++ b/t/t2002-checkout-cache-u.sh @@ -8,7 +8,6 @@ test_description='git checkout-index -u test. With -u flag, git checkout-index internally runs the equivalent of git update-index --refresh on the checked out entry.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh index f0fd441d810d52..ff163cf6750f6d 100755 --- a/t/t2003-checkout-cache-mkdir.sh +++ b/t/t2003-checkout-cache-mkdir.sh @@ -10,7 +10,6 @@ also verifies that such leading path may contain symlinks, unlike the GIT controlled paths. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh index 98e818f09f21fe..b92d96fdc4ed5f 100755 --- a/t/t2004-checkout-cache-temp.sh +++ b/t/t2004-checkout-cache-temp.sh @@ -8,7 +8,6 @@ test_description='git checkout-index --temp test. With --temp flag, git checkout-index writes to temporary merge files rather than the tracked path.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh index 67d18cfa104b86..91b08e03717a61 100755 --- a/t/t2005-checkout-index-symlinks.sh +++ b/t/t2005-checkout-index-symlinks.sh @@ -8,7 +8,6 @@ test_description='git checkout-index on filesystem w/o symlinks test. This tests that git checkout-index creates a symbolic link as a plain file if core.symlinks is false.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t2006-checkout-index-basic.sh b/t/t2006-checkout-index-basic.sh index 570ba38580d995..bac231b167c2c6 100755 --- a/t/t2006-checkout-index-basic.sh +++ b/t/t2006-checkout-index-basic.sh @@ -3,7 +3,6 @@ test_description='basic checkout-index tests ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'checkout-index --gobbledegook' ' diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh index bd9e9e7530da06..6f0b90ce1271ec 100755 --- a/t/t2007-checkout-symlink.sh +++ b/t/t2007-checkout-symlink.sh @@ -7,7 +7,6 @@ test_description='git checkout to switch between branches with symlink<->dir' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2008-checkout-subdir.sh b/t/t2008-checkout-subdir.sh index 8a518a44ea2d2a..eadb9434ae764c 100755 --- a/t/t2008-checkout-subdir.sh +++ b/t/t2008-checkout-subdir.sh @@ -4,7 +4,6 @@ test_description='git checkout from subdirectories' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2009-checkout-statinfo.sh b/t/t2009-checkout-statinfo.sh index 71195dd28f2258..b0540636ae3871 100755 --- a/t/t2009-checkout-statinfo.sh +++ b/t/t2009-checkout-statinfo.sh @@ -5,7 +5,6 @@ test_description='checkout should leave clean stat info' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh index 82c3bfeac1ad9b..3a3d56018e525e 100755 --- a/t/t2010-checkout-ambiguous.sh +++ b/t/t2010-checkout-ambiguous.sh @@ -5,7 +5,6 @@ test_description='checkout and pathspecs/refspecs ambiguities' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh index 04f53b1ea14cb5..61417c756750bb 100755 --- a/t/t2011-checkout-invalid-head.sh +++ b/t/t2011-checkout-invalid-head.sh @@ -5,7 +5,6 @@ test_description='checkout switching away from an invalid branch' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh index 4b6372f4c3e946..1f6c4ed0428a5c 100755 --- a/t/t2012-checkout-last.sh +++ b/t/t2012-checkout-last.sh @@ -5,7 +5,6 @@ test_description='checkout can switch to last branch and merge base' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh index 3c1d663d948490..b2bdd1fcb425a1 100755 --- a/t/t2013-checkout-submodule.sh +++ b/t/t2013-checkout-submodule.sh @@ -2,7 +2,6 @@ test_description='checkout can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t2014-checkout-switch.sh b/t/t2014-checkout-switch.sh index c138bdde4fea15..3e757c6e4e3250 100755 --- a/t/t2014-checkout-switch.sh +++ b/t/t2014-checkout-switch.sh @@ -2,7 +2,6 @@ test_description='Peter MacMillan' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2015-checkout-unborn.sh b/t/t2015-checkout-unborn.sh index fb0e13881cd8a2..1820300c62fb34 100755 --- a/t/t2015-checkout-unborn.sh +++ b/t/t2015-checkout-unborn.sh @@ -4,7 +4,6 @@ test_description='checkout from unborn branch' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index c40b661ac12d57..c4f9bf09aa4fd8 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -2,7 +2,6 @@ test_description='git checkout --patch' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-patch-mode.sh test_expect_success 'setup' ' diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index a5c7358eeabefb..80ac661815d0a7 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -10,7 +10,6 @@ Main Tests for --orphan functionality.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh TEST_FILE=foo diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index 43551cc1481c38..a48ebdbf4d0957 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -3,7 +3,6 @@ test_description='checkout' TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Arguments: [!] <branch> <oid> [<checkout options>] diff --git a/t/t2019-checkout-ambiguous-ref.sh b/t/t2019-checkout-ambiguous-ref.sh index c67261e2b68a9d..1fcef4be95ce14 100755 --- a/t/t2019-checkout-ambiguous-ref.sh +++ b/t/t2019-checkout-ambiguous-ref.sh @@ -2,7 +2,6 @@ test_description='checkout handling of ambiguous (branch/tag) refs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ambiguous refs' ' diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh index 8d90d028504529..28bbbe6c05547a 100755 --- a/t/t2020-checkout-detach.sh +++ b/t/t2020-checkout-detach.sh @@ -4,7 +4,6 @@ test_description='checkout into detached HEAD state' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_detached () { diff --git a/t/t2021-checkout-overwrite.sh b/t/t2021-checkout-overwrite.sh index ecfacf0f7f3a5f..a5c03d5d4a2c5a 100755 --- a/t/t2021-checkout-overwrite.sh +++ b/t/t2021-checkout-overwrite.sh @@ -2,7 +2,6 @@ test_description='checkout must not overwrite an untracked objects' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh index f1b709d58bef00..c49ba7f9bd4fe0 100755 --- a/t/t2022-checkout-paths.sh +++ b/t/t2022-checkout-paths.sh @@ -4,7 +4,6 @@ test_description='checkout $tree -- $paths' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2023-checkout-m.sh b/t/t2023-checkout-m.sh index 81e772fb4ebbf1..7b327b754494a8 100755 --- a/t/t2023-checkout-m.sh +++ b/t/t2023-checkout-m.sh @@ -7,7 +7,6 @@ Ensures that checkout -m on a resolved file restores the conflicted file' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index 2caada3d834ffc..a3b1449ef11667 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh @@ -4,7 +4,6 @@ test_description='checkout <branch> Ensures that checkout on an unborn branch does what the user expects' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Is the current branch "refs/heads/$1"? diff --git a/t/t2025-checkout-no-overlay.sh b/t/t2025-checkout-no-overlay.sh index 246609d54d050e..dda169bbc4a649 100755 --- a/t/t2025-checkout-no-overlay.sh +++ b/t/t2025-checkout-no-overlay.sh @@ -2,7 +2,6 @@ test_description='checkout --no-overlay <tree-ish> -- <pathspec>' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2026-checkout-pathspec-file.sh b/t/t2026-checkout-pathspec-file.sh index acd55217a6231c..161da054b6dbb5 100755 --- a/t/t2026-checkout-pathspec-file.sh +++ b/t/t2026-checkout-pathspec-file.sh @@ -2,7 +2,6 @@ test_description='checkout --pathspec-from-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t2027-checkout-track.sh b/t/t2027-checkout-track.sh index 98f16c72399806..a397790df59d0b 100755 --- a/t/t2027-checkout-track.sh +++ b/t/t2027-checkout-track.sh @@ -5,7 +5,6 @@ test_description='tests for git branch --track' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh index b3f6bc97b53d87..be3fcdde07562c 100755 --- a/t/t2030-unresolve-info.sh +++ b/t/t2030-unresolve-info.sh @@ -5,7 +5,6 @@ test_description='undoing resolution' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_resolve_undo () { diff --git a/t/t2050-git-dir-relative.sh b/t/t2050-git-dir-relative.sh index 1f193cde965303..21f4659a9d1c22 100755 --- a/t/t2050-git-dir-relative.sh +++ b/t/t2050-git-dir-relative.sh @@ -12,7 +12,6 @@ into the subdir while keeping the worktree location, and tries commits from the top and the subdir, checking that the commit-hook still gets called.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh COMMIT_FILE="$(pwd)/output" diff --git a/t/t2060-switch.sh b/t/t2060-switch.sh index 77b2346291b39c..c91c4db9361133 100755 --- a/t/t2060-switch.sh +++ b/t/t2060-switch.sh @@ -5,7 +5,6 @@ test_description='switch basic functionality' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh index ac404945d4c4e2..16d6348b692806 100755 --- a/t/t2070-restore.sh +++ b/t/t2070-restore.sh @@ -5,7 +5,6 @@ test_description='restore basic functionality' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2071-restore-patch.sh b/t/t2071-restore-patch.sh index 42d55221191575..27e85be40ad695 100755 --- a/t/t2071-restore-patch.sh +++ b/t/t2071-restore-patch.sh @@ -2,7 +2,6 @@ test_description='git restore --patch' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-patch-mode.sh test_expect_success 'setup' ' diff --git a/t/t2072-restore-pathspec-file.sh b/t/t2072-restore-pathspec-file.sh index 86c9c887881b94..8198a1e5789cc9 100755 --- a/t/t2072-restore-pathspec-file.sh +++ b/t/t2072-restore-pathspec-file.sh @@ -2,7 +2,6 @@ test_description='restore --pathspec-from-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t2080-parallel-checkout-basics.sh b/t/t2080-parallel-checkout-basics.sh index 59e5570cb2d522..5ffe1a41e2cd72 100755 --- a/t/t2080-parallel-checkout-basics.sh +++ b/t/t2080-parallel-checkout-basics.sh @@ -8,7 +8,6 @@ working tree. ' TEST_NO_CREATE_REPO=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-parallel-checkout.sh" diff --git a/t/t2081-parallel-checkout-collisions.sh b/t/t2081-parallel-checkout-collisions.sh index 6acdb89d12bd04..f6fcfc0c1e4039 100755 --- a/t/t2081-parallel-checkout-collisions.sh +++ b/t/t2081-parallel-checkout-collisions.sh @@ -11,7 +11,6 @@ The tests in this file exercise parallel checkout's collision detection code in both these mechanics. " -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-parallel-checkout.sh" diff --git a/t/t2082-parallel-checkout-attributes.sh b/t/t2082-parallel-checkout-attributes.sh index aec55496eb1588..79fb11f139a2c1 100755 --- a/t/t2082-parallel-checkout-attributes.sh +++ b/t/t2082-parallel-checkout-attributes.sh @@ -10,7 +10,6 @@ properly (without access to the index or attribute stack). ' TEST_NO_CREATE_REPO=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-parallel-checkout.sh" . "$TEST_DIRECTORY/lib-encoding.sh" @@ -34,7 +33,7 @@ test_expect_success 'parallel-checkout with ident' ' ) ' -test_expect_success 'parallel-checkout with re-encoding' ' +test_expect_success ICONV 'parallel-checkout with re-encoding' ' set_checkout_config 2 0 && git init encoding && ( @@ -91,7 +90,7 @@ test_expect_success 'parallel-checkout with eol conversions' ' # Entries that require an external filter are not eligible for parallel # checkout. Check that both the parallel-eligible and non-eligible entries are -# properly writen in a single checkout operation. +# properly written in a single checkout operation. # test_expect_success 'parallel-checkout and external filter' ' set_checkout_config 2 0 && diff --git a/t/t2100-update-cache-badpath.sh b/t/t2100-update-cache-badpath.sh index 7915e7b8211dbb..2df3fdde8bf665 100755 --- a/t/t2100-update-cache-badpath.sh +++ b/t/t2100-update-cache-badpath.sh @@ -22,7 +22,6 @@ and tries to git update-index --add the following: All of the attempts should fail. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh mkdir path2 path3 diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh index e3c7acdbf9125d..6c32d42c8c6888 100755 --- a/t/t2101-update-index-reupdate.sh +++ b/t/t2101-update-index-reupdate.sh @@ -6,7 +6,6 @@ test_description='git update-index --again test. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'update-index --add' ' diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh index c49cdfb6e582f4..9b11130ab93a32 100755 --- a/t/t2102-update-index-symlinks.sh +++ b/t/t2102-update-index-symlinks.sh @@ -8,7 +8,6 @@ test_description='git update-index on filesystem w/o symlinks test. This tests that git update-index keeps the symbolic link property even if a plain file is in the working tree if core.symlinks is false.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t2103-update-index-ignore-missing.sh b/t/t2103-update-index-ignore-missing.sh index e9451cd567cd61..6938ecca868366 100755 --- a/t/t2103-update-index-ignore-missing.sh +++ b/t/t2103-update-index-ignore-missing.sh @@ -2,7 +2,6 @@ test_description='update-index with options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success basics ' diff --git a/t/t2104-update-index-skip-worktree.sh b/t/t2104-update-index-skip-worktree.sh index 7ec7f30b442b3b..7a0778ed983a50 100755 --- a/t/t2104-update-index-skip-worktree.sh +++ b/t/t2104-update-index-skip-worktree.sh @@ -5,7 +5,6 @@ test_description='skip-worktree bit test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sane_unset GIT_TEST_SPLIT_INDEX diff --git a/t/t2105-update-index-gitfile.sh b/t/t2105-update-index-gitfile.sh index 963ebe77eb6b49..a7f3d47aec2591 100755 --- a/t/t2105-update-index-gitfile.sh +++ b/t/t2105-update-index-gitfile.sh @@ -6,7 +6,6 @@ test_description='git update-index for gitlink to .git file. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'submodule with absolute .git file' ' diff --git a/t/t2106-update-index-assume-unchanged.sh b/t/t2106-update-index-assume-unchanged.sh index 95c004dc5c5462..6b2ccc21a937df 100755 --- a/t/t2106-update-index-assume-unchanged.sh +++ b/t/t2106-update-index-assume-unchanged.sh @@ -3,7 +3,6 @@ test_description='git update-index --assume-unchanged test. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh index f0eab13f96a6b9..cc72ead79f3978 100755 --- a/t/t2107-update-index-basic.sh +++ b/t/t2107-update-index-basic.sh @@ -5,7 +5,6 @@ test_description='basic update-index tests Tests for command-line parsing and basic operation. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'update-index --nonsense fails' ' diff --git a/t/t2108-update-index-refresh-racy.sh b/t/t2108-update-index-refresh-racy.sh index bc5f2886faf887..b31dd8ece5023e 100755 --- a/t/t2108-update-index-refresh-racy.sh +++ b/t/t2108-update-index-refresh-racy.sh @@ -2,7 +2,6 @@ test_description='update-index refresh tests related to racy timestamps' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh reset_files () { diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index df235ac306e712..06e83d33333dc8 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -14,7 +14,6 @@ only the updates to dir/sub. Also tested are "git add -u" without limiting, and "git add -u" without contents changes, and other conditions' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh index dba62d69c6c5c1..687be974d413a1 100755 --- a/t/t2201-add-update-typechange.sh +++ b/t/t2201-add-update-typechange.sh @@ -2,7 +2,6 @@ test_description='more git add -u' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2202-add-addremove.sh b/t/t2202-add-addremove.sh index 24c60bfd7905ba..9ee659098c45fb 100755 --- a/t/t2202-add-addremove.sh +++ b/t/t2202-add-addremove.sh @@ -2,7 +2,6 @@ test_description='git add --all' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index 8fa44a92a277f4..192ad14b5f474f 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -2,7 +2,6 @@ test_description='Intent to add' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'intent to add' ' diff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh index b7cf1e492c1073..31eb233df51f5e 100755 --- a/t/t2204-add-ignored.sh +++ b/t/t2204-add-ignored.sh @@ -2,7 +2,6 @@ test_description='giving ignored paths to git add' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2205-add-worktree-config.sh b/t/t2205-add-worktree-config.sh index 98265ba1b495eb..43d950de6400fc 100755 --- a/t/t2205-add-worktree-config.sh +++ b/t/t2205-add-worktree-config.sh @@ -17,7 +17,6 @@ outside the repository. Two instances for which this can occur are tested: repository can be added to the index. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success '1a: setup--config worktree' ' diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh index b40eeb263fe896..c8de6d8a190220 100755 --- a/t/t2300-cd-to-toplevel.sh +++ b/t/t2300-cd-to-toplevel.sh @@ -2,7 +2,6 @@ test_description='cd_to_toplevel' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh EXEC_PATH="$(git --exec-path)" diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index cfc4aeb1798c6d..90638fa886a22e 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -6,7 +6,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh @@ -1207,4 +1206,50 @@ test_expect_success '"add" with initialized submodule, with submodule.recurse se git -C project-clone -c submodule.recurse worktree add ../project-5 ' +test_expect_success 'can create worktrees with relative paths' ' + test_when_finished "git worktree remove relative" && + test_config worktree.useRelativePaths false && + git worktree add --relative-paths ./relative && + echo "gitdir: ../.git/worktrees/relative" >expect && + test_cmp expect relative/.git && + echo "../../../relative/.git" >expect && + test_cmp expect .git/worktrees/relative/gitdir +' + +test_expect_success 'can create worktrees with absolute paths' ' + test_config worktree.useRelativePaths true && + git worktree add ./relative && + echo "gitdir: ../.git/worktrees/relative" >expect && + test_cmp expect relative/.git && + git worktree add --no-relative-paths ./absolute && + echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect && + test_cmp expect absolute/.git && + echo "$(pwd)/absolute/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir +' + +test_expect_success 'move repo without breaking relative internal links' ' + test_when_finished rm -rf repo moved && + git init repo && + ( + cd repo && + test_commit initial && + git worktree add --relative-paths wt1 && + cd .. && + mv repo moved && + cd moved/wt1 && + git worktree list >out 2>err && + test_must_be_empty err + ) +' + +test_expect_success 'relative worktree sets extension config' ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo commit --allow-empty -m base && + git -C repo worktree add --relative-paths ./foo && + test_cmp_config -C repo 1 core.repositoryformatversion && + test_cmp_config -C repo true extensions.relativeworktrees +' + test_done diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh index 71aa9bcd620f8a..fe671d41974281 100755 --- a/t/t2401-worktree-prune.sh +++ b/t/t2401-worktree-prune.sh @@ -5,7 +5,6 @@ test_description='prune $GIT_DIR/worktrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success initialize ' @@ -120,4 +119,24 @@ test_expect_success 'prune duplicate (main/linked)' ' ! test -d .git/worktrees/wt ' +test_expect_success 'not prune proper worktrees inside linked worktree with relative paths' ' + test_when_finished rm -rf repo wt_ext && + git init repo && + ( + cd repo && + git config worktree.useRelativePaths true && + echo content >file && + git add file && + git commit -m msg && + git worktree add ../wt_ext && + git worktree add wt_int && + cd wt_int && + git worktree prune -v >out && + test_must_be_empty out && + cd ../../wt_ext && + git worktree prune -v >out && + test_must_be_empty out + ) +' + test_done diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index 33ea9cb21ba07c..8ef1cad7f29d7d 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -5,7 +5,6 @@ test_description='test git worktree list' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -261,6 +260,7 @@ test_expect_success 'broken main worktree still at the top' ' ' test_expect_success 'linked worktrees are sorted' ' + test_when_finished "rm -rf sorted" && mkdir sorted && git init sorted/main && ( @@ -280,6 +280,27 @@ test_expect_success 'linked worktrees are sorted' ' test_cmp expected sorted/main/actual ' +test_expect_success 'linked worktrees with relative paths are shown with absolute paths' ' + test_when_finished "rm -rf sorted" && + mkdir sorted && + git init sorted/main && + ( + cd sorted/main && + test_tick && + test_commit new && + git worktree add --relative-paths ../first && + git worktree add ../second && + git worktree list --porcelain >out && + grep ^worktree out >actual + ) && + cat >expected <<-EOF && + worktree $(pwd)/sorted/main + worktree $(pwd)/sorted/first + worktree $(pwd)/sorted/second + EOF + test_cmp expected sorted/main/actual +' + test_expect_success 'worktree path when called in .git directory' ' git worktree list >list1 && git -C .git worktree list >list2 && diff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh index 901342ea09b51a..0bb33e8b1b90fb 100755 --- a/t/t2403-worktree-move.sh +++ b/t/t2403-worktree-move.sh @@ -2,7 +2,6 @@ test_description='test git worktree move, remove, lock and unlock' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -247,4 +246,29 @@ test_expect_success 'not remove a repo with initialized submodule' ' ) ' +test_expect_success 'move worktree with absolute path to relative path' ' + test_config worktree.useRelativePaths false && + git worktree add ./absolute && + git worktree move --relative-paths absolute relative && + echo "gitdir: ../.git/worktrees/absolute" >expect && + test_cmp expect relative/.git && + echo "../../../relative/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir && + test_config worktree.useRelativePaths true && + git worktree move relative relative2 && + echo "gitdir: ../.git/worktrees/absolute" >expect && + test_cmp expect relative2/.git && + echo "../../../relative2/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir +' + +test_expect_success 'move worktree with relative path to absolute path' ' + test_config worktree.useRelativePaths true && + git worktree move --no-relative-paths relative2 absolute && + echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect && + test_cmp expect absolute/.git && + echo "$(pwd)/absolute/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir +' + test_done diff --git a/t/t2404-worktree-config.sh b/t/t2404-worktree-config.sh index 842937bfb9a8a6..9536d1091954b4 100755 --- a/t/t2404-worktree-config.sh +++ b/t/t2404-worktree-config.sh @@ -2,7 +2,6 @@ test_description="config file in multi worktree" -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2405-worktree-submodule.sh b/t/t2405-worktree-submodule.sh index 1d7f60563387f9..11018f37c70c02 100755 --- a/t/t2405-worktree-submodule.sh +++ b/t/t2405-worktree-submodule.sh @@ -5,7 +5,6 @@ test_description='Combination of submodules and multiple worktrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh base_path=$(pwd -P) diff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh index edbf502ec57bb7..f5f19b3169384f 100755 --- a/t/t2406-worktree-repair.sh +++ b/t/t2406-worktree-repair.sh @@ -2,7 +2,6 @@ test_description='test git worktree repair' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -197,4 +196,62 @@ test_expect_success 'repair moved main and linked worktrees' ' test_cmp expect-gitfile sidemoved/.git ' +test_expect_success 'repair copied main and linked worktrees' ' + test_when_finished "rm -rf orig dup" && + mkdir -p orig && + git -C orig init main && + test_commit -C orig/main nothing && + git -C orig/main worktree add ../linked && + cp orig/main/.git/worktrees/linked/gitdir orig/main.expect && + cp orig/linked/.git orig/linked.expect && + cp -R orig dup && + sed "s,orig/linked/\.git$,dup/linked/.git," orig/main.expect >dup/main.expect && + sed "s,orig/main/\.git/worktrees/linked$,dup/main/.git/worktrees/linked," \ + orig/linked.expect >dup/linked.expect && + git -C dup/main worktree repair ../linked && + test_cmp orig/main.expect orig/main/.git/worktrees/linked/gitdir && + test_cmp orig/linked.expect orig/linked/.git && + test_cmp dup/main.expect dup/main/.git/worktrees/linked/gitdir && + test_cmp dup/linked.expect dup/linked/.git +' + +test_expect_success 'repair worktree with relative path with missing gitfile' ' + test_when_finished "rm -rf main wt" && + test_create_repo main && + git -C main config worktree.useRelativePaths true && + test_commit -C main init && + git -C main worktree add --detach ../wt && + rm wt/.git && + test_path_is_missing wt/.git && + git -C main worktree repair && + echo "gitdir: ../main/.git/worktrees/wt" >expect && + test_cmp expect wt/.git +' + +test_expect_success 'repair absolute worktree to use relative paths' ' + test_when_finished "rm -rf main side sidemoved" && + test_create_repo main && + test_commit -C main init && + git -C main worktree add --detach ../side && + echo "../../../../sidemoved/.git" >expect-gitdir && + echo "gitdir: ../main/.git/worktrees/side" >expect-gitfile && + mv side sidemoved && + git -C main worktree repair --relative-paths ../sidemoved && + test_cmp expect-gitdir main/.git/worktrees/side/gitdir && + test_cmp expect-gitfile sidemoved/.git +' + +test_expect_success 'repair relative worktree to use absolute paths' ' + test_when_finished "rm -rf main side sidemoved" && + test_create_repo main && + test_commit -C main init && + git -C main worktree add --relative-paths --detach ../side && + echo "$(pwd)/sidemoved/.git" >expect-gitdir && + echo "gitdir: $(pwd)/main/.git/worktrees/side" >expect-gitfile && + mv side sidemoved && + git -C main worktree repair ../sidemoved && + test_cmp expect-gitdir main/.git/worktrees/side/gitdir && + test_cmp expect-gitfile sidemoved/.git +' + test_done diff --git a/t/t2407-worktree-heads.sh b/t/t2407-worktree-heads.sh index f6835c91dcc49c..57c201869f02e6 100755 --- a/t/t2407-worktree-heads.sh +++ b/t/t2407-worktree-heads.sh @@ -2,7 +2,6 @@ test_description='test operations trying to overwrite refs at worktree HEAD' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -49,7 +48,7 @@ test_expect_success 'refuse to overwrite: checked out in worktree' ' done ' -test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in bisect' ' +test_expect_success 'refuse to overwrite: worktree in bisect' ' test_when_finished git -C wt-4 bisect reset && # Set up a bisect so HEAD no longer points to wt-4. @@ -61,7 +60,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in bisect' ' grep "cannot force update the branch '\''wt-4'\'' used by worktree at.*wt-4" err ' -test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (apply)' ' +test_expect_success 'refuse to overwrite: worktree in rebase (apply)' ' test_when_finished git -C wt-2 rebase --abort && # This will fail part-way through due to a conflict. @@ -71,7 +70,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (app grep "cannot force update the branch '\''wt-2'\'' used by worktree at.*wt-2" err ' -test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (merge)' ' +test_expect_success 'refuse to overwrite: worktree in rebase (merge)' ' test_when_finished git -C wt-2 rebase --abort && # This will fail part-way through due to a conflict. @@ -81,7 +80,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (mer grep "cannot force update the branch '\''wt-2'\'' used by worktree at.*wt-2" err ' -test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase with --update-refs' ' +test_expect_success 'refuse to overwrite: worktree in rebase with --update-refs' ' test_when_finished git -C wt-3 rebase --abort && git branch -f can-be-updated wt-3 && @@ -95,7 +94,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase with done ' -test_expect_success !SANITIZE_LEAK 'refuse to fetch over ref: checked out' ' +test_expect_success 'refuse to fetch over ref: checked out' ' test_must_fail git fetch server +refs/heads/wt-3:refs/heads/wt-3 2>err && grep "refusing to fetch into branch '\''refs/heads/wt-3'\''" err && @@ -105,7 +104,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to fetch over ref: checked out' ' grep "refusing to fetch into branch" err ' -test_expect_success !SANITIZE_LEAK 'refuse to fetch over ref: worktree in bisect' ' +test_expect_success 'refuse to fetch over ref: worktree in bisect' ' test_when_finished git -C wt-4 bisect reset && # Set up a bisect so HEAD no longer points to wt-4. @@ -117,7 +116,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to fetch over ref: worktree in bisect grep "refusing to fetch into branch" err ' -test_expect_success !SANITIZE_LEAK 'refuse to fetch over ref: worktree in rebase' ' +test_expect_success 'refuse to fetch over ref: worktree in rebase' ' test_when_finished git -C wt-3 rebase --abort && # This will fail part-way through due to a conflict. @@ -157,7 +156,7 @@ test_expect_success 'refuse to overwrite when in error states' ' . "$TEST_DIRECTORY"/lib-rebase.sh -test_expect_success !SANITIZE_LEAK 'refuse to overwrite during rebase with --update-refs' ' +test_expect_success 'refuse to overwrite during rebase with --update-refs' ' git commit --fixup HEAD~2 --allow-empty && ( set_cat_todo_editor && diff --git a/t/t2500-untracked-overwriting.sh b/t/t2500-untracked-overwriting.sh index 714feb83be5b36..5c0bf4d21fcbb2 100755 --- a/t/t2500-untracked-overwriting.sh +++ b/t/t2500-untracked-overwriting.sh @@ -2,7 +2,6 @@ test_description='Test handling of overwriting untracked files' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_setup_reset () { diff --git a/t/t2501-cwd-empty.sh b/t/t2501-cwd-empty.sh index 8af4e8cfe3c841..f6d8d7d03d7ca4 100755 --- a/t/t2501-cwd-empty.sh +++ b/t/t2501-cwd-empty.sh @@ -2,7 +2,6 @@ test_description='Test handling of the current working directory becoming empty' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh index 11af4552f7461e..13f66fd649d81d 100755 --- a/t/t3000-ls-files-others.sh +++ b/t/t3000-ls-files-others.sh @@ -16,7 +16,6 @@ filesystem. path4 - an empty directory ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ' ' diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index 1ed0aa967ece5a..4b676462852ab8 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -8,7 +8,6 @@ test_description='git ls-files --others --exclude This test runs git ls-files --others and tests --exclude patterns. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh rm -fr one three diff --git a/t/t3002-ls-files-dashpath.sh b/t/t3002-ls-files-dashpath.sh index 4dd24550eba00e..31462cb441ef2f 100755 --- a/t/t3002-ls-files-dashpath.sh +++ b/t/t3002-ls-files-dashpath.sh @@ -13,7 +13,6 @@ filesystem. -- - another file with a funny name. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3003-ls-files-exclude.sh b/t/t3003-ls-files-exclude.sh index 7933dff9b38491..ac3c811f464c28 100755 --- a/t/t3003-ls-files-exclude.sh +++ b/t/t3003-ls-files-exclude.sh @@ -2,7 +2,6 @@ test_description='ls-files --exclude does not affect index files' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create repo with file' ' diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh index 12e41a7b40e0ab..a1078f8701dbfb 100755 --- a/t/t3004-ls-files-basic.sh +++ b/t/t3004-ls-files-basic.sh @@ -6,7 +6,6 @@ This test runs git ls-files with various unusual or malformed command-line arguments. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'ls-files in empty repository' ' diff --git a/t/t3005-ls-files-relative.sh b/t/t3005-ls-files-relative.sh index fbfa210a50b290..db13aabf625b3a 100755 --- a/t/t3005-ls-files-relative.sh +++ b/t/t3005-ls-files-relative.sh @@ -5,7 +5,6 @@ test_description='ls-files tests with relative paths This test runs git ls-files with various relative path arguments. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare' ' diff --git a/t/t3006-ls-files-long.sh b/t/t3006-ls-files-long.sh index 2aaf91ebc8c323..22c7256c3aec85 100755 --- a/t/t3006-ls-files-long.sh +++ b/t/t3006-ls-files-long.sh @@ -2,7 +2,6 @@ test_description='overly long paths' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh index f04bdc8c78b6e8..61771eec830c06 100755 --- a/t/t3007-ls-files-recurse-submodules.sh +++ b/t/t3007-ls-files-recurse-submodules.sh @@ -6,7 +6,6 @@ This test verifies the recurse-submodules feature correctly lists files from submodules. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup directory structure and submodules' ' diff --git a/t/t3008-ls-files-lazy-init-name-hash.sh b/t/t3008-ls-files-lazy-init-name-hash.sh index 51d3dffaa66528..85f370495876f5 100755 --- a/t/t3008-ls-files-lazy-init-name-hash.sh +++ b/t/t3008-ls-files-lazy-init-name-hash.sh @@ -2,7 +2,6 @@ test_description='Test the lazy init name hash with various folder structures' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test 1 -eq $(test-tool online-cpus) diff --git a/t/t3009-ls-files-others-nonsubmodule.sh b/t/t3009-ls-files-others-nonsubmodule.sh index 14218b34243778..963f3462b750b2 100755 --- a/t/t3009-ls-files-others-nonsubmodule.sh +++ b/t/t3009-ls-files-others-nonsubmodule.sh @@ -18,7 +18,6 @@ This test runs git ls-files --others with the following working tree: git repository with a commit and an untracked file ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: directories' ' diff --git a/t/t3010-ls-files-killed-modified.sh b/t/t3010-ls-files-killed-modified.sh index 054178703d7324..7af4532cd1dfd0 100755 --- a/t/t3010-ls-files-killed-modified.sh +++ b/t/t3010-ls-files-killed-modified.sh @@ -42,7 +42,6 @@ We should report path0, path1, path2/file2, path3/file3, path7 and path8 modified without reporting path9 and path10. submod1 is also modified. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'git update-index --add to add various paths.' ' diff --git a/t/t3012-ls-files-dedup.sh b/t/t3012-ls-files-dedup.sh index 190e2f6eed7582..2682b1f43a6665 100755 --- a/t/t3012-ls-files-dedup.sh +++ b/t/t3012-ls-files-dedup.sh @@ -2,7 +2,6 @@ test_description='git ls-files --deduplicate test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3013-ls-files-format.sh b/t/t3013-ls-files-format.sh index 6e6ea0b6f3ca25..8bdaacd85ace3d 100755 --- a/t/t3013-ls-files-format.sh +++ b/t/t3013-ls-files-format.sh @@ -2,7 +2,6 @@ test_description='git ls-files --format test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh for flag in -s -o -k -t --resolve-undo --deduplicate --eol diff --git a/t/t3020-ls-files-error-unmatch.sh b/t/t3020-ls-files-error-unmatch.sh index 133593d23c0e89..ac82c9cee8a0f3 100755 --- a/t/t3020-ls-files-error-unmatch.sh +++ b/t/t3020-ls-files-error-unmatch.sh @@ -10,7 +10,6 @@ returns an error when a non-existent path is provided on the command line. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3040-subprojects-basic.sh b/t/t3040-subprojects-basic.sh index bd65dfcffc7b80..768d702fbbfb4a 100755 --- a/t/t3040-subprojects-basic.sh +++ b/t/t3040-subprojects-basic.sh @@ -2,7 +2,6 @@ test_description='Basic subproject functionality' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: create superproject' ' diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh index 3884694165525b..f1f09abdd9b254 100755 --- a/t/t3050-subprojects-fetch.sh +++ b/t/t3050-subprojects-fetch.sh @@ -2,7 +2,6 @@ test_description='fetching and pushing project with subproject' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh index 5a06732ca730f4..eb69da61fe7cd1 100755 --- a/t/t3060-ls-files-with-tree.sh +++ b/t/t3060-ls-files-with-tree.sh @@ -9,7 +9,6 @@ This test runs git ls-files --with-tree and in particular in a scenario known to trigger a crash with some versions of git. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh index 4dd42df38c2561..3da824117c61fd 100755 --- a/t/t3070-wildmatch.sh +++ b/t/t3070-wildmatch.sh @@ -2,7 +2,6 @@ test_description='wildmatch tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh should_create_test_file() { diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh index 436de44971eca5..8f294d983267f3 100755 --- a/t/t3100-ls-tree-restrict.sh +++ b/t/t3100-ls-tree-restrict.sh @@ -17,7 +17,6 @@ The new path restriction code should do the right thing for path2 and path2/baz. Also path0/ should snow nothing. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh index 5af2dac0e4b8d5..ac44525810f977 100755 --- a/t/t3101-ls-tree-dirname.sh +++ b/t/t3101-ls-tree-dirname.sh @@ -20,7 +20,6 @@ Test the handling of multiple directories which have matching file entries. Also test odd filename and missing entries handling. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index 3942db229000e0..1e16c6b8ea610c 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh @@ -2,7 +2,6 @@ test_description='ls-tree with(out) globs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3103-ls-tree-misc.sh b/t/t3103-ls-tree-misc.sh index 81c6343962381f..e7636f6908f19f 100755 --- a/t/t3103-ls-tree-misc.sh +++ b/t/t3103-ls-tree-misc.sh @@ -7,7 +7,6 @@ Miscellaneous tests for git ls-tree. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3104-ls-tree-format.sh b/t/t3104-ls-tree-format.sh index 3adb206a93bc58..a1b2069a256aab 100755 --- a/t/t3104-ls-tree-format.sh +++ b/t/t3104-ls-tree-format.sh @@ -2,7 +2,6 @@ test_description='ls-tree --format' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t3100.sh diff --git a/t/t3105-ls-tree-output.sh b/t/t3105-ls-tree-output.sh index ce2391e28be6f2..8bdf400682dae5 100755 --- a/t/t3105-ls-tree-output.sh +++ b/t/t3105-ls-tree-output.sh @@ -2,7 +2,6 @@ test_description='ls-tree output' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t3100.sh diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index ccfa6a720d090c..f3e720dc10da46 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -8,7 +8,6 @@ test_description='git branch assorted tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh @@ -411,6 +410,20 @@ test_expect_success 'bare main worktree has HEAD at branch deleted by secondary git -C secondary branch -D main ' +test_expect_success 'secondary worktrees recognize core.bare=true in main config.worktree' ' + test_when_finished "rm -rf bare_repo non_bare_repo secondary_worktree" && + git init -b main non_bare_repo && + test_commit -C non_bare_repo x && + + git clone --bare non_bare_repo bare_repo && + git -C bare_repo config extensions.worktreeConfig true && + git -C bare_repo config unset core.bare && + git -C bare_repo config --worktree core.bare true && + + git -C bare_repo worktree add ../secondary_worktree && + git -C secondary_worktree checkout main +' + test_expect_success 'git branch --list -v with --abbrev' ' test_when_finished "git branch -D t" && git branch t && @@ -1697,7 +1710,7 @@ test_expect_success 'errors if given a bad branch name' ' cat <<-\EOF >expect && fatal: '\''foo..bar'\'' is not a valid branch name hint: See `man git check-ref-format` - hint: Disable this message with "git config advice.refSyntax false" + hint: Disable this message with "git config set advice.refSyntax false" EOF test_must_fail git branch foo..bar >actual 2>&1 && test_cmp expect actual diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh index 6e587d27d7a5e3..800fc33165a9ef 100755 --- a/t/t3201-branch-contains.sh +++ b/t/t3201-branch-contains.sh @@ -2,7 +2,6 @@ test_description='branch --contains <commit>, --no-contains <commit> --merged, and --no-merged' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index 3b6dad0c466150..a1139f79e2ccfd 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -2,7 +2,6 @@ test_description='test show-branch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'error descriptions on empty repository' ' diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index e627f08a1790b3..a6bd88a58d0a8c 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -2,7 +2,6 @@ test_description='git branch display tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -369,6 +368,34 @@ test_expect_success 'git branch --format with ahead-behind' ' test_cmp expect actual ' +test_expect_success 'git branch `--sort=[-]ahead-behind` option' ' + cat >expect <<-\EOF && + (HEAD detached from fromtag) 0 0 + refs/heads/ambiguous 0 0 + refs/heads/branch-two 0 0 + refs/heads/branch-one 1 0 + refs/heads/main 1 0 + refs/heads/ref-to-branch 1 0 + refs/heads/ref-to-remote 1 0 + EOF + git branch --format="%(refname) %(ahead-behind:HEAD)" \ + --sort=refname --sort=ahead-behind:HEAD >actual && + test_cmp expect actual && + + cat >expect <<-\EOF && + (HEAD detached from fromtag) 0 0 + refs/heads/branch-one 1 0 + refs/heads/main 1 0 + refs/heads/ref-to-branch 1 0 + refs/heads/ref-to-remote 1 0 + refs/heads/ambiguous 0 0 + refs/heads/branch-two 0 0 + EOF + git branch --format="%(refname) %(ahead-behind:HEAD)" \ + --sort=refname --sort=-ahead-behind:HEAD >actual && + test_cmp expect actual +' + test_expect_success 'git branch with --format=%(rest) must fail' ' test_must_fail git branch --format="%(rest)" >actual ' diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh index 594e3e43e129a8..3399344f25dc85 100755 --- a/t/t3204-branch-name-interpretation.sh +++ b/t/t3204-branch-name-interpretation.sh @@ -9,7 +9,6 @@ This script aims to check the behavior of those corner cases. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh expect_branch() { diff --git a/t/t3205-branch-color.sh b/t/t3205-branch-color.sh index 0b61da92b37763..da1c202fa71345 100755 --- a/t/t3205-branch-color.sh +++ b/t/t3205-branch-color.sh @@ -1,7 +1,6 @@ #!/bin/sh test_description='basic branch output coloring' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up some sample branches' ' diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index 86010931ab6243..e091df6d01da90 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -5,7 +5,6 @@ test_description='range-diff tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Note that because of the range-diff's heuristics, test_commit does more @@ -909,4 +908,20 @@ test_expect_success 'submodule changes are shown irrespective of diff.submodule' test_cmp expect actual ' +test_expect_success '--diff-merges' ' + renamed_oid=$(git rev-parse --short renamed-file) && + tree=$(git merge-tree unmodified renamed-file) && + clean=$(git commit-tree -m merge -p unmodified -p renamed-file $tree) && + clean_oid=$(git rev-parse --short $clean) && + conflict=$(git commit-tree -m merge -p unmodified -p renamed-file^ $tree) && + conflict_oid=$(git rev-parse --short $conflict) && + + git range-diff --diff-merges=1 $clean...$conflict >actual && + cat >expect <<-EOF && + 1: $renamed_oid < -: ------- s/12/B/ + 2: $clean_oid = 1: $conflict_oid merge + EOF + test_cmp expect actual +' + test_done diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh index 9cbc34fc5838b4..37b9d26f4b6ba8 100755 --- a/t/t3211-peel-ref.sh +++ b/t/t3211-peel-ref.sh @@ -4,7 +4,6 @@ test_description='tests for the peel_ref optimization of packed-refs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create annotated tag in refs/tags' ' diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index d3ac826283e1a1..f5bf16abcd8ce2 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -9,7 +9,6 @@ This test tries pathnames with funny characters in the working tree, index, and tree objects. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh HT=' ' diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 99137fb235731b..d6c50460d08648 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -5,7 +5,6 @@ test_description='Test commit notes' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh write_script fake_editor <<\EOF @@ -1567,4 +1566,67 @@ test_expect_success 'empty notes do not invoke the editor' ' git notes remove HEAD ' +test_expect_success 'git notes add with -m/-F invokes editor with -e' ' + test_commit 19th && + echo "edited" >expect && + MSG="$(cat expect)" git notes add -m "initial" -e && + git notes show >actual && + test_cmp expect actual && + git notes remove HEAD && + + # Add a note using -F and edit it + echo "initial" >note_file && + MSG="$(cat expect)" git notes add -F note_file -e && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'git notes append with -m/-F invokes the editor with -e' ' + test_commit 20th && + cat >expect <<-EOF && + initial + + edited + EOF + git notes add -m "initial" && + MSG="edited" git notes append -m "appended" -e && + + # Verify the note content was appended and edited + git notes show >actual && + test_cmp expect actual && + git notes remove HEAD && + + # Append a note using -F and edit it + echo "note from file" >note_file && + git notes add -m "initial" && + MSG="edited" git notes append -F note_file -e && + + # Verify notes from file has been edited in editor and appended + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'git notes with a combination of -m, -F and -e invokes editor' ' + test_commit 21st && + echo "foo-file-1" >note_1 && + echo "foo-file-2" >note_2 && + echo "edited" >expect && + + MSG=$(cat expect) git notes append -F note_1 -m "message-1" -F note_2 -e && + + # Verify that combined messages from file and -m have been edited + git notes show >actual && + test_cmp expect actual +' +test_expect_success 'git notes append aborts when editor fails with -e' ' + test_commit 22nd && + echo "foo-file-1" >note_1 && + + # Try to append a note with -F and -e, but make the editor fail + test_env GIT_EDITOR="false" test_must_fail git notes append -F note_1 -e && + + # Verify that no note was added due to editor failure + test_must_fail git notes show +' + test_done diff --git a/t/t3302-notes-index-expensive.sh b/t/t3302-notes-index-expensive.sh index d0c4d38b4d485d..bb5fea02a03a56 100755 --- a/t/t3302-notes-index-expensive.sh +++ b/t/t3302-notes-index-expensive.sh @@ -8,7 +8,6 @@ test_description='Test commit notes index (expensive!)' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_repo () { diff --git a/t/t3303-notes-subtrees.sh b/t/t3303-notes-subtrees.sh index bc9b791d1b9ed2..eac193757bf1a5 100755 --- a/t/t3303-notes-subtrees.sh +++ b/t/t3303-notes-subtrees.sh @@ -5,7 +5,6 @@ test_description='Test commit notes organized in subtrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh number_of_commits=100 diff --git a/t/t3304-notes-mixed.sh b/t/t3304-notes-mixed.sh index 2c3a2452668c51..03dfcd3954cee5 100755 --- a/t/t3304-notes-mixed.sh +++ b/t/t3304-notes-mixed.sh @@ -5,7 +5,6 @@ test_description='Test notes trees that also contain non-notes' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh number_of_commits=100 diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 1ec1fb6715efda..fcecdc94ff74c2 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -2,7 +2,6 @@ test_description='Test that adding/removing many notes triggers automatic fanout restructuring' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh path_has_fanout() { diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh index b6e9f643e3cd8d..8f4102ff9e446b 100755 --- a/t/t3306-notes-prune.sh +++ b/t/t3306-notes-prune.sh @@ -2,7 +2,6 @@ test_description='Test git notes prune' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: create a few commits with notes' ' diff --git a/t/t3307-notes-man.sh b/t/t3307-notes-man.sh index ae316502c4531b..1aa366a410e9a3 100755 --- a/t/t3307-notes-man.sh +++ b/t/t3307-notes-man.sh @@ -4,7 +4,6 @@ test_description='Examples from the git-notes man page Make sure the manual is not full of lies.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh index e1d05ff6bc986a..202702be1a78b7 100755 --- a/t/t3308-notes-merge.sh +++ b/t/t3308-notes-merge.sh @@ -5,7 +5,6 @@ test_description='Test merging of notes trees' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3309-notes-merge-auto-resolve.sh b/t/t3309-notes-merge-auto-resolve.sh index f55277f499dd57..9bd5dbf341fd81 100755 --- a/t/t3309-notes-merge-auto-resolve.sh +++ b/t/t3309-notes-merge-auto-resolve.sh @@ -5,7 +5,6 @@ test_description='Test notes merging with auto-resolving strategies' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Set up a notes merge scenario with all kinds of potential conflicts diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh index 04866b89bed314..597df5ebc0a582 100755 --- a/t/t3310-notes-merge-manual-resolve.sh +++ b/t/t3310-notes-merge-manual-resolve.sh @@ -5,7 +5,6 @@ test_description='Test notes merging with manual conflict resolution' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Set up a notes merge scenario with different kinds of conflicts diff --git a/t/t3311-notes-merge-fanout.sh b/t/t3311-notes-merge-fanout.sh index ce4144db0f24c7..5b675417e9bbf9 100755 --- a/t/t3311-notes-merge-fanout.sh +++ b/t/t3311-notes-merge-fanout.sh @@ -5,7 +5,6 @@ test_description='Test notes merging at various fanout levels' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh verify_notes () { diff --git a/t/t3320-notes-merge-worktrees.sh b/t/t3320-notes-merge-worktrees.sh index 0fd33280cf91f7..96243b72222420 100755 --- a/t/t3320-notes-merge-worktrees.sh +++ b/t/t3320-notes-merge-worktrees.sh @@ -8,7 +8,6 @@ test_description='Test merging of notes trees in multiple worktrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commit' ' diff --git a/t/t3321-notes-stripspace.sh b/t/t3321-notes-stripspace.sh index beca34605672d4..c4a7839540a99e 100755 --- a/t/t3321-notes-stripspace.sh +++ b/t/t3321-notes-stripspace.sh @@ -5,7 +5,6 @@ test_description='Test commit notes with stripspace behavior' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh MULTI_LF="$LF$LF$LF" diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 09f230eefb2cbc..c0c00fbb7b1e4e 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -11,7 +11,6 @@ among other things. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_AUTHOR_NAME=author@name @@ -456,4 +455,23 @@ test_expect_success 'rebase when inside worktree subdirectory' ' ) ' +test_expect_success 'git rebase --update-ref with core.commentChar and branch on worktree' ' + test_when_finished git branch -D base topic2 && + test_when_finished git checkout main && + test_when_finished git branch -D wt-topic && + test_when_finished git worktree remove wt-topic && + git checkout main && + git checkout -b base && + git checkout -b topic2 && + test_commit msg2 && + git worktree add wt-topic && + git checkout base && + test_commit msg3 && + git checkout topic2 && + GIT_SEQUENCE_EDITOR="cat >actual" git -c core.commentChar=% \ + rebase -i --update-refs base && + test_grep "% Ref refs/heads/wt-topic checked out at" actual && + test_grep "% Ref refs/heads/topic2 checked out at" actual +' + test_done diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh index 328c1d3a3f45bc..f18bae94507587 100755 --- a/t/t3401-rebase-and-am-rename.sh +++ b/t/t3401-rebase-and-am-rename.sh @@ -2,7 +2,6 @@ test_description='git rebase + directory rename tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 5c67d07ba3ecf6..761de63b6b9822 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -8,7 +8,6 @@ test_description='git rebase --merge test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh T="A quick brown fox diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index 4f1d6e8ea642e1..a1911c4a9d60e7 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -8,7 +8,6 @@ test_description='git rebase --merge --skip tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index f171af3061db95..2aee9789a2fae2 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -26,7 +26,6 @@ Initial setup: touch file "conflict". ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh @@ -281,8 +280,9 @@ test_expect_success 'stop on conflicting pick' ' test_cmp expect2 file1 && test "$(git diff --name-status | sed -n -e "/^U/s/^U[^a-z]*//p")" = file1 && - test 4 = $(grep -v "^#" < .git/rebase-merge/done | wc -l) && - test 0 = $(grep -c "^[^#]" < .git/rebase-merge/git-rebase-todo) + grep -v "^#" <.git/rebase-merge/done >actual && + test_line_count = 4 actual && + test 0 = $(grep -c "^[^#]" <.git/rebase-merge/git-rebase-todo) ' test_expect_success 'show conflicted patch' ' @@ -319,7 +319,8 @@ test_expect_success 'retain authorship' ' GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" && git tag twerp && git rebase -i --onto primary HEAD^ && - git show HEAD | grep "^Author: Twerp Snog" + git show HEAD >actual && + grep "^Author: Twerp Snog" actual ' test_expect_success 'retain authorship w/ conflicts' ' @@ -360,7 +361,8 @@ test_expect_success 'squash' ' ' test_expect_success 'retain authorship when squashing' ' - git show HEAD | grep "^Author: Twerp Snog" + git show HEAD >actual && + grep "^Author: Twerp Snog" actual ' test_expect_success '--continue tries to commit' ' @@ -374,7 +376,8 @@ test_expect_success '--continue tries to commit' ' FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue ) && test_cmp_rev HEAD^ new-branch1 && - git show HEAD | grep chouette + git show HEAD >actual && + grep chouette actual ' test_expect_success 'verbose flag is heeded, even after --continue' ' @@ -397,7 +400,9 @@ test_expect_success 'multi-squash only fires up editor once' ' git rebase -i $base ) && test $base = $(git rev-parse HEAD^) && - test 1 = $(git show | grep ONCE | wc -l) + git show >output && + grep ONCE output >actual && + test_line_count = 1 actual ' test_expect_success 'multi-fixup does not fire up editor' ' @@ -410,7 +415,8 @@ test_expect_success 'multi-fixup does not fire up editor' ' git rebase -i $base ) && test $base = $(git rev-parse HEAD^) && - test 0 = $(git show | grep NEVER | wc -l) && + git show >output && + ! grep NEVER output && git checkout @{-1} && git branch -D multi-fixup ' @@ -428,7 +434,9 @@ test_expect_success 'commit message used after conflict' ' git rebase --continue ) && test $base = $(git rev-parse HEAD^) && - test 1 = $(git show | grep ONCE | wc -l) && + git show >output && + grep ONCE output >actual && + test_line_count = 1 actual && git checkout @{-1} && git branch -D conflict-fixup ' @@ -446,7 +454,9 @@ test_expect_success 'commit message retained after conflict' ' git rebase --continue ) && test $base = $(git rev-parse HEAD^) && - test 2 = $(git show | grep TWICE | wc -l) && + git show >output && + grep TWICE output >actual && + test_line_count = 2 actual && git checkout @{-1} && git branch -D conflict-squash ' @@ -470,10 +480,10 @@ test_expect_success 'squash and fixup generate correct log messages' ' ) && git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup && test_cmp expect-squash-fixup actual-squash-fixup && - git cat-file commit HEAD@{2} | - grep "^# This is a combination of 3 commits\." && - git cat-file commit HEAD@{3} | - grep "^# This is a combination of 2 commits\." && + git cat-file commit HEAD@{2} >actual && + grep "^# This is a combination of 3 commits\." actual && + git cat-file commit HEAD@{3} >actual && + grep "^# This is a combination of 2 commits\." actual && git checkout @{-1} && git branch -D squash-fixup ' @@ -489,7 +499,9 @@ test_expect_success 'squash ignores comments' ' git rebase -i $base ) && test $base = $(git rev-parse HEAD^) && - test 1 = $(git show | grep ONCE | wc -l) && + git show >output && + grep ONCE output >actual && + test_line_count = 1 actual && git checkout @{-1} && git branch -D skip-comments ' @@ -505,7 +517,9 @@ test_expect_success 'squash ignores blank lines' ' git rebase -i $base ) && test $base = $(git rev-parse HEAD^) && - test 1 = $(git show | grep ONCE | wc -l) && + git show >output && + grep ONCE output >actual && + test_line_count = 1 actual && git checkout @{-1} && git branch -D skip-blank-lines ' @@ -572,7 +586,8 @@ test_expect_success '--continue tries to commit, even for "edit"' ' FAKE_COMMIT_MESSAGE="chouette!" git rebase --continue ) && test edited = $(git show HEAD:file7) && - git show HEAD | grep chouette && + git show HEAD >actual && + grep chouette actual && test $parent = $(git rev-parse HEAD^) ' @@ -757,19 +772,37 @@ test_expect_success 'reword' ' set_fake_editor && FAKE_LINES="1 2 3 reword 4" FAKE_COMMIT_MESSAGE="E changed" \ git rebase -i A && - git show HEAD | grep "E changed" && + git show HEAD >actual && + grep "E changed" actual && test $(git rev-parse primary) != $(git rev-parse HEAD) && test_cmp_rev primary^ HEAD^ && FAKE_LINES="1 2 reword 3 4" FAKE_COMMIT_MESSAGE="D changed" \ git rebase -i A && - git show HEAD^ | grep "D changed" && + git show HEAD^ >actual && + grep "D changed" actual && FAKE_LINES="reword 1 2 3 4" FAKE_COMMIT_MESSAGE="B changed" \ git rebase -i A && - git show HEAD~3 | grep "B changed" && + git show HEAD~3 >actual && + grep "B changed" actual && FAKE_LINES="1 r 2 pick 3 p 4" FAKE_COMMIT_MESSAGE="C changed" \ git rebase -i A ) && - git show HEAD~2 | grep "C changed" + git show HEAD~2 >actual && + grep "C changed" actual +' + +test_expect_success 'reword fast-forwarded empty commit' ' + git commit --allow-empty -m "empty commit" --only && + ( + set_fake_editor && + FAKE_COMMIT_AMEND=edited FAKE_LINES="reword 1" \ + git rebase -i HEAD^ + ) && + test_commit_message HEAD <<-\EOF + empty commit + + edited + EOF ' test_expect_success 'no uncommitted changes when rewording and the todo list is reloaded' ' @@ -1003,8 +1036,10 @@ test_expect_success 'rebase -i --root retain root commit author and message' ' set_fake_editor && FAKE_LINES="2" git rebase -i --root ) && - git cat-file commit HEAD | grep -q "^author Twerp Snog" && - git cat-file commit HEAD | grep -q "^different author$" + git cat-file commit HEAD >output && + grep -q "^author Twerp Snog" output && + git cat-file commit HEAD >actual && + grep -q "^different author$" actual ' test_expect_success 'rebase -i --root temporary sentinel commit' ' @@ -1013,7 +1048,8 @@ test_expect_success 'rebase -i --root temporary sentinel commit' ' set_fake_editor && test_must_fail env FAKE_LINES="2" git rebase -i --root ) && - git cat-file commit HEAD | grep "^tree $EMPTY_TREE" && + git cat-file commit HEAD >actual && + grep "^tree $EMPTY_TREE" actual && git rebase --abort ' @@ -1036,7 +1072,8 @@ test_expect_success 'rebase -i --root reword original root commit' ' FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \ git rebase -i --root ) && - git show HEAD^ | grep "A changed" && + git show HEAD^ >actual && + grep "A changed" actual && test -z "$(git show -s --format=%p HEAD^)" ' @@ -1048,7 +1085,8 @@ test_expect_success 'rebase -i --root reword new root commit' ' FAKE_LINES="reword 3 1" FAKE_COMMIT_MESSAGE="C changed" \ git rebase -i --root ) && - git show HEAD^ | grep "C changed" && + git show HEAD^ >actual && + grep "C changed" actual && test -z "$(git show -s --format=%p HEAD^)" ' @@ -1870,7 +1908,7 @@ test_expect_success '--update-refs adds commands with --rebase-merges' ' pick $(git log -1 --format=%h branch2~1) F pick $(git log -1 --format=%h branch2) I update-ref refs/heads/branch2 - label merge + label branch2 reset onto pick $(git log -1 --format=%h refs/heads/second) J update-ref refs/heads/second @@ -1881,7 +1919,7 @@ test_expect_success '--update-refs adds commands with --rebase-merges' ' update-ref refs/heads/third pick $(git log -1 --format=%h HEAD~2) M update-ref refs/heads/no-conflict-branch - merge -C $(git log -1 --format=%h HEAD~1) merge # merge + merge -C $(git log -1 --format=%h HEAD~1) branch2 # merge update-ref refs/heads/merge-branch EOF @@ -1917,18 +1955,17 @@ test_expect_success '--update-refs updates refs correctly' ' test_cmp_rev HEAD~1 refs/heads/third && test_cmp_rev HEAD refs/heads/no-conflict-branch && - cat >expect <<-\EOF && + q_to_tab >expect <<-\EOF && Successfully rebased and updated refs/heads/update-refs. Updated the following refs with --update-refs: - refs/heads/first - refs/heads/no-conflict-branch - refs/heads/second - refs/heads/third + Qrefs/heads/first + Qrefs/heads/no-conflict-branch + Qrefs/heads/second + Qrefs/heads/third EOF # Clear "Rebasing (X/Y)" progress lines and drop leading tabs. - sed -e "s/Rebasing.*Successfully/Successfully/g" -e "s/^\t//g" \ - <err >err.trimmed && + sed "s/Rebasing.*Successfully/Successfully/g" <err >err.trimmed && test_cmp expect err.trimmed ' @@ -2178,19 +2215,18 @@ test_expect_success '--update-refs: check failed ref update' ' test_must_fail git rebase --continue 2>err && grep "update_ref failed for ref '\''refs/heads/second'\''" err && - cat >expect <<-\EOF && + q_to_tab >expect <<-\EOF && Updated the following refs with --update-refs: - refs/heads/first - refs/heads/no-conflict-branch - refs/heads/third + Qrefs/heads/first + Qrefs/heads/no-conflict-branch + Qrefs/heads/third Failed to update the following refs with --update-refs: - refs/heads/second + Qrefs/heads/second EOF # Clear "Rebasing (X/Y)" progress lines and drop leading tabs. tail -n 6 err >err.last && - sed -e "s/Rebasing.*Successfully/Successfully/g" -e "s/^\t//g" \ - <err.last >err.trimmed && + sed "s/Rebasing.*Successfully/Successfully/g" <err.last >err.trimmed && test_cmp expect err.trimmed ' @@ -2236,20 +2272,20 @@ test_expect_success 'non-merge commands reject merge commits' ' error: ${SQ}pick${SQ} does not accept merge commits hint: ${SQ}pick${SQ} does not take a merge commit. If you wanted to hint: replay the merge, use ${SQ}merge -C${SQ} on the commit. - hint: Disable this message with "git config advice.rebaseTodoError false" + hint: Disable this message with "git config set advice.rebaseTodoError false" error: invalid line 1: pick $oid error: ${SQ}reword${SQ} does not accept merge commits hint: ${SQ}reword${SQ} does not take a merge commit. If you wanted to hint: replay the merge and reword the commit message, use hint: ${SQ}merge -c${SQ} on the commit - hint: Disable this message with "git config advice.rebaseTodoError false" + hint: Disable this message with "git config set advice.rebaseTodoError false" error: invalid line 2: reword $oid error: ${SQ}edit${SQ} does not accept merge commits hint: ${SQ}edit${SQ} does not take a merge commit. If you wanted to hint: replay the merge, use ${SQ}merge -C${SQ} on the commit, and then hint: ${SQ}break${SQ} to give the control back to you so that you can hint: do ${SQ}git commit --amend && git rebase --continue${SQ}. - hint: Disable this message with "git config advice.rebaseTodoError false" + hint: Disable this message with "git config set advice.rebaseTodoError false" error: invalid line 3: edit $oid error: cannot squash merge commit into another commit error: invalid line 4: fixup $oid diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh index 8979bc340734f8..2524331861869d 100755 --- a/t/t3405-rebase-malformed.sh +++ b/t/t3405-rebase-malformed.sh @@ -5,7 +5,6 @@ test_description='rebase should handle arbitrary git message' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index 82108b67e67c18..a1d7fa7f7c6965 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -5,7 +5,6 @@ test_description='messages from rebase operation' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index 2c3f38d45a8482..9f49c4228b6295 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -5,7 +5,6 @@ test_description='git rebase --abort tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh index 7b4607d72f2748..cde3562e3a64f7 100755 --- a/t/t3408-rebase-multi-line.sh +++ b/t/t3408-rebase-multi-line.sh @@ -5,7 +5,6 @@ test_description='rebasing a commit with multi-line first paragraph.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3409-rebase-environ.sh b/t/t3409-rebase-environ.sh index acaf5558dbe2e4..83ffb39d9ffdfd 100755 --- a/t/t3409-rebase-environ.sh +++ b/t/t3409-rebase-environ.sh @@ -2,7 +2,6 @@ test_description='git rebase interactive environment' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh index e75b3d0e07cb13..58371d8a5477f4 100755 --- a/t/t3412-rebase-root.sh +++ b/t/t3412-rebase-root.sh @@ -7,7 +7,6 @@ Tests if git rebase --root --onto <newparent> can rebase the root commit. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh log_with_names () { diff --git a/t/t3413-rebase-hook.sh b/t/t3413-rebase-hook.sh index 426ff098e1dc73..b4ff614987ed62 100755 --- a/t/t3413-rebase-hook.sh +++ b/t/t3413-rebase-hook.sh @@ -5,7 +5,6 @@ test_description='git rebase with its hook(s)' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index 22452ff84cb339..fcc40d6fe1fd5b 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -5,7 +5,6 @@ test_description='auto squash' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh index f8c4ed78c9ef7f..ea501f2b42b8cc 100755 --- a/t/t3416-rebase-onto-threedots.sh +++ b/t/t3416-rebase-onto-threedots.sh @@ -5,7 +5,6 @@ test_description='git rebase --onto A...B' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-rebase.sh" diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh index 22ee3a204598cf..96f2cf22fafd47 100755 --- a/t/t3417-rebase-whitespace-fix.sh +++ b/t/t3417-rebase-whitespace-fix.sh @@ -5,7 +5,6 @@ test_description='git rebase --whitespace=fix This test runs git rebase --whitespace=fix and make sure that it works. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # prepare initial revision of "file" with a blank line at the end diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index c0d29c2154f0b4..127216f7225aa4 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -5,7 +5,6 @@ test_description='git rebase --continue tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh index 6c61f240cf9874..7181f176b81365 100755 --- a/t/t3419-rebase-patch-id.sh +++ b/t/t3419-rebase-patch-id.sh @@ -5,7 +5,6 @@ test_description='git rebase - test patch id computation' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh scramble () { diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index b43046b3b0dfb8..ad3ba6a9848f8a 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -7,7 +7,6 @@ test_description='git rebase --autostash tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index 737af80bb3dbb2..f5b7807abd089d 100755 --- a/t/t3421-rebase-topology-linear.sh +++ b/t/t3421-rebase-topology-linear.sh @@ -2,7 +2,6 @@ test_description='basic rebase topology tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh index b40f26250b7e3d..b9408f9ba1285f 100755 --- a/t/t3422-rebase-incompatible-options.sh +++ b/t/t3422-rebase-incompatible-options.sh @@ -2,7 +2,6 @@ test_description='test if rebase detects and aborts on incompatible options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3423-rebase-reword.sh b/t/t3423-rebase-reword.sh index 2fab703d615485..4859bb8f722314 100755 --- a/t/t3423-rebase-reword.sh +++ b/t/t3423-rebase-reword.sh @@ -2,7 +2,6 @@ test_description='git rebase interactive with rewording' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh index 515c949ae37269..1ee6b00fd57726 100755 --- a/t/t3424-rebase-empty.sh +++ b/t/t3424-rebase-empty.sh @@ -2,7 +2,6 @@ test_description='git rebase of commits that start or become empty' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup test repository' ' diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh index a16428bdf54ab9..675491234a6155 100755 --- a/t/t3425-rebase-topology-merges.sh +++ b/t/t3425-rebase-topology-merges.sh @@ -2,7 +2,6 @@ test_description='rebase topology tests with merges' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3426-rebase-submodule.sh b/t/t3426-rebase-submodule.sh index 94ea88e384e621..ba069dccbdf561 100755 --- a/t/t3426-rebase-submodule.sh +++ b/t/t3426-rebase-submodule.sh @@ -2,7 +2,6 @@ test_description='rebase can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3428-rebase-signoff.sh b/t/t3428-rebase-signoff.sh index 365436ebfc3641..6f57aed9fac68f 100755 --- a/t/t3428-rebase-signoff.sh +++ b/t/t3428-rebase-signoff.sh @@ -5,7 +5,6 @@ test_description='git rebase --signoff This test runs git rebase --signoff and make sure that it works. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh index 8e0d03969a2fec..abd66f360213e1 100755 --- a/t/t3429-rebase-edit-todo.sh +++ b/t/t3429-rebase-edit-todo.sh @@ -2,7 +2,6 @@ test_description='rebase should reread the todo file if an exec modifies it' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 2aa8593f77af91..b84d68c4b96bc9 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -21,7 +21,6 @@ Initial setup: GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh . "$TEST_DIRECTORY"/lib-log-graph.sh @@ -108,19 +107,19 @@ test_expect_success 'generate correct todo list' ' reset onto pick $b B - label E + label first reset onto pick $c C label branch-point pick $f F pick $g G - label H + label second reset branch-point # C pick $d D - merge -C $e E # E - merge -C $h H # H + merge -C $e first # E + merge -C $h second # H EOF @@ -462,11 +461,11 @@ test_expect_success 'A root commit can be a cousin, treat it that way' ' ' test_expect_success 'labels that are object IDs are rewritten' ' - git checkout -b third B && + git checkout --detach B && test_commit I && third=$(git rev-parse HEAD) && git checkout -b labels main && - git merge --no-commit third && + git merge --no-commit $third && test_tick && git commit -m "Merge commit '\''$third'\'' into labels" && echo noop >script-from-scratch && @@ -611,4 +610,24 @@ test_expect_success 'truncate label names' ' grep "label 0123456789-$" out ' +test_expect_success 'reword fast-forwarded empty merge commit' ' + oid="$(git commit-tree -m "D1" -p A D^{tree})" && + oid="$(git commit-tree -m "empty merge" -p D -p $oid D^{tree})" && + + write_script sequence-editor.sh <<-\EOF && + sed /^merge/s/-C/-c/ "$1" >"$1.tmp" + mv "$1.tmp" "$1" + EOF + + ( + test_set_sequence_editor "$(pwd)/sequence-editor.sh" && + GIT_EDITOR="echo edited >>" git rebase -i -r D $oid + ) && + test_commit_message HEAD <<-\EOF + empty merge + + edited + EOF +' + test_done diff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh index 0bb284d61dbfae..be09fc78c16aab 100755 --- a/t/t3431-rebase-fork-point.sh +++ b/t/t3431-rebase-fork-point.sh @@ -8,7 +8,6 @@ test_description='git rebase --fork-point test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # A---B---D---E (main) @@ -74,7 +73,7 @@ test_rebase 'G F C D B A' --onto D main test_rebase 'G F C B A' --keep-base refs/heads/main test_rebase 'G F C B A' --keep-base main -test_expect_success 'git rebase --fork-point with ambigous refname' ' +test_expect_success 'git rebase --fork-point with ambiguous refname' ' git checkout main && git checkout -b one && git checkout side && diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index 7f1a5dd3deb10b..5086e14c022071 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -8,7 +8,6 @@ test_description='ensure rebase fast-forwards commits when possible' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3433-rebase-across-mode-change.sh b/t/t3433-rebase-across-mode-change.sh index c8172b0852233b..05df964670f49d 100755 --- a/t/t3433-rebase-across-mode-change.sh +++ b/t/t3433-rebase-across-mode-change.sh @@ -2,7 +2,6 @@ test_description='git rebase across mode change' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh index 26a48d6b1039a5..8c94fdffc43044 100755 --- a/t/t3434-rebase-i18n.sh +++ b/t/t3434-rebase-i18n.sh @@ -17,9 +17,14 @@ Initial setup: 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 ICONV +then + skip_all='skipping rebase i18n tests; iconv not available' + test_done +fi + compare_msg () { iconv -f "$2" -t "$3" "$TEST_DIRECTORY/t3434/$1" >expect && git cat-file commit HEAD >raw && diff --git a/t/t3435-rebase-gpg-sign.sh b/t/t3435-rebase-gpg-sign.sh index 6e329fea7c0fac..6aa2aeb628d0ed 100755 --- a/t/t3435-rebase-gpg-sign.sh +++ b/t/t3435-rebase-gpg-sign.sh @@ -8,7 +8,6 @@ test_description='test rebase --[no-]gpg-sign' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-rebase.sh" . "$TEST_DIRECTORY/lib-gpg.sh" diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh index 4d9744e5fc7ade..94671d3c465046 100755 --- a/t/t3436-rebase-more-options.sh +++ b/t/t3436-rebase-more-options.sh @@ -5,7 +5,6 @@ test_description='tests to ensure compatibility between am and interactive backends' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3437-rebase-fixup-options.sh b/t/t3437-rebase-fixup-options.sh index 7929e2e2e3a8fc..5d306a476928b1 100755 --- a/t/t3437-rebase-fixup-options.sh +++ b/t/t3437-rebase-fixup-options.sh @@ -14,7 +14,6 @@ to the "fixup" command that works with "fixup!", "fixup -C" works with "amend!" upon --autosquash. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh @@ -127,6 +126,21 @@ test_expect_success 'fixup -C with conflicts gives correct message' ' test_cmp expected-author actual-author ' +test_expect_success 'conflicting fixup -C after fixup with custom comment string' ' + test_config core.commentString COMMENT && + test_when_finished "test_might_fail git rebase --abort" && + git checkout --detach A3 && + test_must_fail env FAKE_LINES="1 fixup 2 fixup_-C 4" git rebase -i A && + echo resolved >A && + git add A && + FAKE_COMMIT_AMEND=edited git rebase --continue && + test_commit_message HEAD <<-\EOF + A3 + + edited + EOF +' + test_expect_success 'skipping fixup -C after fixup gives correct message' ' test_when_finished "test_might_fail git rebase --abort" && git checkout --detach A3 && diff --git a/t/t3438-rebase-broken-files.sh b/t/t3438-rebase-broken-files.sh index 821f08e5afb698..78d42f4c799f14 100755 --- a/t/t3438-rebase-broken-files.sh +++ b/t/t3438-rebase-broken-files.sh @@ -2,7 +2,6 @@ test_description='rebase behavior when on-disk files are broken' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up conflicting branches' ' diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh index 61ca87512d59dc..78c3eac54b599e 100755 --- a/t/t3500-cherry.sh +++ b/t/t3500-cherry.sh @@ -11,7 +11,6 @@ checks that git cherry only returns the second patch in the local branch GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_AUTHOR_EMAIL=bogus_email_address diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 411027fb58c7df..8025a28cfddb08 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -5,7 +5,6 @@ test_description='miscellaneous basic tests for cherry-pick and revert' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -178,7 +177,7 @@ test_expect_success 'advice from failed revert' ' hint: You can instead skip this commit with "git revert --skip". hint: To abort and get back to the state before "git revert", hint: run "git revert --abort". - hint: Disable this message with "git config advice.mergeConflict false" + hint: Disable this message with "git config set advice.mergeConflict false" EOF test_commit --append --no-tag "double-add dream" dream dream && test_must_fail git revert HEAD^ 2>actual && @@ -228,6 +227,20 @@ test_expect_success 'identification of reverted commit (--reference)' ' test_cmp expect actual ' +test_expect_success 'git revert --reference with core.commentChar' ' + test_when_finished "git reset --hard to-ident" && + git checkout --detach to-ident && + GIT_EDITOR="head -n4 >actual" git -c core.commentChar=% revert \ + --edit --reference HEAD && + cat <<-EOF >expect && + % *** SAY WHY WE ARE REVERTING ON THE TITLE LINE *** + + This reverts commit $(git show -s --pretty=reference HEAD^). + + EOF + test_cmp expect actual +' + test_expect_success 'identification of reverted commit (revert.reference)' ' git checkout --detach to-ident && git -c revert.reference=true revert --no-edit HEAD && diff --git a/t/t3502-cherry-pick-merge.sh b/t/t3502-cherry-pick-merge.sh index 1b2c0d6aca64e0..5495eacfec11a9 100755 --- a/t/t3502-cherry-pick-merge.sh +++ b/t/t3502-cherry-pick-merge.sh @@ -11,7 +11,6 @@ test_description='cherry picking and reverting a merge GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3503-cherry-pick-root.sh b/t/t3503-cherry-pick-root.sh index 76d393dc8a307e..95fe4feaeee98f 100755 --- a/t/t3503-cherry-pick-root.sh +++ b/t/t3503-cherry-pick-root.sh @@ -5,7 +5,6 @@ test_description='test cherry-picking (and reverting) a root commit' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3504-cherry-pick-rerere.sh b/t/t3504-cherry-pick-rerere.sh index 597c98e9c57753..18aeba161c0ae4 100755 --- a/t/t3504-cherry-pick-rerere.sh +++ b/t/t3504-cherry-pick-rerere.sh @@ -5,7 +5,6 @@ test_description='cherry-pick should rerere for conflicts' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -43,7 +42,7 @@ test_expect_success 'cherry-pick conflict with --rerere-autoupdate' ' git reset --hard bar-dev ' -test_expect_success 'cherry-pick conflict repsects rerere.autoUpdate' ' +test_expect_success 'cherry-pick conflict respects rerere.autoUpdate' ' test_config rerere.autoUpdate true && test_must_fail git cherry-pick foo..bar-main && test_cmp foo-expect foo && diff --git a/t/t3505-cherry-pick-empty.sh b/t/t3505-cherry-pick-empty.sh index ead3fb46807ef3..9748443530cd71 100755 --- a/t/t3505-cherry-pick-empty.sh +++ b/t/t3505-cherry-pick-empty.sh @@ -5,7 +5,6 @@ test_description='test cherry-picking an empty commit' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh index b71bad17b853c5..7e11bd4a4c5c41 100755 --- a/t/t3506-cherry-pick-ff.sh +++ b/t/t3506-cherry-pick-ff.sh @@ -5,7 +5,6 @@ test_description='test cherry-picking with --ff option' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 10e9c91dbbd0f0..44596cb1e8036c 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -13,7 +13,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pristine_detach () { @@ -35,7 +34,7 @@ test_expect_success setup ' git commit --allow-empty --allow-empty-message && git tag empty && git checkout main && - git config advice.detachedhead false + git config set advice.detachedhead false ' @@ -61,7 +60,7 @@ test_expect_success 'advice from failed cherry-pick' ' hint: You can instead skip this commit with "git cherry-pick --skip". hint: To abort and get back to the state before "git cherry-pick", hint: run "git cherry-pick --abort". - hint: Disable this message with "git config advice.mergeConflict false" + hint: Disable this message with "git config set advice.mergeConflict false" EOF test_must_fail git cherry-pick picked 2>actual && @@ -76,7 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' " error: could not apply \$picked... picked hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' - hint: Disable this message with \"git config advice.mergeConflict false\" + hint: Disable this message with \"git config set advice.mergeConflict false\" EOF test_must_fail git cherry-pick --no-commit picked 2>actual && diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh index afa7727a4af8e4..2d53ce754c5fb7 100755 --- a/t/t3508-cherry-pick-many-commits.sh +++ b/t/t3508-cherry-pick-many-commits.sh @@ -5,7 +5,6 @@ test_description='test cherry-picking many commits' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_head_differs_from() { diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh index 171cc6d76b797c..f4159246e1e35d 100755 --- a/t/t3509-cherry-pick-merge-df.sh +++ b/t/t3509-cherry-pick-merge-df.sh @@ -4,7 +4,6 @@ test_description='Test cherry-pick with directory/file conflicts' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'Initialize repository' ' diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh index 93c725bac3cb3e..66ff9db2702a35 100755 --- a/t/t3510-cherry-pick-sequence.sh +++ b/t/t3510-cherry-pick-sequence.sh @@ -12,7 +12,6 @@ test_description='Test cherry-pick continuation features ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Repeat first match 10 times @@ -26,7 +25,7 @@ pristine_detach () { } test_expect_success setup ' - git config advice.detachedhead false && + git config set advice.detachedhead false && echo unrelated >unrelated && git add unrelated && test_commit initial foo a && diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh index dd5d92ef302124..98ef13f0a32576 100755 --- a/t/t3511-cherry-pick-x.sh +++ b/t/t3511-cherry-pick-x.sh @@ -2,7 +2,6 @@ test_description='Test cherry-pick -x and -s' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pristine_detach () { @@ -52,7 +51,7 @@ trailing empty lines " test_expect_success setup ' - git config advice.detachedhead false && + git config set advice.detachedhead false && echo unrelated >unrelated && git add unrelated && test_commit initial foo a && diff --git a/t/t3512-cherry-pick-submodule.sh b/t/t3512-cherry-pick-submodule.sh index 9387a22a9e7100..f22d1ddead1ac9 100755 --- a/t/t3512-cherry-pick-submodule.sh +++ b/t/t3512-cherry-pick-submodule.sh @@ -5,7 +5,6 @@ test_description='cherry-pick can handle submodules' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t3513-revert-submodule.sh b/t/t3513-revert-submodule.sh index e178968b408f4b..8bfe3ed2467fa1 100755 --- a/t/t3513-revert-submodule.sh +++ b/t/t3513-revert-submodule.sh @@ -2,7 +2,6 @@ test_description='revert can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 31ac31d4bcd3bb..98259e2adaa9db 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -8,7 +8,6 @@ test_description='Test of the various options to git rm.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Setup some files to be removed, some with funny characters diff --git a/t/t3601-rm-pathspec-file.sh b/t/t3601-rm-pathspec-file.sh index 7cef12981c4be0..31bd9960fcde39 100755 --- a/t/t3601-rm-pathspec-file.sh +++ b/t/t3601-rm-pathspec-file.sh @@ -2,7 +2,6 @@ test_description='rm --pathspec-from-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t3602-rm-sparse-checkout.sh b/t/t3602-rm-sparse-checkout.sh index fcdefba48cc76b..02c7acd61784ad 100755 --- a/t/t3602-rm-sparse-checkout.sh +++ b/t/t3602-rm-sparse-checkout.sh @@ -2,7 +2,6 @@ test_description='git rm in sparse checked out working trees' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' " @@ -21,7 +20,7 @@ test_expect_success 'setup' " hint: If you intend to update such entries, try one of the following: hint: * Use the --sparse option. hint: * Disable or modify the sparsity rules. - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF echo b | cat sparse_error_header - >sparse_entry_b_error && diff --git a/t/t3650-replay-basics.sh b/t/t3650-replay-basics.sh index 12bd3db4cb7463..389670262e458e 100755 --- a/t/t3650-replay-basics.sh +++ b/t/t3650-replay-basics.sh @@ -5,7 +5,6 @@ test_description='basic git replay tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_AUTHOR_NAME=author@name diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 839c904745a286..df580a5806b4f1 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -5,7 +5,6 @@ test_description='Test of git add, including the -- option.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-unique-files.sh @@ -32,7 +31,7 @@ test_expect_success 'Test with no pathspecs' ' cat >expect <<-EOF && Nothing specified, nothing added. hint: Maybe you wanted to say ${SQ}git add .${SQ}? - hint: Disable this message with "git config advice.addEmptyPathspec false" + hint: Disable this message with "git config set advice.addEmptyPathspec false" EOF git add 2>actual && test_cmp expect actual @@ -376,7 +375,7 @@ test_expect_success '"git add" a embedded repository' ' hint: git rm --cached inner1 hint: hint: See "git help submodule" for more information. - hint: Disable this message with "git config advice.addEmbeddedRepo false" + hint: Disable this message with "git config set advice.addEmbeddedRepo false" warning: adding embedded git repository: inner2 EOF test_cmp expect actual @@ -414,7 +413,7 @@ cat >expect.err <<\EOF The following paths are ignored by one of your .gitignore files: ignored-file hint: Use -f if you really want to add them. -hint: Disable this message with "git config advice.addIgnoredFile false" +hint: Disable this message with "git config set advice.addIgnoredFile false" EOF cat >expect.out <<\EOF add 'track-this' diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 718438ffc7d2a8..b8a05d95f3f130 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -4,7 +4,6 @@ test_description='add -i basic tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t3702-add-edit.sh b/t/t3702-add-edit.sh index 82bfb2fd2aca9e..8bacacbac6807c 100755 --- a/t/t3702-add-edit.sh +++ b/t/t3702-add-edit.sh @@ -5,7 +5,6 @@ test_description='add -e basic tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t3703-add-magic-pathspec.sh b/t/t3703-add-magic-pathspec.sh index d84071038e0515..3ef525a559d91b 100755 --- a/t/t3703-add-magic-pathspec.sh +++ b/t/t3703-add-magic-pathspec.sh @@ -2,7 +2,6 @@ test_description='magic pathspec tests using git-add' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3704-add-pathspec-file.sh b/t/t3704-add-pathspec-file.sh index 3aa59f6f639b5b..b9c96e273fb71a 100755 --- a/t/t3704-add-pathspec-file.sh +++ b/t/t3704-add-pathspec-file.sh @@ -2,7 +2,6 @@ test_description='add --pathspec-from-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t3705-add-sparse-checkout.sh b/t/t3705-add-sparse-checkout.sh index 6ae45a788d1a97..53a4782267b705 100755 --- a/t/t3705-add-sparse-checkout.sh +++ b/t/t3705-add-sparse-checkout.sh @@ -2,7 +2,6 @@ test_description='git add in sparse checked out working trees' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh SPARSE_ENTRY_BLOB="" @@ -55,7 +54,7 @@ test_expect_success 'setup' " hint: If you intend to update such entries, try one of the following: hint: * Use the --sparse option. hint: * Disable or modify the sparsity rules. - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF echo sparse_entry | cat sparse_error_header - >sparse_entry_error && diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index d3e428ff46eb5c..e3cf0ffbe59c44 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -4,7 +4,6 @@ test_description='git mktag: tag object verify test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh ########################################################### diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index db7b403bc1541d..3c930ec202d682 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -5,9 +5,14 @@ test_description='commit and log output encodings' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +if ! test_have_prereq ICONV +then + skip_all='skipping commit i18n tests; iconv not available' + test_done +fi + compare_with () { git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' >current && case "$3" in diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh index 5f0b9afc3faa7d..f03601b49a9397 100755 --- a/t/t3901-i18n-patch.sh +++ b/t/t3901-i18n-patch.sh @@ -8,9 +8,14 @@ test_description='i18n settings and format-patch | am pipe' 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 ICONV +then + skip_all='skipping patch i18n tests; iconv not available' + test_done +fi + check_encoding () { # Make sure characters are not corrupted cnt="$1" header="$2" i=1 j=0 diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh index 72a5a565e973ad..f528008c363c68 100755 --- a/t/t3902-quoted.sh +++ b/t/t3902-quoted.sh @@ -5,7 +5,6 @@ test_description='quoted output' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh FN='濱野' diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index c87592ee2f39fe..74666ff3e4b2b8 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -8,7 +8,6 @@ test_description='Test git stash' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-unique-files.sh diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh index aa5019fd6c3d59..ae313e3c705e46 100755 --- a/t/t3904-stash-patch.sh +++ b/t/t3904-stash-patch.sh @@ -2,7 +2,6 @@ test_description='stash -p' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-patch-mode.sh test_expect_success 'setup' ' diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh index a1733f45c3aa13..1289ae3e07c635 100755 --- a/t/t3905-stash-include-untracked.sh +++ b/t/t3905-stash-include-untracked.sh @@ -5,7 +5,6 @@ test_description='Test git stash --include-untracked' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'stash save --include-untracked some dirty working directory' ' diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh index 0f61f01ef43b2c..0f7348ec21b882 100755 --- a/t/t3906-stash-submodule.sh +++ b/t/t3906-stash-submodule.sh @@ -2,7 +2,6 @@ test_description='stash can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t3907-stash-show-config.sh b/t/t3907-stash-show-config.sh index 7a2eb98b86426e..10914bba7b3737 100755 --- a/t/t3907-stash-show-config.sh +++ b/t/t3907-stash-show-config.sh @@ -2,7 +2,6 @@ test_description='Test git stash show configuration.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3908-stash-in-worktree.sh b/t/t3908-stash-in-worktree.sh index 347a89b030b68d..2b2b366ef94b7c 100755 --- a/t/t3908-stash-in-worktree.sh +++ b/t/t3908-stash-in-worktree.sh @@ -5,7 +5,6 @@ test_description='Test git stash in a worktree' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3920-crlf-messages.sh b/t/t3920-crlf-messages.sh index 50ae222f08424e..e2e1251a057f24 100755 --- a/t/t3920-crlf-messages.sh +++ b/t/t3920-crlf-messages.sh @@ -2,7 +2,6 @@ test_description='Test ref-filter and pretty APIs for commit and tag messages using CRLF' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh LIB_CRLF_BRANCHES="" @@ -82,7 +81,7 @@ test_crlf_subject_body_and_contents() { test_expect_success 'Setup refs with commit and tag messages using CRLF' ' - test_commit inital && + test_commit initial && create_crlf_refs ' diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh index 8d50331b8c8e43..a51f881b1c9ee0 100755 --- a/t/t4000-diff-format.sh +++ b/t/t4000-diff-format.sh @@ -10,7 +10,6 @@ same command line parser, so testing one should be sufficient; pick diff-files as a representative. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index cd1931dd555702..4f520d600de495 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -5,7 +5,6 @@ test_description='Test rename detection in diff engine.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index cb3307010c1ed9..e44648e6f3d9ff 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -7,7 +7,6 @@ test_description='Test diff raw-output. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh diff --git a/t/t4003-diff-rename-1.sh b/t/t4003-diff-rename-1.sh index ebe091828c878e..fd4faee5d252c5 100755 --- a/t/t4003-diff-rename-1.sh +++ b/t/t4003-diff-rename-1.sh @@ -7,7 +7,6 @@ test_description='More rename detection ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh index 1d70d4d221b753..faf3465deb48a1 100755 --- a/t/t4004-diff-rename-symlink.sh +++ b/t/t4004-diff-rename-symlink.sh @@ -10,7 +10,6 @@ copy of symbolic links, but should not produce rename/copy followed by an edit for them. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4005-diff-rename-2.sh b/t/t4005-diff-rename-2.sh index 5c756dc24358cf..92d1141fbe08e1 100755 --- a/t/t4005-diff-rename-2.sh +++ b/t/t4005-diff-rename-2.sh @@ -6,7 +6,6 @@ test_description='Same rename detection as t4003 but testing diff-raw.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index dbd4c0da213eb4..2299b91fc4b3cd 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -7,7 +7,6 @@ test_description='Test mode change diffs. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sed_script='s/\(:100644 100755\) \('"$OID_REGEX"'\) \2 /\1 X X /' diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh index b86165cbac5970..e8faf0dd2ef1c5 100755 --- a/t/t4007-rename-3.sh +++ b/t/t4007-rename-3.sh @@ -7,7 +7,6 @@ test_description='Rename interaction with pathspec. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh index 562aaf3a2a295e..c187c52dab20e2 100755 --- a/t/t4008-diff-break-rewrite.sh +++ b/t/t4008-diff-break-rewrite.sh @@ -21,6 +21,7 @@ With -B, this should be detected as two complete rewrites. Further, with -B and -M together, these should turn into two renames. ' + . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh index 3480781dabf30a..59e71e3acdea54 100755 --- a/t/t4009-diff-rename-4.sh +++ b/t/t4009-diff-rename-4.sh @@ -7,7 +7,6 @@ test_description='Same rename detection as t4003 but testing diff-raw -z. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 9d9650eba7e977..c84c3fa05b218e 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -10,7 +10,6 @@ Prepare: path1/file1 ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index bc8ba887191fac..ac837b6c9ecd7b 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -7,7 +7,6 @@ test_description='Test diff of symlinks. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index c64d9d2f405e1e..d1d30ac2a9474e 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -6,7 +6,6 @@ test_description='Binary diff and apply ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect.binary-numstat <<\EOF diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 87d248d0347ae0..3855d68dbc0a64 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -8,7 +8,6 @@ test_description='Various diff formatting options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 1c46e963e4326b..884f83fb8a45fe 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -8,7 +8,6 @@ test_description='various format-patch tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 851cfe4f32cd8d..52e3e476ffa5a9 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -7,7 +7,6 @@ test_description='Test special whitespace in diff engine. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh index 5a8d8876831657..876271d6826cca 100755 --- a/t/t4016-diff-quote.sh +++ b/t/t4016-diff-quote.sh @@ -6,7 +6,6 @@ test_description='Quoting paths in diff output. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh P0='pathname' diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh index 1cea73ef5a31a5..c2863c99b71fac 100755 --- a/t/t4017-diff-retval.sh +++ b/t/t4017-diff-retval.sh @@ -5,7 +5,6 @@ test_description='Return value of diffs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 8128c30e7f2c65..e026fac1f40903 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -5,7 +5,6 @@ test_description='Test custom diff function name patterns' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index d2b3109c2d3744..4001dacee39193 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -2,7 +2,6 @@ test_description='diff whitespace error detection' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index 3baa52a9bf653d..f1efe482a59427 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -2,7 +2,6 @@ test_description='external diff interface test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -102,7 +101,7 @@ test_expect_success 'diff attribute' ' test_cmp expect actual ' -test_expect_success !SANITIZE_LEAK 'diff attribute should apply only to diff' ' +test_expect_success 'diff attribute should apply only to diff' ' git log -p -1 HEAD >out && grep "^diff --git a/file b/file" out @@ -129,7 +128,7 @@ test_expect_success 'diff attribute' ' test_cmp expect actual ' -test_expect_success !SANITIZE_LEAK 'diff attribute should apply only to diff' ' +test_expect_success 'diff attribute should apply only to diff' ' git log -p -1 HEAD >out && grep "^diff --git a/file b/file" out diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh index 1219aa226dc725..9be65fd4440a68 100755 --- a/t/t4021-format-patch-numbered.sh +++ b/t/t4021-format-patch-numbered.sh @@ -5,7 +5,6 @@ test_description='Format-patch numbering options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh index e2f0eca4af0650..b98ac0a0c039c0 100755 --- a/t/t4024-diff-optimize-common.sh +++ b/t/t4024-diff-optimize-common.sh @@ -2,7 +2,6 @@ test_description='common tail optimization' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh z=zzzzzzzz ;# 8 diff --git a/t/t4025-hunk-header.sh b/t/t4025-hunk-header.sh index 5397cb7d42d748..c39bb07a417a5d 100755 --- a/t/t4025-hunk-header.sh +++ b/t/t4025-hunk-header.sh @@ -2,7 +2,6 @@ test_description='diff hunk header truncation' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh N='日本語' diff --git a/t/t4026-color.sh b/t/t4026-color.sh index b05f2a9b6075d0..08f6805e1c87c9 100755 --- a/t/t4026-color.sh +++ b/t/t4026-color.sh @@ -5,7 +5,6 @@ test_description='Test diff/status color escape codes' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh ESC=$(printf '\033') diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 40164ae07d2c06..295da987cce5c8 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -2,7 +2,6 @@ test_description='difference in submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4028-format-patch-mime-headers.sh b/t/t4028-format-patch-mime-headers.sh index 60cb819c42e4bc..a06a7479260fa9 100755 --- a/t/t4028-format-patch-mime-headers.sh +++ b/t/t4028-format-patch-mime-headers.sh @@ -2,7 +2,6 @@ test_description='format-patch mime headers and extra headers do not conflict' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create commit with utf-8 body' ' diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh index 5f8ffef74b6474..32b6e9a4e76217 100755 --- a/t/t4029-diff-trailing-space.sh +++ b/t/t4029-diff-trailing-space.sh @@ -4,7 +4,6 @@ # test_description='diff honors config option, diff.suppressBlankEmpty' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat <<\EOF >expected || diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index 29f6d610c2e61b..daebf9796f595b 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -2,7 +2,6 @@ test_description='diff.*.textconv tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh find_diff() { diff --git a/t/t4032-diff-inter-hunk-context.sh b/t/t4032-diff-inter-hunk-context.sh index 7db92d0d9f461a..bada0cbd32f764 100755 --- a/t/t4032-diff-inter-hunk-context.sh +++ b/t/t4032-diff-inter-hunk-context.sh @@ -2,7 +2,6 @@ test_description='diff hunk fusing' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh f() { diff --git a/t/t4033-diff-patience.sh b/t/t4033-diff-patience.sh index f7be7f5ef0139b..113304dc596034 100755 --- a/t/t4033-diff-patience.sh +++ b/t/t4033-diff-patience.sh @@ -2,7 +2,6 @@ test_description='patience diff algorithm' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-alternative.sh diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 4dcd7e99250ed1..f51d3557f101cf 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -2,7 +2,6 @@ test_description='word diff colors' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh index 76f8034c60fabe..0352bf81a90a38 100755 --- a/t/t4035-diff-quiet.sh +++ b/t/t4035-diff-quiet.sh @@ -2,7 +2,6 @@ test_description='Return value of diffs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4036-format-patch-signer-mime.sh b/t/t4036-format-patch-signer-mime.sh index 48655bcc789eef..98d9713d8b2454 100755 --- a/t/t4036-format-patch-signer-mime.sh +++ b/t/t4036-format-patch-signer-mime.sh @@ -2,7 +2,6 @@ test_description='format-patch -s should force MIME encoding as needed' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4037-diff-r-t-dirs.sh b/t/t4037-diff-r-t-dirs.sh index b5f96fe23bd214..f5ce3b29a2ac75 100755 --- a/t/t4037-diff-r-t-dirs.sh +++ b/t/t4037-diff-r-t-dirs.sh @@ -2,7 +2,6 @@ test_description='diff -r -t shows directory additions and deletions' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh index 78090e6852d5a8..0eb0314a8b35da 100755 --- a/t/t4039-diff-assume-unchanged.sh +++ b/t/t4039-diff-assume-unchanged.sh @@ -2,7 +2,6 @@ test_description='diff with assume-unchanged entries' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # external diff has been tested in t4020-diff-external.sh diff --git a/t/t4040-whitespace-status.sh b/t/t4040-whitespace-status.sh index eec3d73dc2b475..1b27a0e3813cc8 100755 --- a/t/t4040-whitespace-status.sh +++ b/t/t4040-whitespace-status.sh @@ -2,7 +2,6 @@ test_description='diff --exit-code with whitespace' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh index 8fc40e75eb3c78..28f9d83d4c1c34 100755 --- a/t/t4041-diff-submodule-option.sh +++ b/t/t4041-diff-submodule-option.sh @@ -12,15 +12,20 @@ This test tries to verify the sanity of the --submodule option of git diff. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -# Tested non-UTF-8 encoding -test_encoding="ISO8859-1" +# Test non-UTF-8 encoding in case iconv is available. +if test_have_prereq ICONV +then + test_encoding="ISO8859-1" + # String "added" in German (translated with Google Translate), encoded in UTF-8, + # used in sample commit log messages in add_file() function below. + added=$(printf "hinzugef\303\274gt") +else + test_encoding="UTF-8" + added="added" +fi -# String "added" in German (translated with Google Translate), encoded in UTF-8, -# used in sample commit log messages in add_file() function below. -added=$(printf "hinzugef\303\274gt") add_file () { ( cd "$1" && diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh index a179205394d8a3..ff0e73531b90ed 100755 --- a/t/t4042-diff-textconv-caching.sh +++ b/t/t4042-diff-textconv-caching.sh @@ -2,7 +2,6 @@ test_description='test textconv caching' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >helper <<'EOF' diff --git a/t/t4043-diff-rename-binary.sh b/t/t4043-diff-rename-binary.sh index e4864939081a8c..2a2cf91352037b 100755 --- a/t/t4043-diff-rename-binary.sh +++ b/t/t4043-diff-rename-binary.sh @@ -5,7 +5,6 @@ test_description='Move a binary file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t4044-diff-index-unique-abbrev.sh b/t/t4044-diff-index-unique-abbrev.sh index 9f6043dabaccdc..8400bfbd3c7e0e 100755 --- a/t/t4044-diff-index-unique-abbrev.sh +++ b/t/t4044-diff-index-unique-abbrev.sh @@ -2,7 +2,6 @@ test_description='test unique sha1 abbreviation on "index from..to" line' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh index 9b46c4c1befece..2c8493fe66c441 100755 --- a/t/t4045-diff-relative.sh +++ b/t/t4045-diff-relative.sh @@ -2,7 +2,6 @@ test_description='diff --relative tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4046-diff-unmerged.sh b/t/t4046-diff-unmerged.sh index afda629c98137f..7c27f053663fb7 100755 --- a/t/t4046-diff-unmerged.sh +++ b/t/t4046-diff-unmerged.sh @@ -2,7 +2,6 @@ test_description='diff with unmerged index entries' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4047-diff-dirstat.sh b/t/t4047-diff-dirstat.sh index 7b73462d53d2c1..a7ce8d3161bb13 100755 --- a/t/t4047-diff-dirstat.sh +++ b/t/t4047-diff-dirstat.sh @@ -2,7 +2,6 @@ test_description='diff --dirstat tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # set up two commits where the second commit has these files diff --git a/t/t4048-diff-combined-binary.sh b/t/t4048-diff-combined-binary.sh index f399484bcef623..0260cf64f5d550 100755 --- a/t/t4048-diff-combined-binary.sh +++ b/t/t4048-diff-combined-binary.sh @@ -4,7 +4,6 @@ test_description='combined and merge diff handle binary files and textconv' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup binary merge conflict' ' diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh index 0a4fc735d44ad5..eceb47c8594416 100755 --- a/t/t4049-diff-stat-count.sh +++ b/t/t4049-diff-stat-count.sh @@ -3,7 +3,6 @@ test_description='diff --stat-count' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4050-diff-histogram.sh b/t/t4050-diff-histogram.sh index c61b30f96daf57..fd3e86a74f3d92 100755 --- a/t/t4050-diff-histogram.sh +++ b/t/t4050-diff-histogram.sh @@ -2,7 +2,6 @@ test_description='histogram diff algorithm' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-alternative.sh diff --git a/t/t4051-diff-function-context.sh b/t/t4051-diff-function-context.sh index 725278ad19c720..4838a1df8b4369 100755 --- a/t/t4051-diff-function-context.sh +++ b/t/t4051-diff-function-context.sh @@ -2,7 +2,6 @@ test_description='diff function context' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh dir="$TEST_DIRECTORY/t4051" diff --git a/t/t4052-stat-output.sh b/t/t4052-stat-output.sh index 7badd72488d664..740bb9709181ab 100755 --- a/t/t4052-stat-output.sh +++ b/t/t4052-stat-output.sh @@ -8,7 +8,6 @@ test_description='test --stat output of various commands' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 651ec776606bb0..5e5bad61ca1ed8 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -2,7 +2,6 @@ test_description='diff --no-index' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4054-diff-bogus-tree.sh b/t/t4054-diff-bogus-tree.sh index 05c88f8cdf01d9..1131431fe0e3ce 100755 --- a/t/t4054-diff-bogus-tree.sh +++ b/t/t4054-diff-bogus-tree.sh @@ -2,7 +2,6 @@ test_description='test diff with a bogus tree containing the null sha1' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create bogus tree' ' diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index 3ea9ae99e04b93..f7ff234cf9366e 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -5,7 +5,6 @@ test_description='diff.context configuration' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh index 9a7505cbb8bf90..04b8a1542a8ec3 100755 --- a/t/t4057-diff-combined-paths.sh +++ b/t/t4057-diff-combined-paths.sh @@ -5,7 +5,6 @@ test_description='combined diff show only paths that are different to all parent GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # verify that diffc.expect matches output of diff --git a/t/t4058-diff-duplicates.sh b/t/t4058-diff-duplicates.sh index 2501c89c1c91ec..2fce4a98977b71 100755 --- a/t/t4058-diff-duplicates.sh +++ b/t/t4058-diff-duplicates.sh @@ -10,6 +10,7 @@ # that the diff output isn't wildly unreasonable. test_description='test tree diff when trees have duplicate entries' + . ./test-lib.sh # make_tree_entry <mode> <mode> <sha1> @@ -132,22 +133,23 @@ test_expect_success 'create a few commits' ' rm commit_id up final ' -test_expect_failure 'git read-tree does not segfault' ' - test_when_finished rm .git/index.lock && - test_might_fail git read-tree --reset base +test_expect_success 'git read-tree does not segfault' ' + test_must_fail git read-tree --reset base 2>err && + test_grep "error: corrupted cache-tree has entries not present in index" err ' -test_expect_failure 'reset --hard does not segfault' ' - test_when_finished rm .git/index.lock && +test_expect_success 'reset --hard does not segfault' ' git checkout base && - test_might_fail git reset --hard + test_must_fail git reset --hard 2>err && + test_grep "error: corrupted cache-tree has entries not present in index" err ' -test_expect_failure 'git diff HEAD does not segfault' ' +test_expect_success 'git diff HEAD does not segfault' ' git checkout base && GIT_TEST_CHECK_CACHE_TREE=false && git reset --hard && - test_might_fail git diff HEAD + test_must_fail git diff HEAD 2>err && + test_grep "error: corrupted cache-tree has entries not present in index" err ' test_expect_failure 'can switch to another branch when status is empty' ' diff --git a/t/t4059-diff-submodule-not-initialized.sh b/t/t4059-diff-submodule-not-initialized.sh index 668f5263038374..0fe81056d5be68 100755 --- a/t/t4059-diff-submodule-not-initialized.sh +++ b/t/t4059-diff-submodule-not-initialized.sh @@ -9,15 +9,20 @@ This test tries to verify that add_submodule_odb works when the submodule was initialized previously but the checkout has since been removed. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -# Tested non-UTF-8 encoding -test_encoding="ISO8859-1" -# String "added" in German (translated with Google Translate), encoded in UTF-8, -# used in sample commit log messages in add_file() function below. -added=$(printf "hinzugef\303\274gt") +# Test non-UTF-8 encoding in case iconv is available. +if test_have_prereq ICONV +then + test_encoding="ISO8859-1" + # String "added" in German (translated with Google Translate), encoded in UTF-8, + # used in sample commit log messages in add_file() function below. + added=$(printf "hinzugef\303\274gt") +else + test_encoding="UTF-8" + added="added" +fi add_file () { ( diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh index 8ce67442d96b2c..76b83101d3b7b6 100755 --- a/t/t4060-diff-submodule-option-diff-format.sh +++ b/t/t4060-diff-submodule-option-diff-format.sh @@ -10,15 +10,19 @@ test_description='Support for diff format verbose submodule difference in git di This test tries to verify the sanity of --submodule=diff option of git diff. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -# Tested non-UTF-8 encoding -test_encoding="ISO8859-1" - -# String "added" in German (translated with Google Translate), encoded in UTF-8, -# used in sample commit log messages in add_file() function below. -added=$(printf "hinzugef\303\274gt") +# Test non-UTF-8 encoding in case iconv is available. +if test_have_prereq ICONV +then + test_encoding="ISO8859-1" + # String "added" in German (translated with Google Translate), encoded in UTF-8, + # used in sample commit log messages in add_file() function below. + added=$(printf "hinzugef\303\274gt") +else + test_encoding="UTF-8" + added="added" +fi add_file () { ( diff --git a/t/t4061-diff-indent.sh b/t/t4061-diff-indent.sh index 2942e5d9b93899..7750b87ca16ab3 100755 --- a/t/t4061-diff-indent.sh +++ b/t/t4061-diff-indent.sh @@ -6,7 +6,6 @@ test_description='Test diff indent heuristic. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4062-diff-pickaxe.sh b/t/t4062-diff-pickaxe.sh index a90b46b678ca35..8ad3d799579230 100755 --- a/t/t4062-diff-pickaxe.sh +++ b/t/t4062-diff-pickaxe.sh @@ -5,7 +5,6 @@ test_description='Pickaxe options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4063-diff-blobs.sh b/t/t4063-diff-blobs.sh index 7e6c9d638433ca..50fdb5ea529234 100755 --- a/t/t4063-diff-blobs.sh +++ b/t/t4063-diff-blobs.sh @@ -2,7 +2,6 @@ test_description='test direct comparison of blobs via git-diff' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh run_diff () { diff --git a/t/t4064-diff-oidfind.sh b/t/t4064-diff-oidfind.sh index 846f285f772e53..e86bba679e516d 100755 --- a/t/t4064-diff-oidfind.sh +++ b/t/t4064-diff-oidfind.sh @@ -2,7 +2,6 @@ test_description='test finding specific blobs in the revision walking' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ' ' diff --git a/t/t4065-diff-anchored.sh b/t/t4065-diff-anchored.sh index 647537c12ea99d..b3f510f040ec3b 100755 --- a/t/t4065-diff-anchored.sh +++ b/t/t4065-diff-anchored.sh @@ -2,7 +2,6 @@ test_description='anchored diff algorithm' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success '--anchored' ' diff --git a/t/t4066-diff-emit-delay.sh b/t/t4066-diff-emit-delay.sh index 0ecb3915412fcd..a1de63b77f8b41 100755 --- a/t/t4066-diff-emit-delay.sh +++ b/t/t4066-diff-emit-delay.sh @@ -4,7 +4,6 @@ test_description='test combined/stat/moved interaction' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test covers a weird 3-way interaction between "--cc -p", which will run diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh index 7af3a08862dec8..581250dd2d227a 100755 --- a/t/t4067-diff-partial-clone.sh +++ b/t/t4067-diff-partial-clone.sh @@ -2,7 +2,6 @@ test_description='behavior of diff when reading objects in a partial clone' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'git show batches blobs' ' diff --git a/t/t4068-diff-symmetric-merge-base.sh b/t/t4068-diff-symmetric-merge-base.sh index 4d6565e728bccd..eff63c16b064d1 100755 --- a/t/t4068-diff-symmetric-merge-base.sh +++ b/t/t4068-diff-symmetric-merge-base.sh @@ -5,7 +5,6 @@ test_description='behavior of diff with symmetric-diff setups and --merge-base' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # build these situations: diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh index df342850a0d420..c6c94aef14d5cd 100755 --- a/t/t4069-remerge-diff.sh +++ b/t/t4069-remerge-diff.sh @@ -2,7 +2,6 @@ test_description='remerge-diff handling' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test is ort-specific @@ -353,4 +352,11 @@ test_expect_success 'remerge-diff turns off history simplification' ' test_cmp expect actual ' +test_expect_success 'remerge-diff with --reverse' ' + git log -1 --remerge-diff --oneline ab_resolution^ >expect && + git log -1 --remerge-diff --oneline ab_resolution >>expect && + git log -2 --remerge-diff --oneline ab_resolution --reverse >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh index d503547732c54d..a5664f3eb3c675 100755 --- a/t/t4100-apply-stat.sh +++ b/t/t4100-apply-stat.sh @@ -7,7 +7,6 @@ test_description='git apply --stat --summary test, with --recount ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh UNC='s/^\(@@ -[1-9][0-9]*\),[0-9]* \(+[1-9][0-9]*\),[0-9]* @@/\1,999 \2,999 @@/' @@ -39,4 +38,17 @@ incomplete (1) incomplete (2) EOF +test_expect_success 'applying a hunk header which overflows fails' ' + cat >patch <<-\EOF && + diff -u a/file b/file + --- a/file + +++ b/file + @@ -98765432109876543210 +98765432109876543210 @@ + -a + +b + EOF + test_must_fail git apply patch 2>err && + echo "error: corrupt patch at line 4" >expect && + test_cmp expect err +' test_done diff --git a/t/t4101-apply-nonl.sh b/t/t4101-apply-nonl.sh index b1169193ef5d53..4df74baa24955a 100755 --- a/t/t4101-apply-nonl.sh +++ b/t/t4101-apply-nonl.sh @@ -7,7 +7,6 @@ test_description='git apply should handle files with incomplete lines. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh index d1e06fc1ac4135..e42a31c9179dfe 100755 --- a/t/t4102-apply-rename.sh +++ b/t/t4102-apply-rename.sh @@ -7,7 +7,6 @@ test_description='git apply handling copy/rename patch. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index 144619ab873f5d..d370ecfe0d9eea 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -9,7 +9,6 @@ test_description='git apply handling binary patches GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh index dc501aac387b26..71ef4132d153b7 100755 --- a/t/t4104-apply-boundary.sh +++ b/t/t4104-apply-boundary.sh @@ -5,7 +5,6 @@ test_description='git apply boundary tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh L="c d e f g h i j k l m n o p q r s t u v w x" diff --git a/t/t4105-apply-fuzz.sh b/t/t4105-apply-fuzz.sh index ed814a839e679d..b59785166d49a3 100755 --- a/t/t4105-apply-fuzz.sh +++ b/t/t4105-apply-fuzz.sh @@ -3,7 +3,6 @@ test_description='apply with fuzz and offset' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh dotest () { diff --git a/t/t4106-apply-stdin.sh b/t/t4106-apply-stdin.sh index 5c150f3b0b2391..aa2fff7afa72a5 100755 --- a/t/t4106-apply-stdin.sh +++ b/t/t4106-apply-stdin.sh @@ -3,7 +3,6 @@ test_description='git apply --numstat - <patch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4107-apply-ignore-whitespace.sh b/t/t4107-apply-ignore-whitespace.sh index 5e6e203aa521ea..94ba6dd4e00966 100755 --- a/t/t4107-apply-ignore-whitespace.sh +++ b/t/t4107-apply-ignore-whitespace.sh @@ -5,7 +5,6 @@ test_description='git-apply --ignore-whitespace.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This primes main.c file that indents without using HT at all. diff --git a/t/t4108-apply-threeway.sh b/t/t4108-apply-threeway.sh index c6302163d848a7..f30e85659dbb87 100755 --- a/t/t4108-apply-threeway.sh +++ b/t/t4108-apply-threeway.sh @@ -5,7 +5,6 @@ test_description='git apply --3way' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh print_sanitized_conflicted_diff () { diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh index 4dc6d8e7d3c8bb..ac523a5d5622ea 100755 --- a/t/t4109-apply-multifrag.sh +++ b/t/t4109-apply-multifrag.sh @@ -7,7 +7,6 @@ test_description='git apply test patches with multiple fragments.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cp "$TEST_DIRECTORY/t4109/patch1.patch" . diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh index 266302a1829da4..cc17ff2ab9ac09 100755 --- a/t/t4110-apply-scan.sh +++ b/t/t4110-apply-scan.sh @@ -8,7 +8,6 @@ test_description='git apply test for patches which require scanning forwards and ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'git apply scan' ' diff --git a/t/t4111-apply-subdir.sh b/t/t4111-apply-subdir.sh index e9a87d761d1683..1618a6dbc7c718 100755 --- a/t/t4111-apply-subdir.sh +++ b/t/t4111-apply-subdir.sh @@ -2,7 +2,6 @@ test_description='patching from inconvenient places' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4112-apply-renames.sh b/t/t4112-apply-renames.sh index d53aa4222ea3c1..bb5d529bec1ab2 100755 --- a/t/t4112-apply-renames.sh +++ b/t/t4112-apply-renames.sh @@ -8,7 +8,6 @@ test_description='git apply should not get confused with rename/copy. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4113-apply-ending.sh b/t/t4113-apply-ending.sh index 2c65c6a16960a0..66fa51591eb7ee 100755 --- a/t/t4113-apply-ending.sh +++ b/t/t4113-apply-ending.sh @@ -6,7 +6,6 @@ test_description='git apply trying to add an ending line. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh index 8ff36407667374..da3e64f8110d54 100755 --- a/t/t4114-apply-typechange.sh +++ b/t/t4114-apply-typechange.sh @@ -7,7 +7,6 @@ test_description='git apply should not get confused with type changes. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup repository and commits' ' diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index cbef0a593fb7cc..769b0e4f9df06b 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -7,7 +7,6 @@ test_description='git apply symlinks and partial files ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index a9f4ddda6c3bd6..0784ba033a4e5a 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -8,7 +8,6 @@ test_description='git apply in reverse ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh index 4d15ccd28ecb27..c86d05a96fe8d5 100755 --- a/t/t4117-apply-reject.sh +++ b/t/t4117-apply-reject.sh @@ -7,7 +7,6 @@ test_description='git apply with rejects ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh index 69c9c48e72b493..c1dcbd7d356449 100755 --- a/t/t4118-apply-empty-context.sh +++ b/t/t4118-apply-empty-context.sh @@ -8,7 +8,6 @@ test_description='git apply with new style GNU diff with empty context ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh index 208c961d376b28..f3b43e221627a7 100755 --- a/t/t4119-apply-config.sh +++ b/t/t4119-apply-config.sh @@ -8,7 +8,6 @@ test_description='git apply --whitespace=strip and configuration file. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index f7884285400f50..697e86c0ff4560 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -5,7 +5,6 @@ test_description='git apply -p handling.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh index a80cec9d1193be..b45454aaf4bfe6 100755 --- a/t/t4121-apply-diffs.sh +++ b/t/t4121-apply-diffs.sh @@ -4,7 +4,6 @@ test_description='git apply for contextually independent diffs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh echo '1 diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh index 2089d84f64577b..3340ab4370c77a 100755 --- a/t/t4122-apply-symlink-inside.sh +++ b/t/t4122-apply-symlink-inside.sh @@ -4,7 +4,6 @@ test_description='apply to deeper directory without getting fooled with symlink' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4123-apply-shrink.sh b/t/t4123-apply-shrink.sh index 3601c0c5dca5aa..3ef84619f53e27 100755 --- a/t/t4123-apply-shrink.sh +++ b/t/t4123-apply-shrink.sh @@ -2,7 +2,6 @@ test_description='apply a patch that is larger than the preimage' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >F <<\EOF diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index cdffee0273c9ff..485c7d2d124ade 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -2,7 +2,6 @@ test_description='core.whitespace rules and git apply' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh prepare_test_file () { diff --git a/t/t4125-apply-ws-fuzz.sh b/t/t4125-apply-ws-fuzz.sh index f248cc2a0084d5..090987c89b24b4 100755 --- a/t/t4125-apply-ws-fuzz.sh +++ b/t/t4125-apply-ws-fuzz.sh @@ -2,7 +2,6 @@ test_description='applying patch that has broken whitespaces in context' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4126-apply-empty.sh b/t/t4126-apply-empty.sh index 56210b5609919d..eff783f8d683a6 100755 --- a/t/t4126-apply-empty.sh +++ b/t/t4126-apply-empty.sh @@ -2,7 +2,6 @@ test_description='apply empty' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh index aa5cfae2b681c0..bd516c4aad757b 100755 --- a/t/t4127-apply-same-fn.sh +++ b/t/t4127-apply-same-fn.sh @@ -3,7 +3,6 @@ test_description='apply same filename' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh modify () { diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index ed94c90204e9c2..f6db5a79dd9d35 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -2,7 +2,6 @@ test_description='apply same filename' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index 87ffd2b8e1a3d3..2149ad5da44cde 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -3,7 +3,6 @@ test_description='applying patch with mode bits' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4130-apply-criss-cross-rename.sh b/t/t4130-apply-criss-cross-rename.sh index f3ea63274258c6..211ef1c7e78e8f 100755 --- a/t/t4130-apply-criss-cross-rename.sh +++ b/t/t4130-apply-criss-cross-rename.sh @@ -2,7 +2,6 @@ test_description='git apply handling criss-cross rename patch.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_file() { diff --git a/t/t4131-apply-fake-ancestor.sh b/t/t4131-apply-fake-ancestor.sh index 40c92115a66e83..b1361ce54693a0 100755 --- a/t/t4131-apply-fake-ancestor.sh +++ b/t/t4131-apply-fake-ancestor.sh @@ -5,7 +5,6 @@ test_description='git apply --build-fake-ancestor handling.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4132-apply-removal.sh b/t/t4132-apply-removal.sh index c1e3049c041b84..ab1628d27d0a31 100755 --- a/t/t4132-apply-removal.sh +++ b/t/t4132-apply-removal.sh @@ -5,7 +5,6 @@ test_description='git-apply notices removal patches generated by GNU diff' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4133-apply-filenames.sh b/t/t4133-apply-filenames.sh index c21ddb29466ec4..3cab1038cf5648 100755 --- a/t/t4133-apply-filenames.sh +++ b/t/t4133-apply-filenames.sh @@ -6,7 +6,6 @@ test_description='git apply filename consistency check' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh index aceb4c42b0ffc7..8cea75cf7bc230 100755 --- a/t/t4134-apply-submodule.sh +++ b/t/t4134-apply-submodule.sh @@ -6,7 +6,6 @@ test_description='git apply submodule tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4135-apply-weird-filenames.sh b/t/t4135-apply-weird-filenames.sh index d3502c6fddf5a6..6bc3fb97a754bf 100755 --- a/t/t4135-apply-weird-filenames.sh +++ b/t/t4135-apply-weird-filenames.sh @@ -2,7 +2,6 @@ test_description='git apply with weird postimage filenames' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4136-apply-check.sh b/t/t4136-apply-check.sh index dfec1c5f0f63fc..82f2f2e4753455 100755 --- a/t/t4136-apply-check.sh +++ b/t/t4136-apply-check.sh @@ -3,7 +3,6 @@ test_description='git apply should exit non-zero with unrecognized input.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4137-apply-submodule.sh b/t/t4137-apply-submodule.sh index ebd0d4ad17c1bf..07d52625375d4b 100755 --- a/t/t4137-apply-submodule.sh +++ b/t/t4137-apply-submodule.sh @@ -2,7 +2,6 @@ test_description='git apply handling submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t4138-apply-ws-expansion.sh b/t/t4138-apply-ws-expansion.sh index 7981931b4ed76a..8bbf8260fa6b98 100755 --- a/t/t4138-apply-ws-expansion.sh +++ b/t/t4138-apply-ws-expansion.sh @@ -5,7 +5,6 @@ test_description='git apply test patches with whitespace expansion.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4139-apply-escape.sh b/t/t4139-apply-escape.sh index e5c7439df13389..e07fb9ef089ab4 100755 --- a/t/t4139-apply-escape.sh +++ b/t/t4139-apply-escape.sh @@ -2,7 +2,6 @@ test_description='paths written by git-apply cannot escape the working tree' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # tests will try to write to ../foo, and we do not diff --git a/t/t4140-apply-ita.sh b/t/t4140-apply-ita.sh index b375aca0d74ea3..c614eaf04cca93 100755 --- a/t/t4140-apply-ita.sh +++ b/t/t4140-apply-ita.sh @@ -2,7 +2,6 @@ test_description='git apply of i-t-a file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4141-apply-too-large.sh b/t/t4141-apply-too-large.sh index 20cc1209f6259c..eac6f7e151b562 100755 --- a/t/t4141-apply-too-large.sh +++ b/t/t4141-apply-too-large.sh @@ -2,7 +2,6 @@ test_description='git apply with too-large patch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success EXPENSIVE 'git apply rejects patches that are too large' ' diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 232e1394e8d925..5e2b6c80eaedfc 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -5,7 +5,6 @@ test_description='git am running' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: messages' ' diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index 1825a89d6a98cb..edb38da7010d33 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -2,7 +2,6 @@ test_description='am --abort' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4152-am-subjects.sh b/t/t4152-am-subjects.sh index 9f2edba1f833a7..768495b131547d 100755 --- a/t/t4152-am-subjects.sh +++ b/t/t4152-am-subjects.sh @@ -2,7 +2,6 @@ test_description='test subject preservation with format-patch | am' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh make_patches() { diff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh index dd6ad8f7a80d96..9bec989a0ed71c 100755 --- a/t/t4153-am-resume-override-opts.sh +++ b/t/t4153-am-resume-override-opts.sh @@ -2,7 +2,6 @@ test_description='git-am command-line options override saved options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh format_patch () { diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 213b36fb96242b..b0a3e84984185d 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -25,7 +25,6 @@ test_description='git rerere GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index c20c88572445dc..5f23fc147bb88d 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -9,7 +9,6 @@ test_description='git shortlog GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -105,7 +104,7 @@ test_expect_success 'output from user-defined format is re-wrapped' ' test_cmp expect log.predictable ' -test_expect_success !MINGW 'shortlog wrapping' ' +test_expect_success !MINGW,ICONV 'shortlog wrapping' ' cat >expect <<\EOF && A U Thor (5): Test @@ -126,13 +125,13 @@ EOF test_cmp expect out ' -test_expect_success !MINGW 'shortlog from non-git directory' ' +test_expect_success !MINGW,ICONV 'shortlog from non-git directory' ' git log --no-expand-tabs HEAD >log && GIT_DIR=non-existing git shortlog -w <log >out && test_cmp expect out ' -test_expect_success !MINGW 'shortlog can read --format=raw output' ' +test_expect_success !MINGW,ICONV 'shortlog can read --format=raw output' ' git log --format=raw HEAD >log && GIT_DIR=non-existing git shortlog -w <log >out && test_cmp expect out @@ -143,6 +142,10 @@ test_expect_success 'shortlog from non-git directory refuses extra arguments' ' test_grep "too many arguments" out ' +test_expect_success 'shortlog --author from non-git directory does not segfault' ' + nongit git shortlog --author=author </dev/null +' + test_expect_success 'shortlog should add newline when input line matches wraplen' ' cat >expect <<\EOF && A U Thor (2): @@ -182,7 +185,7 @@ $DSCHO (2): EOF -test_expect_success !MINGW 'shortlog encoding' ' +test_expect_success !MINGW,ICONV 'shortlog encoding' ' git reset --hard "$commit" && git config --unset i18n.commitencoding && echo 2 > a1 && diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh index 2265ff8872df9c..4a6242ff99b59e 100755 --- a/t/t4203-mailmap.sh +++ b/t/t4203-mailmap.sh @@ -5,7 +5,6 @@ test_description='.mailmap configurations' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commits and contacts file' ' @@ -114,6 +113,18 @@ test_expect_success 'check-mailmap --stdin simple address: no mapping' ' test_cmp expect actual ' +test_expect_success 'check-mailmap name and address: mapping' ' + test_when_finished "rm .mailmap" && + cat >.mailmap <<-EOF && + Bug Reports <bugs-new@company.xx> Bugs <bugs@company.xx> + EOF + cat >expect <<-EOF && + <bugs@company.xx> + EOF + git check-mailmap "bugs@company.xx" >actual && + test_cmp expect actual +' + test_expect_success 'No mailmap' ' cat >expect <<-EOF && $GIT_AUTHOR_NAME (1): diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index eb63ce011fa646..f81e42a84d5adc 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -6,7 +6,6 @@ test_description='Test pretty formats' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Tested non-UTF-8 encoding @@ -114,19 +113,19 @@ test_expect_success 'alias loop' ' test_must_fail git log --pretty=test-foo ' -test_expect_success 'NUL separation' ' +test_expect_success ICONV 'NUL separation' ' printf "add bar\0$(commit_msg)" >expected && git log -z --pretty="format:%s" >actual && test_cmp expected actual ' -test_expect_success 'NUL termination' ' +test_expect_success ICONV 'NUL termination' ' printf "add bar\0$(commit_msg)\0" >expected && git log -z --pretty="tformat:%s" >actual && test_cmp expected actual ' -test_expect_success 'NUL separation with --stat' ' +test_expect_success ICONV 'NUL separation with --stat' ' stat0_part=$(git diff --stat HEAD^ HEAD) && stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) && printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n" >expected && @@ -137,7 +136,7 @@ test_expect_success 'NUL separation with --stat' ' test_expect_failure 'NUL termination with --stat' ' stat0_part=$(git diff --stat HEAD^ HEAD) && stat1_part=$(git diff-tree --no-commit-id --stat --root HEAD^) && - printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n0" >expected && + printf "add bar\n$stat0_part\n\0$(commit_msg)\n$stat1_part\n\0" >expected && git log -z --stat --pretty="tformat:%s" >actual && test_cmp expected actual ' @@ -181,7 +180,7 @@ test_expect_success 'setup more commits' ' head4=$(git rev-parse --verify --short HEAD~3) ' -test_expect_success 'left alignment formatting' ' +test_expect_success ICONV 'left alignment formatting' ' git log --pretty="tformat:%<(40)%s" >actual && qz_to_tab_space <<-EOF >expected && message two Z @@ -192,7 +191,7 @@ test_expect_success 'left alignment formatting' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting. i18n.logOutputEncoding' ' +test_expect_success ICONV 'left alignment formatting. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(40)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && message two Z @@ -203,7 +202,7 @@ test_expect_success 'left alignment formatting. i18n.logOutputEncoding' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting at the nth column' ' +test_expect_success ICONV 'left alignment formatting at the nth column' ' git log --pretty="tformat:%h %<|(40)%s" >actual && qz_to_tab_space <<-EOF >expected && $head1 message two Z @@ -214,7 +213,7 @@ test_expect_success 'left alignment formatting at the nth column' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting at the nth column' ' +test_expect_success ICONV 'left alignment formatting at the nth column' ' COLUMNS=50 git log --pretty="tformat:%h %<|(-10)%s" >actual && qz_to_tab_space <<-EOF >expected && $head1 message two Z @@ -225,7 +224,7 @@ test_expect_success 'left alignment formatting at the nth column' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting at the nth column. i18n.logOutputEncoding' ' +test_expect_success ICONV 'left alignment formatting at the nth column. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %<|(40)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && $head1 message two Z @@ -236,7 +235,7 @@ test_expect_success 'left alignment formatting at the nth column. i18n.logOutput test_cmp expected actual ' -test_expect_success 'left alignment formatting with no padding' ' +test_expect_success ICONV 'left alignment formatting with no padding' ' git log --pretty="tformat:%<(1)%s" >actual && cat <<-EOF >expected && message two @@ -258,7 +257,7 @@ test_expect_success 'left alignment formatting with no padding. i18n.logOutputEn test_cmp expected actual ' -test_expect_success 'left alignment formatting with trunc' ' +test_expect_success ICONV 'left alignment formatting with trunc' ' git log --pretty="tformat:%<(10,trunc)%s" >actual && qz_to_tab_space <<-\EOF >expected && message .. @@ -269,7 +268,7 @@ test_expect_success 'left alignment formatting with trunc' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncoding' ' +test_expect_success ICONV 'left alignment formatting with trunc. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,trunc)%s" >actual && qz_to_tab_space <<-\EOF | iconv -f utf-8 -t $test_encoding >expected && message .. @@ -280,7 +279,7 @@ test_expect_success 'left alignment formatting with trunc. i18n.logOutputEncodin test_cmp expected actual ' -test_expect_success 'left alignment formatting with ltrunc' ' +test_expect_success ICONV 'left alignment formatting with ltrunc' ' git log --pretty="tformat:%<(10,ltrunc)%s" >actual && qz_to_tab_space <<-EOF >expected && ..sage two @@ -291,7 +290,7 @@ test_expect_success 'left alignment formatting with ltrunc' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncoding' ' +test_expect_success ICONV 'left alignment formatting with ltrunc. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,ltrunc)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && ..sage two @@ -302,7 +301,7 @@ test_expect_success 'left alignment formatting with ltrunc. i18n.logOutputEncodi test_cmp expected actual ' -test_expect_success 'left alignment formatting with mtrunc' ' +test_expect_success ICONV 'left alignment formatting with mtrunc' ' git log --pretty="tformat:%<(10,mtrunc)%s" >actual && qz_to_tab_space <<-\EOF >expected && mess.. two @@ -313,7 +312,7 @@ test_expect_success 'left alignment formatting with mtrunc' ' test_cmp expected actual ' -test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncoding' ' +test_expect_success ICONV 'left alignment formatting with mtrunc. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,mtrunc)%s" >actual && qz_to_tab_space <<-\EOF | iconv -f utf-8 -t $test_encoding >expected && mess.. two @@ -324,7 +323,7 @@ test_expect_success 'left alignment formatting with mtrunc. i18n.logOutputEncodi test_cmp expected actual ' -test_expect_success 'right alignment formatting' ' +test_expect_success ICONV 'right alignment formatting' ' git log --pretty="tformat:%>(40)%s" >actual && qz_to_tab_space <<-EOF >expected && Z message two @@ -335,7 +334,7 @@ test_expect_success 'right alignment formatting' ' test_cmp expected actual ' -test_expect_success 'right alignment formatting. i18n.logOutputEncoding' ' +test_expect_success ICONV 'right alignment formatting. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(40)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && Z message two @@ -346,7 +345,7 @@ test_expect_success 'right alignment formatting. i18n.logOutputEncoding' ' test_cmp expected actual ' -test_expect_success 'right alignment formatting at the nth column' ' +test_expect_success ICONV 'right alignment formatting at the nth column' ' git log --pretty="tformat:%h %>|(40)%s" >actual && qz_to_tab_space <<-EOF >expected && $head1 message two @@ -357,7 +356,7 @@ test_expect_success 'right alignment formatting at the nth column' ' test_cmp expected actual ' -test_expect_success 'right alignment formatting at the nth column' ' +test_expect_success ICONV 'right alignment formatting at the nth column' ' COLUMNS=50 git log --pretty="tformat:%h %>|(-10)%s" >actual && qz_to_tab_space <<-EOF >expected && $head1 message two @@ -368,7 +367,7 @@ test_expect_success 'right alignment formatting at the nth column' ' test_cmp expected actual ' -test_expect_success 'right alignment formatting at the nth column. i18n.logOutputEncoding' ' +test_expect_success ICONV 'right alignment formatting at the nth column. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %>|(40)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && $head1 message two @@ -381,7 +380,7 @@ test_expect_success 'right alignment formatting at the nth column. i18n.logOutpu # Note: Space between 'message' and 'two' should be in the same column # as in previous test. -test_expect_success 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' ' +test_expect_success ICONV 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --graph --pretty="tformat:%h %>|(40)%s" >actual && iconv -f utf-8 -t $test_encoding >expected <<-EOF && * $head1 message two @@ -392,7 +391,7 @@ test_expect_success 'right alignment formatting at the nth column with --graph. test_cmp expected actual ' -test_expect_success 'right alignment formatting with no padding' ' +test_expect_success ICONV 'right alignment formatting with no padding' ' git log --pretty="tformat:%>(1)%s" >actual && cat <<-EOF >expected && message two @@ -403,7 +402,7 @@ test_expect_success 'right alignment formatting with no padding' ' test_cmp expected actual ' -test_expect_success 'right alignment formatting with no padding and with --graph' ' +test_expect_success ICONV 'right alignment formatting with no padding and with --graph' ' git log --graph --pretty="tformat:%>(1)%s" >actual && cat <<-EOF >expected && * message two @@ -414,7 +413,7 @@ test_expect_success 'right alignment formatting with no padding and with --graph test_cmp expected actual ' -test_expect_success 'right alignment formatting with no padding. i18n.logOutputEncoding' ' +test_expect_success ICONV 'right alignment formatting with no padding. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(1)%s" >actual && cat <<-EOF | iconv -f utf-8 -t $test_encoding >expected && message two @@ -425,7 +424,7 @@ test_expect_success 'right alignment formatting with no padding. i18n.logOutputE test_cmp expected actual ' -test_expect_success 'center alignment formatting' ' +test_expect_success ICONV 'center alignment formatting' ' git log --pretty="tformat:%><(40)%s" >actual && qz_to_tab_space <<-EOF >expected && Z message two Z @@ -436,7 +435,7 @@ test_expect_success 'center alignment formatting' ' test_cmp expected actual ' -test_expect_success 'center alignment formatting. i18n.logOutputEncoding' ' +test_expect_success ICONV 'center alignment formatting. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%><(40)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && Z message two Z @@ -446,7 +445,7 @@ test_expect_success 'center alignment formatting. i18n.logOutputEncoding' ' EOF test_cmp expected actual ' -test_expect_success 'center alignment formatting at the nth column' ' +test_expect_success ICONV 'center alignment formatting at the nth column' ' git log --pretty="tformat:%h %><|(40)%s" >actual && qz_to_tab_space <<-EOF >expected && $head1 message two Z @@ -457,7 +456,7 @@ test_expect_success 'center alignment formatting at the nth column' ' test_cmp expected actual ' -test_expect_success 'center alignment formatting at the nth column' ' +test_expect_success ICONV 'center alignment formatting at the nth column' ' COLUMNS=70 git log --pretty="tformat:%h %><|(-30)%s" >actual && qz_to_tab_space <<-EOF >expected && $head1 message two Z @@ -468,7 +467,7 @@ test_expect_success 'center alignment formatting at the nth column' ' test_cmp expected actual ' -test_expect_success 'center alignment formatting at the nth column. i18n.logOutputEncoding' ' +test_expect_success ICONV 'center alignment formatting at the nth column. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %><|(40)%s" >actual && qz_to_tab_space <<-EOF | iconv -f utf-8 -t $test_encoding >expected && $head1 message two Z @@ -479,7 +478,7 @@ test_expect_success 'center alignment formatting at the nth column. i18n.logOutp test_cmp expected actual ' -test_expect_success 'center alignment formatting with no padding' ' +test_expect_success ICONV 'center alignment formatting with no padding' ' git log --pretty="tformat:%><(1)%s" >actual && cat <<-EOF >expected && message two @@ -493,7 +492,7 @@ test_expect_success 'center alignment formatting with no padding' ' # save HEAD's SHA-1 digest (with no abbreviations) to use it below # as far as the next test amends HEAD old_head1=$(git rev-parse --verify HEAD~0) -test_expect_success 'center alignment formatting with no padding. i18n.logOutputEncoding' ' +test_expect_success ICONV 'center alignment formatting with no padding. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%><(1)%s" >actual && cat <<-EOF | iconv -f utf-8 -t $test_encoding >expected && message two @@ -504,7 +503,7 @@ test_expect_success 'center alignment formatting with no padding. i18n.logOutput test_cmp expected actual ' -test_expect_success 'left/right alignment formatting with stealing' ' +test_expect_success ICONV 'left/right alignment formatting with stealing' ' git commit --amend -m short --author "long long long <long@me.com>" && git log --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual && cat <<-\EOF >expected && @@ -515,7 +514,7 @@ test_expect_success 'left/right alignment formatting with stealing' ' EOF test_cmp expected actual ' -test_expect_success 'left/right alignment formatting with stealing. i18n.logOutputEncoding' ' +test_expect_success ICONV 'left/right alignment formatting with stealing. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual && cat <<-\EOF | iconv -f utf-8 -t $test_encoding >expected && short long long long @@ -564,22 +563,38 @@ test_expect_success 'log decoration properly follows tag chain' ' git tag -d tag1 && git commit --amend -m shorter && git log --no-walk --tags --pretty="%H %d" --decorate=full >actual && - cat <<-EOF >expected && - $head2 (tag: refs/tags/message-one) - $old_head1 (tag: refs/tags/message-two) - $head1 (tag: refs/tags/tag2) - EOF + if test_have_prereq ICONV + then + cat <<-EOF >expected + $head2 (tag: refs/tags/message-one) + $old_head1 (tag: refs/tags/message-two) + $head1 (tag: refs/tags/tag2) + EOF + else + cat <<-EOF >expected + $head2 (tag: refs/tags/message-one) + $old_head1 (tag: refs/tags/tag2, tag: refs/tags/message-two) + EOF + fi && sort -k3 actual >actual1 && test_cmp expected actual1 ' test_expect_success 'clean log decoration' ' git log --no-walk --tags --pretty="%H %D" --decorate=full >actual && - cat >expected <<-EOF && - $head2 tag: refs/tags/message-one - $old_head1 tag: refs/tags/message-two - $head1 tag: refs/tags/tag2 - EOF + if test_have_prereq ICONV + then + cat <<-EOF >expected + $head2 tag: refs/tags/message-one + $old_head1 tag: refs/tags/message-two + $head1 tag: refs/tags/tag2 + EOF + else + cat <<-EOF >expected + $head2 tag: refs/tags/message-one + $old_head1 tag: refs/tags/tag2, tag: refs/tags/message-two + EOF + fi && sort -k3 actual >actual1 && test_cmp expected actual1 ' diff --git a/t/t4206-log-follow-harder-copies.sh b/t/t4206-log-follow-harder-copies.sh index 9167b0351f2212..bcab71c8e84503 100755 --- a/t/t4206-log-follow-harder-copies.sh +++ b/t/t4206-log-follow-harder-copies.sh @@ -7,7 +7,6 @@ test_description='Test --follow should always find copies hard in git log. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index 73ea9e515503ba..2e83cc820a145e 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -8,7 +8,6 @@ test_description='test "git log --decorate" colors' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -59,7 +58,8 @@ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}v1.0${c_reset}${c_commit}, \ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}B${c_reset}${c_commit})${c_reset} B ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ ${c_tag}tag: ${c_reset}${c_tag}A1${c_reset}${c_commit}, \ -${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit})${c_reset} A1 +${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit}, \ +${c_reset}${c_remoteBranch}other/HEAD${c_reset}${c_commit})${c_reset} A1 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ ${c_stash}refs/stash${c_reset}${c_commit})${c_reset} On main: Changes to A.t ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh index 2a46eb6bedbe28..806b2809d405f8 100755 --- a/t/t4208-log-magic-pathspec.sh +++ b/t/t4208-log-magic-pathspec.sh @@ -5,7 +5,6 @@ test_description='magic pathspec tests using git-log' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4209-log-pickaxe.sh b/t/t4209-log-pickaxe.sh index b42fdc54fcb544..0e2f80a268ed0d 100755 --- a/t/t4209-log-pickaxe.sh +++ b/t/t4209-log-pickaxe.sh @@ -2,7 +2,6 @@ test_description='log --grep/--author/--regexp-ignore-case/-S/-G' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_log () { @@ -94,6 +93,22 @@ test_expect_success 'usage: --no-pickaxe-regex' ' test_cmp expect actual ' +test_expect_success 'usage: -G and -S with empty argument' ' + cat >expect <<-\EOF && + error: -S requires a non-empty argument + EOF + + test_expect_code 129 git log -S "" 2>actual && + test_cmp expect actual && + + cat >expect <<-\EOF && + error: -G requires a non-empty argument + EOF + + test_expect_code 129 git log -G "" 2>actual && + test_cmp expect actual +' + test_log expect_initial --grep initial test_log expect_nomatch --grep InItial test_log_icase expect_initial --grep InItial diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index 7120030b5c650d..26dda0db38481a 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -2,9 +2,14 @@ test_description='test log with i18n features' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh +if ! test_have_prereq ICONV +then + skip_all='skipping log i18n tests; iconv not available' + test_done +fi + # two forms of é utf8_e=$(printf '\303\251') latin1_e=$(printf '\351') diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index 02d76dca284cba..950451cf6a66e6 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -337,4 +337,32 @@ test_expect_success 'zero-width regex .* matches any function name' ' test_cmp expect actual ' +test_expect_success 'show line-log with graph' ' + qz_to_tab_space >expect <<-EOF && + * $head_oid Modify func2() in file.c + |Z + | diff --git a/file.c b/file.c + | --- a/file.c + | +++ b/file.c + | @@ -6,4 +6,4 @@ + | int func2() + | { + | - return F2; + | + return F2 + 2; + | } + * $root_oid Add func1() and func2() in file.c + ZZ + diff --git a/file.c b/file.c + --- /dev/null + +++ b/file.c + @@ -0,0 +6,4 @@ + +int func2() + +{ + + return F2; + +} + EOF + git log --graph --oneline -L:func2:file.c >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4212-log-corrupt.sh b/t/t4212-log-corrupt.sh index e6b59123a37251..64d818bc70a5c8 100755 --- a/t/t4212-log-corrupt.sh +++ b/t/t4212-log-corrupt.sh @@ -2,7 +2,6 @@ test_description='git log with invalid commit headers' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4213-log-tabexpand.sh b/t/t4213-log-tabexpand.sh index 590fce95e90a8b..53a4af324495dd 100755 --- a/t/t4213-log-tabexpand.sh +++ b/t/t4213-log-tabexpand.sh @@ -2,7 +2,6 @@ test_description='log/show --expand-tabs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh HT=" " diff --git a/t/t4214-log-graph-octopus.sh b/t/t4214-log-graph-octopus.sh index 79055978690962..f70c46bbbfa2c8 100755 --- a/t/t4214-log-graph-octopus.sh +++ b/t/t4214-log-graph-octopus.sh @@ -5,7 +5,6 @@ test_description='git log --graph of skewed left octopus merge.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-log-graph.sh diff --git a/t/t4215-log-skewed-merges.sh b/t/t4215-log-skewed-merges.sh index b877ac723516dc..28d0779a8c599e 100755 --- a/t/t4215-log-skewed-merges.sh +++ b/t/t4215-log-skewed-merges.sh @@ -2,7 +2,6 @@ test_description='git log --graph of skewed merges' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-log-graph.sh diff --git a/t/t4217-log-limit.sh b/t/t4217-log-limit.sh index 613f0710e90511..6e01e2629c1b15 100755 --- a/t/t4217-log-limit.sh +++ b/t/t4217-log-limit.sh @@ -2,7 +2,6 @@ test_description='git log with filter options limiting the output' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup test' ' diff --git a/t/t4252-am-options.sh b/t/t4252-am-options.sh index 5b680dc755916e..bda8822b3d1eb6 100755 --- a/t/t4252-am-options.sh +++ b/t/t4252-am-options.sh @@ -2,7 +2,6 @@ test_description='git am with options and not losing them' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh tm="$TEST_DIRECTORY/t4252" diff --git a/t/t4253-am-keep-cr-dos.sh b/t/t4253-am-keep-cr-dos.sh index 2bcdd9f34fad67..0ee69d2a0c4e0d 100755 --- a/t/t4253-am-keep-cr-dos.sh +++ b/t/t4253-am-keep-cr-dos.sh @@ -9,7 +9,6 @@ test_description='git-am mbox with dos line ending. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Three patches which will be added as files with dos line ending. diff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh index 661feb60709f23..ae0a56cf5ec2d7 100755 --- a/t/t4254-am-corrupt.sh +++ b/t/t4254-am-corrupt.sh @@ -2,9 +2,14 @@ test_description='git am with corrupt input' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +if ! test_have_prereq ICONV +then + skip_all='skipping am encoding corruption tests; iconv not available' + test_done +fi + make_mbox_with_nul () { space=' ' q_nul_in_subject= diff --git a/t/t4255-am-submodule.sh b/t/t4255-am-submodule.sh index 04f3ccfc41cc66..a7ba08f728c0b8 100755 --- a/t/t4255-am-submodule.sh +++ b/t/t4255-am-submodule.sh @@ -2,7 +2,6 @@ test_description='git am handling submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh index 92d8c8b651cbe6..ac9db285f3fd70 100755 --- a/t/t4256-am-format-flowed.sh +++ b/t/t4256-am-format-flowed.sh @@ -2,7 +2,6 @@ test_description='test format=flowed support of git am' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh index f26d7fd2dbd35c..30a565cbeaf185 100755 --- a/t/t4257-am-interactive.sh +++ b/t/t4257-am-interactive.sh @@ -2,7 +2,6 @@ test_description='am --interactive tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up patches to apply' ' diff --git a/t/t4258-am-quoted-cr.sh b/t/t4258-am-quoted-cr.sh index 3573c9147f17c5..201915b45a8bd6 100755 --- a/t/t4258-am-quoted-cr.sh +++ b/t/t4258-am-quoted-cr.sh @@ -2,7 +2,6 @@ test_description='test am --quoted-cr=<action>' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh DATA="$TEST_DIRECTORY/t4258" diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh index 9c197260d5bbf5..27fbe193bca95e 100755 --- a/t/t4300-merge-tree.sh +++ b/t/t4300-merge-tree.sh @@ -5,7 +5,6 @@ test_description='git merge-tree' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4301-merge-tree-write-tree.sh b/t/t4301-merge-tree-write-tree.sh index 37f1cd7364ce0d..eea19907b550c4 100755 --- a/t/t4301-merge-tree-write-tree.sh +++ b/t/t4301-merge-tree-write-tree.sh @@ -2,7 +2,6 @@ test_description='git merge-tree --write-tree' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test is ort-specific diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index b9fda973f7bfbf..5465054f1779f0 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -25,7 +25,6 @@ commit id embedding: ' TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh SUBSTFORMAT=%H%n diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh index 7310774af5efea..e7450764411093 100755 --- a/t/t5001-archive-attr.sh +++ b/t/t5001-archive-attr.sh @@ -3,7 +3,6 @@ test_description='git archive attribute tests' TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh SUBSTFORMAT='%H (%h)%n' diff --git a/t/t5002-archive-attr-pattern.sh b/t/t5002-archive-attr-pattern.sh index 78ab75f1bc2442..97c93f6c44260d 100755 --- a/t/t5002-archive-attr-pattern.sh +++ b/t/t5002-archive-attr-pattern.sh @@ -2,7 +2,6 @@ test_description='git archive attribute pattern tests' -TEST_PASSES_SANITIZE_LEAK=true TEST_CREATE_REPO_NO_TEMPLATE=1 . ./test-lib.sh diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh index 01f591c99b962f..961c6aac256135 100755 --- a/t/t5003-archive-zip.sh +++ b/t/t5003-archive-zip.sh @@ -3,7 +3,6 @@ test_description='git archive --format=zip test' TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh SUBSTFORMAT=%H%n diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh index 9f2c6da80e8cd9..50344e17ca175d 100755 --- a/t/t5004-archive-corner-cases.sh +++ b/t/t5004-archive-corner-cases.sh @@ -2,7 +2,6 @@ test_description='test corner cases of git-archive' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # the 10knuls.tar file is used to test for an empty git generated tar diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index 065156c1f39b14..e57e1ae7395b13 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -5,7 +5,6 @@ test_description='git mailinfo and git mailsplit test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh DATA="$TEST_DIRECTORY/t5100" @@ -28,7 +27,12 @@ check_mailinfo () { for mail in 00* do - test_expect_success "mailinfo $mail" ' + case "$mail" in + 0004) + prereq=ICONV;; + esac + + test_expect_success $prereq "mailinfo $mail" ' check_mailinfo "$mail" "" && if test -f "$DATA/msg$mail--scissors" then @@ -56,7 +60,12 @@ test_expect_success 'split box with rfc2047 samples' \ for mail in rfc2047/00* do - test_expect_success "mailinfo $mail" ' + case "$mail" in + rfc2047/0001) + prereq=ICONV;; + esac + + test_expect_success $prereq "mailinfo $mail" ' git mailinfo -u "$mail-msg" "$mail-patch" <"$mail" >"$mail-info" && echo msg && test_cmp "$DATA/empty" "$mail-msg" && diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh index 86bee331607037..cb67bac1c47487 100755 --- a/t/t5150-request-pull.sh +++ b/t/t5150-request-pull.sh @@ -5,7 +5,6 @@ test_description='Test workflows involving pull request.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq PERL diff --git a/t/t5200-update-server-info.sh b/t/t5200-update-server-info.sh index ed9dfd624c7542..83659070559952 100755 --- a/t/t5200-update-server-info.sh +++ b/t/t5200-update-server-info.sh @@ -2,7 +2,6 @@ test_description='Test git update-server-info' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' 'test_commit file' @@ -39,4 +38,12 @@ test_expect_success 'info/refs updates when changes are made' ' ! test_cmp a b ' +test_expect_success 'midx does not create duplicate pack entries' ' + git repack -d --write-midx && + git repack -d && + grep ^P .git/objects/info/packs >packs && + uniq -d <packs >dups && + test_must_be_empty dups +' + test_done diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 3b9dae331a5ea9..5ac8d39094b653 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -5,7 +5,6 @@ test_description='git pack-object' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -156,6 +155,11 @@ test_expect_success 'pack without delta' ' check_deltas stderr = 0 ' +test_expect_success 'negative window clamps to 0' ' + git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr && + check_deltas stderr = 0 +' + test_expect_success 'pack-objects with bogus arguments' ' test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list ' @@ -327,10 +331,8 @@ test_expect_success 'build pack index for an existing pack' ' git index-pack -o tmp.idx test-3.pack && cmp tmp.idx test-1-${packname_1}.idx && - git index-pack --promisor=message test-3.pack && + git index-pack test-3.pack && cmp test-3.idx test-1-${packname_1}.idx && - echo message >expect && - test_cmp expect test-3.promisor && cat test-2-${packname_2}.pack >test-3.pack && git index-pack -o tmp.idx test-2-${packname_2}.pack && @@ -523,6 +525,24 @@ test_expect_success 'index-pack --strict <pack> works in non-repo' ' test_path_is_file foo.idx ' +test_expect_success SHA1 'show-index works OK outside a repository' ' + nongit git show-index <foo.idx +' + +for hash in sha1 sha256 +do + test_expect_success 'show-index works OK outside a repository with hash algo passed in via --object-format' ' + test_when_finished "rm -rf explicit-hash-$hash" && + git init --object-format=$hash explicit-hash-$hash && + test_commit -C explicit-hash-$hash one && + git -C explicit-hash-$hash rev-parse one >in && + git -C explicit-hash-$hash pack-objects explicit-hash-$hash <in && + idx=$(echo explicit-hash-$hash/explicit-hash-$hash*.idx) && + nongit git show-index --object-format=$hash <"$idx" >actual && + test_line_count = 1 actual + ' +done + test_expect_success !PTHREADS,!FAIL_PREREQS \ 'index-pack --threads=N or pack.threads=N warns when no pthreads' ' test_must_fail git index-pack --threads=2 2>err && @@ -630,11 +650,6 @@ test_expect_success 'prefetch objects' ' test_line_count = 1 donelines ' -test_expect_success 'negative window clamps to 0' ' - git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr && - check_deltas stderr = 0 -' - for hash in sha1 sha256 do test_expect_success "verify-pack with $hash packfile" ' @@ -674,4 +689,38 @@ do ' done +test_expect_success 'valid and invalid --name-hash-versions' ' + sane_unset GIT_TEST_NAME_HASH_VERSION && + + # Valid values are hard to verify other than "do not fail". + # Performance tests will be more valuable to validate these versions. + # Negative values are converted to version 1. + for value in -1 1 2 + do + git pack-objects base --all --name-hash-version=$value || return 1 + done && + + # Invalid values have clear post-conditions. + for value in 0 3 + do + test_must_fail git pack-objects base --all --name-hash-version=$value 2>err && + test_grep "invalid --name-hash-version option" err || return 1 + done +' + +# The following test is not necessarily a permanent choice, but since we do not +# have a "name hash version" bit in the .bitmap file format, we cannot write the +# hash values into the .bitmap file without risking breakage later. +# +# TODO: Make these compatible in the future and replace this test with the +# expected behavior when both are specified. +test_expect_success '--name-hash-version=2 and --write-bitmap-index are incompatible' ' + git pack-objects base --all --name-hash-version=2 --write-bitmap-index 2>err && + test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err && + + # --stdout option silently removes --write-bitmap-index + git pack-objects --stdout --all --name-hash-version=2 --write-bitmap-index >out 2>err && + ! test_grep "currently, --write-bitmap-index requires --name-hash-version=1" err +' + test_done diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 226490d60df3a6..ff6b5159a312bb 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -5,7 +5,6 @@ test_description='mmap sliding window tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index d88e6f16910151..413c99274c8f30 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -5,7 +5,6 @@ test_description='pack index with 64-bit offsets and object CRC' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh index 61469ef4a68120..de58ca654a1215 100755 --- a/t/t5303-pack-corruption-resilience.sh +++ b/t/t5303-pack-corruption-resilience.sh @@ -5,7 +5,6 @@ test_description='resilience to pack corruptions with redundant objects' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Note: the test objects are created with knowledge of their pack encoding @@ -15,7 +14,7 @@ TEST_PASSES_SANITIZE_LEAK=true # 1) blob_2 is a delta with blob_1 for base and blob_3 is a delta with blob2 # for base, such that blob_3 delta depth is 2; # -# 2) the bulk of object data is uncompressible so the text part remains +# 2) the bulk of object data is incompressible so the text part remains # visible; # # 3) object header is always 2 bytes. @@ -44,9 +43,14 @@ create_new_pack() { } do_repack() { + for f in $pack.* + do + mv $f "$(echo $f | sed -e 's/pack-/pack-corrupt-/')" || return 1 + done && pack=$(printf "$blob_1\n$blob_2\n$blob_3\n" | git pack-objects $@ .git/objects/pack/pack) && - pack=".git/objects/pack/pack-${pack}" + pack=".git/objects/pack/pack-${pack}" && + rm -f .git/objects/pack/pack-corrupt-* } do_corrupt_object() { diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index e641df0116c244..1f1f664871ece6 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -7,7 +7,6 @@ test_description='prune' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh day=$((60*60*24)) diff --git a/t/t5305-include-tag.sh b/t/t5305-include-tag.sh index dc8fe55c82d5ee..44bd9ef45fd6d3 100755 --- a/t/t5305-include-tag.sh +++ b/t/t5305-include-tag.sh @@ -4,7 +4,6 @@ test_description='git pack-object --include-tag' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh TRASH=$(pwd) diff --git a/t/t5306-pack-nobase.sh b/t/t5306-pack-nobase.sh index 0d50c6b4bca4c0..805d60ff3179ce 100755 --- a/t/t5306-pack-nobase.sh +++ b/t/t5306-pack-nobase.sh @@ -7,7 +7,6 @@ test_description='git-pack-object with missing base ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Create A-B chain diff --git a/t/t5307-pack-missing-commit.sh b/t/t5307-pack-missing-commit.sh index 1e02c305c4fe5f..fa4bc269fe86f4 100755 --- a/t/t5307-pack-missing-commit.sh +++ b/t/t5307-pack-missing-commit.sh @@ -2,7 +2,6 @@ test_description='pack should notice missing commit objects' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5308-pack-detect-duplicates.sh b/t/t5308-pack-detect-duplicates.sh index 655cafa0541211..0f841378677165 100755 --- a/t/t5308-pack-detect-duplicates.sh +++ b/t/t5308-pack-detect-duplicates.sh @@ -2,7 +2,6 @@ test_description='handling of duplicate objects in incoming packfiles' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh diff --git a/t/t5309-pack-delta-cycles.sh b/t/t5309-pack-delta-cycles.sh index 4e910c5b9d2a9d..60fc710bacb20e 100755 --- a/t/t5309-pack-delta-cycles.sh +++ b/t/t5309-pack-delta-cycles.sh @@ -2,7 +2,6 @@ test_description='test index-pack handling of delta cycles in packfiles' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index a6de7c57643078..621bbbdd26ed21 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -26,6 +26,36 @@ has_any () { grep -Ff "$1" "$2" } +# Since name-hash values are stored in the .bitmap files, add a test +# that checks that the name-hash calculations are stable across versions. +# Not exhaustive, but these hashing algorithms would be hard to change +# without causing deviations here. +test_expect_success 'name-hash value stability' ' + cat >names <<-\EOF && + first + second + third + a/one-long-enough-for-collisions + b/two-long-enough-for-collisions + many/parts/to/this/path/enough/to/collide/in/v2 + enough/parts/to/this/path/enough/to/collide/in/v2 + EOF + + test-tool name-hash <names >out && + + cat >expect <<-\EOF && + 2582249472 1763573760 first + 2289942528 1188134912 second + 2300837888 1130758144 third + 2544516325 3963087891 a/one-long-enough-for-collisions + 2544516325 4013419539 b/two-long-enough-for-collisions + 1420111091 1709547268 many/parts/to/this/path/enough/to/collide/in/v2 + 1420111091 1709547268 enough/parts/to/this/path/enough/to/collide/in/v2 + EOF + + test_cmp expect out +' + test_bitmap_cases () { writeLookupTable=false for i in "$@" @@ -419,7 +449,10 @@ test_bitmap_cases () { cat >expect <<-\EOF && error: missing value for '\''pack.preferbitmaptips'\'' EOF - git repack -adb 2>actual && + + # Disable name hash version adjustment due to stderr comparison. + GIT_TEST_NAME_HASH_VERSION=1 \ + git repack -adb 2>actual && test_cmp expect actual ) ' @@ -502,6 +535,18 @@ test_expect_success 'boundary-based traversal is used when requested' ' done ' +test_expect_success 'left-right not confused by bitmap index' ' + git rev-list --left-right other...HEAD >expect && + git rev-list --use-bitmap-index --left-right other...HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'left-right count not confused by bitmap-index' ' + git rev-list --left-right --count other...HEAD >expect && + git rev-list --use-bitmap-index --left-right --count other...HEAD >actual && + test_cmp expect actual +' + test_bitmap_cases "pack.writeBitmapLookupTable" test_expect_success 'verify writing bitmap lookup table when enabled' ' diff --git a/t/t5311-pack-bitmaps-shallow.sh b/t/t5311-pack-bitmaps-shallow.sh index 4fe71fe8cd21dd..012852c156ac79 100755 --- a/t/t5311-pack-bitmaps-shallow.sh +++ b/t/t5311-pack-bitmaps-shallow.sh @@ -2,7 +2,6 @@ test_description='check bitmap operation with shallow repositories' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # We want to create a situation where the shallow, grafted diff --git a/t/t5312-prune-corruption.sh b/t/t5312-prune-corruption.sh index d8d2e304687b2a..c37ef3818d264b 100755 --- a/t/t5312-prune-corruption.sh +++ b/t/t5312-prune-corruption.sh @@ -14,7 +14,6 @@ what currently happens. If that changes, these tests should be revisited. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'disable reflogs' ' diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh index 86fc73f9fbac4d..5be01260d7760f 100755 --- a/t/t5313-pack-bounds-checks.sh +++ b/t/t5313-pack-bounds-checks.sh @@ -2,7 +2,6 @@ test_description='bounds-checking of access to mmapped on-disk file formats' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh clear_base () { diff --git a/t/t5314-pack-cycle-detection.sh b/t/t5314-pack-cycle-detection.sh index 82734b9a3c4420..9cd18c1e6be94f 100755 --- a/t/t5314-pack-cycle-detection.sh +++ b/t/t5314-pack-cycle-detection.sh @@ -50,7 +50,6 @@ will always find a delta for "file", because its lookup will always come immediately after the lookup for "dummy". ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Create a pack containing the tree $1 and blob $1:file, with diff --git a/t/t5315-pack-objects-compression.sh b/t/t5315-pack-objects-compression.sh index c80ea9e8b71ee8..8bacd96275b0ac 100755 --- a/t/t5315-pack-objects-compression.sh +++ b/t/t5315-pack-objects-compression.sh @@ -2,7 +2,6 @@ test_description='pack-object compression configuration' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5316-pack-delta-depth.sh b/t/t5316-pack-delta-depth.sh index eb4ef3dda4d6e5..32cf4227451ff7 100755 --- a/t/t5316-pack-delta-depth.sh +++ b/t/t5316-pack-delta-depth.sh @@ -2,7 +2,6 @@ test_description='pack-objects breaks long cross-pack delta chains' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This mirrors a repeated push setup: diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh index 79552d6ef7f697..501d715b9a16b7 100755 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@ -5,7 +5,6 @@ test_description='git pack-objects using object filtering' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Test blob:none filter. diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 2916c07e3c2490..f68f64cd85e32c 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -2,7 +2,6 @@ test_description='commit graph' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-chunk.sh diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index fbbc218d04af4a..0f215ad2e88837 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -2,7 +2,6 @@ test_description='multi-pack-indexes' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-chunk.sh . "$TEST_DIRECTORY"/lib-midx.sh diff --git a/t/t5320-delta-islands.sh b/t/t5320-delta-islands.sh index 406363381f10bc..2c961c70963051 100755 --- a/t/t5320-delta-islands.sh +++ b/t/t5320-delta-islands.sh @@ -2,7 +2,6 @@ test_description='exercise delta islands' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # returns true iff $1 is a delta based on $2 diff --git a/t/t5321-pack-large-objects.sh b/t/t5321-pack-large-objects.sh index 70770fe274d84f..51aaca1fcf6229 100755 --- a/t/t5321-pack-large-objects.sh +++ b/t/t5321-pack-large-objects.sh @@ -7,7 +7,6 @@ test_description='git pack-object with "large" deltas ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh diff --git a/t/t5322-pack-objects-sparse.sh b/t/t5322-pack-objects-sparse.sh index 770695c9278292..d39958c066de5e 100755 --- a/t/t5322-pack-objects-sparse.sh +++ b/t/t5322-pack-objects-sparse.sh @@ -4,7 +4,6 @@ test_description='pack-objects object selection using sparse algorithm' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup repo' ' diff --git a/t/t5323-pack-redundant.sh b/t/t5323-pack-redundant.sh index 8dbbcc5e51c06d..688cd9706c876a 100755 --- a/t/t5323-pack-redundant.sh +++ b/t/t5323-pack-redundant.sh @@ -36,6 +36,12 @@ relationship between packs and objects is as follows: . ./test-lib.sh +if ! test_have_prereq WITHOUT_BREAKING_CHANGES +then + skip_all='skipping git-pack-redundant tests; built with breaking changes' + test_done +fi + main_repo=main.git shared_repo=shared.git diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 77e91547ea3243..a32be3867df36f 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -2,7 +2,6 @@ test_description='split commit graph' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-chunk.sh @@ -203,7 +202,7 @@ then graph_git_behavior 'alternate: commit 13 vs 6' commits/13 origin/commits/6 "fork" fi -test_expect_success 'test merge stragety constants' ' +test_expect_success 'test merge strategy constants' ' git clone . merge-2 && ( cd merge-2 && diff --git a/t/t5325-reverse-index.sh b/t/t5325-reverse-index.sh index 431a603ca0e61d..285c8b4a49555b 100755 --- a/t/t5325-reverse-index.sh +++ b/t/t5325-reverse-index.sh @@ -2,7 +2,6 @@ test_description='on-disk reverse index' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # The below tests want control over the 'pack.writeReverseIndex' setting diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh index 832b92619c06b1..d27557b9b042a1 100755 --- a/t/t5326-multi-pack-bitmaps.sh +++ b/t/t5326-multi-pack-bitmaps.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='exercise basic multi-pack bitmap functionality' + . ./test-lib.sh . "${TEST_DIRECTORY}/lib-bitmap.sh" diff --git a/t/t5328-commit-graph-64bit-time.sh b/t/t5328-commit-graph-64bit-time.sh index fc6a242b56d886..a766a3e3f84ff5 100755 --- a/t/t5328-commit-graph-64bit-time.sh +++ b/t/t5328-commit-graph-64bit-time.sh @@ -2,7 +2,6 @@ test_description='commit graph with 64-bit timestamps' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq TIME_IS_64BIT || ! test_have_prereq TIME_T_IS_64BIT diff --git a/t/t5329-pack-objects-cruft.sh b/t/t5329-pack-objects-cruft.sh index fc5fedbe9b0c4d..b71a0aef408ec5 100755 --- a/t/t5329-pack-objects-cruft.sh +++ b/t/t5329-pack-objects-cruft.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='cruft pack related pack-objects tests' + . ./test-lib.sh objdir=.git/objects @@ -688,7 +689,7 @@ test_expect_success 'cruft --local drops unreachable objects' ' test_when_finished "rm -fr alternate repo" && test_commit -C alternate base && - # Pack all objects in alterate so that the cruft repack in "repo" sees + # Pack all objects in alternate so that the cruft repack in "repo" sees # the object it dropped due to `--local` as packed. Otherwise this # object would not appear packed anywhere (since it is not packed in # alternate and likewise not part of the cruft pack in the other repo diff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh index 5eb28f0512d447..313eadba98195b 100755 --- a/t/t5330-no-lazy-fetch-with-commit-graph.sh +++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh @@ -2,7 +2,6 @@ test_description='test for no lazy fetch with the commit-graph' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: prepare a repository with a commit' ' @@ -38,9 +37,9 @@ test_expect_success 'fetch any commit from promisor with the usage of the commit git -C with-commit-graph config remote.origin.partialclonefilter blob:none && test_commit -C with-commit any-commit && anycommit=$(git -C with-commit rev-parse HEAD) && - GIT_TRACE="$(pwd)/trace.txt" \ + test_must_fail env GIT_TRACE="$(pwd)/trace.txt" \ git -C with-commit-graph fetch origin $anycommit 2>err && - ! grep "fatal: promisor-remote: unable to fork off fetch subprocess" err && + test_grep ! "fatal: promisor-remote: unable to fork off fetch subprocess" err && grep "git fetch origin" trace.txt >actual && test_line_count = 1 actual ' diff --git a/t/t5331-pack-objects-stdin.sh b/t/t5331-pack-objects-stdin.sh index 2dcf1eeceeb65c..b48c0cbe8fcfab 100755 --- a/t/t5331-pack-objects-stdin.sh +++ b/t/t5331-pack-objects-stdin.sh @@ -4,7 +4,6 @@ test_description='pack-objects --stdin' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh packed_objects () { diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh index 955ea42769bc0e..57cad7708f80f9 100755 --- a/t/t5332-multi-pack-reuse.sh +++ b/t/t5332-multi-pack-reuse.sh @@ -2,7 +2,6 @@ test_description='pack-objects multi-pack reuse' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bitmap.sh @@ -259,4 +258,26 @@ test_expect_success 'duplicate objects' ' ) ' +test_expect_success 'duplicate objects with verbatim reuse' ' + git init duplicate-objects-verbatim && + ( + cd duplicate-objects-verbatim && + + git config pack.allowPackReuse multi && + + test_commit_bulk 64 && + + # take the first object from the main pack... + git show-index <$(ls $packdir/pack-*.idx) >obj.raw && + sort -nk1 <obj.raw | head -n1 | cut -d" " -f2 >in && + + # ...and create a separate pack containing just that object + p="$(git pack-objects $packdir/pack <in)" && + + git multi-pack-index write --bitmap --preferred-pack=pack-$p.idx && + + test_pack_objects_reused_all 192 2 + ) +' + test_done diff --git a/t/t5333-pseudo-merge-bitmaps.sh b/t/t5333-pseudo-merge-bitmaps.sh index 1dd62847560dc0..3905cb6e4f1c7d 100755 --- a/t/t5333-pseudo-merge-bitmaps.sh +++ b/t/t5333-pseudo-merge-bitmaps.sh @@ -208,7 +208,8 @@ test_expect_success 'bitmapPseudoMerge.stableThreshold creates stable groups' ' ' test_expect_success 'out of order thresholds are rejected' ' - test_must_fail git \ + # Disable the test var to remove a stderr message. + test_must_fail env GIT_TEST_NAME_HASH_VERSION=1 git \ -c bitmapPseudoMerge.test.pattern="refs/*" \ -c bitmapPseudoMerge.test.threshold=1.month.ago \ -c bitmapPseudoMerge.test.stableThreshold=1.week.ago \ diff --git a/t/t5334-incremental-multi-pack-index.sh b/t/t5334-incremental-multi-pack-index.sh index c3b08acc733d94..26257e5660e766 100755 --- a/t/t5334-incremental-multi-pack-index.sh +++ b/t/t5334-incremental-multi-pack-index.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='incremental multi-pack-index' + . ./test-lib.sh . "$TEST_DIRECTORY"/lib-midx.sh diff --git a/t/t5351-unpack-large-objects.sh b/t/t5351-unpack-large-objects.sh index 43cbcd5d497eca..d76eb4be932eeb 100755 --- a/t/t5351-unpack-large-objects.sh +++ b/t/t5351-unpack-large-objects.sh @@ -5,7 +5,6 @@ test_description='git unpack-objects with large objects' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh prepare_dest () { diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 248c74d8ef2e1b..3f81f16e1335ce 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -9,7 +9,6 @@ test_description='See why rewinding head breaks send-pack GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cnt=64 diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index 3c1ea6086e7d28..17a46fd3bae14f 100755 --- a/t/t5401-update-hooks.sh +++ b/t/t5401-update-hooks.sh @@ -5,7 +5,6 @@ test_description='Test the update hook infrastructure.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -65,14 +64,14 @@ test_expect_success 'updated as expected' ' ' test_expect_success 'hooks ran' ' - test -f victim.git/pre-receive.args && - test -f victim.git/pre-receive.stdin && - test -f victim.git/update.args && - test -f victim.git/update.stdin && - test -f victim.git/post-receive.args && - test -f victim.git/post-receive.stdin && - test -f victim.git/post-update.args && - test -f victim.git/post-update.stdin + test_path_is_file victim.git/pre-receive.args && + test_path_is_file victim.git/pre-receive.stdin && + test_path_is_file victim.git/update.args && + test_path_is_file victim.git/update.stdin && + test_path_is_file victim.git/post-receive.args && + test_path_is_file victim.git/post-receive.stdin && + test_path_is_file victim.git/post-update.args && + test_path_is_file victim.git/post-update.stdin ' test_expect_success 'pre-receive hook input' ' diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh index 46ebdfbeebaf52..915af2de95e162 100755 --- a/t/t5402-post-merge-hook.sh +++ b/t/t5402-post-merge-hook.sh @@ -7,7 +7,6 @@ test_description='Test the post-merge hook.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5403-post-checkout-hook.sh b/t/t5403-post-checkout-hook.sh index cfaae547398e0e..978f240cdaceb4 100755 --- a/t/t5403-post-checkout-hook.sh +++ b/t/t5403-post-checkout-hook.sh @@ -7,7 +7,6 @@ test_description='Test the post-checkout hook.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh index 51737eeafeeefa..cc078896673ae2 100755 --- a/t/t5404-tracking-branches.sh +++ b/t/t5404-tracking-branches.sh @@ -5,7 +5,6 @@ test_description='tracking branch update checks for git push' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh index 1686ac13aa6285..11f03239a0628c 100755 --- a/t/t5405-send-pack-rewind.sh +++ b/t/t5405-send-pack-rewind.sh @@ -5,7 +5,6 @@ test_description='forced push to replace commit we do not have' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh index d6a994663383c3..dcbeb42082791b 100755 --- a/t/t5406-remote-rejects.sh +++ b/t/t5406-remote-rejects.sh @@ -2,7 +2,6 @@ test_description='remote push rejects are reported by client' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh index e99e728236ad07..ad7f8c6f00202c 100755 --- a/t/t5407-post-rewrite-hook.sh +++ b/t/t5407-post-rewrite-hook.sh @@ -7,7 +7,6 @@ test_description='Test the post-rewrite hook.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5408-send-pack-stdin.sh b/t/t5408-send-pack-stdin.sh index c3695a4d4e3bbf..526a6750459514 100755 --- a/t/t5408-send-pack-stdin.sh +++ b/t/t5408-send-pack-stdin.sh @@ -2,7 +2,6 @@ test_description='send-pack --stdin tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_ref () { diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh index 516b22fd9637ea..fa5de4500a4f50 100755 --- a/t/t5409-colorize-remote-messages.sh +++ b/t/t5409-colorize-remote-messages.sh @@ -2,7 +2,6 @@ test_description='remote messages are colorized on the client' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5410-receive-pack-alternates.sh b/t/t5410-receive-pack-alternates.sh index 7a45d4c311ed34..0b28e4e452fe7e 100755 --- a/t/t5410-receive-pack-alternates.sh +++ b/t/t5410-receive-pack-alternates.sh @@ -5,7 +5,6 @@ test_description='git receive-pack with alternate ref filtering' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5411/test-0034-report-ft.sh b/t/t5411/test-0034-report-ft.sh index 0e37535065345b..78d0b63876eaf5 100644 --- a/t/t5411/test-0034-report-ft.sh +++ b/t/t5411/test-0034-report-ft.sh @@ -10,7 +10,7 @@ test_expect_success "setup proc-receive hook (ft, $PROTOCOL)" ' # Refs of upstream : main(A) # Refs of workbench: main(A) tags/v123 # git push : refs/for/main/topic(B) -test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL)" ' +test_expect_success "proc-receive: fall through, let receive-pack to execute ($PROTOCOL)" ' git -C workbench push origin \ $B:refs/for/main/topic \ >out 2>&1 && diff --git a/t/t5411/test-0035-report-ft--porcelain.sh b/t/t5411/test-0035-report-ft--porcelain.sh index b9a05181f1ac7a..df5fc212be4081 100644 --- a/t/t5411/test-0035-report-ft--porcelain.sh +++ b/t/t5411/test-0035-report-ft--porcelain.sh @@ -10,7 +10,7 @@ test_expect_success "setup proc-receive hook (fall-through, $PROTOCOL/porcelain) # Refs of upstream : main(A) # Refs of workbench: main(A) tags/v123 # git push : refs/for/main/topic(B) -test_expect_success "proc-receive: fall throught, let receive-pack to execute ($PROTOCOL/porcelain)" ' +test_expect_success "proc-receive: fall through, let receive-pack to execute ($PROTOCOL/porcelain)" ' git -C workbench push --porcelain origin \ $B:refs/for/main/topic \ >out 2>&1 && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 585ea0ee168319..2677cd5faa8253 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -417,7 +417,7 @@ test_expect_success 'in_vain not triggered before first ACK' ' test_grep "remote: Total 3 " log ' -test_expect_success 'in_vain resetted upon ACK' ' +test_expect_success 'in_vain reset upon ACK' ' test_when_finished rm -f log trace2 && rm -rf myserver myclient && git init myserver && @@ -773,7 +773,7 @@ do # file with scheme for p in file do - test_expect_success !MINGW "fetch-pack --diag-url $p://$h/$r" ' + test_expect_success !WINDOWS "fetch-pack --diag-url $p://$h/$r" ' check_prot_path $p://$h/$r $p "/$r" ' test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" ' @@ -783,7 +783,7 @@ do check_prot_path $p:///$r $p "/$r" ' # No "/~" -> "~" conversion for file - test_expect_success !MINGW "fetch-pack --diag-url $p://$h/~$r" ' + test_expect_success !WINDOWS "fetch-pack --diag-url $p://$h/~$r" ' check_prot_path $p://$h/~$r $p "/~$r" ' test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" ' @@ -805,11 +805,17 @@ do p=ssh for h in host [::1] do - test_expect_success "fetch-pack --diag-url $h:$r" ' + expectation="success" + if test_have_prereq CYGWIN && test "$h" = "[::1]" + then + expectation="failure" + fi + + test_expect_$expectation "fetch-pack --diag-url $h:$r" ' check_prot_host_port_path $h:$r $p "$h" NONE "$r" ' # Do "/~" -> "~" conversion - test_expect_success "fetch-pack --diag-url $h:/~$r" ' + test_expect_$expectation "fetch-pack --diag-url $h:/~$r" ' check_prot_host_port_path $h:/~$r $p "$h" NONE "~$r" ' done @@ -919,6 +925,13 @@ test_expect_success 'fetch exclude tag one' ' test_cmp expected actual ' +test_expect_success 'fetch exclude tag one as revision' ' + test_when_finished rm -f rev err && + git -C shallow-exclude rev-parse one >rev && + test_must_fail git -C shallow12 fetch --shallow-exclude $(cat rev) origin 2>err && + grep "deepen-not is not a ref:" err +' + test_expect_success 'fetching deepen' ' test_create_repo shallow-deepen && ( diff --git a/t/t5501-fetch-push-alternates.sh b/t/t5501-fetch-push-alternates.sh index 0c8668a1b8e3e3..66f19a4ef2b6ed 100755 --- a/t/t5501-fetch-push-alternates.sh +++ b/t/t5501-fetch-push-alternates.sh @@ -4,7 +4,6 @@ test_description='fetch/push involving alternates' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh count_objects () { diff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh index 7b3ff21b984ff4..b160f8b7fb7e1f 100755 --- a/t/t5502-quickfetch.sh +++ b/t/t5502-quickfetch.sh @@ -5,7 +5,6 @@ test_description='test quickfetch from local' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh index 5ebbaa489689dc..845ca43ea0a7d7 100755 --- a/t/t5503-tagfollow.sh +++ b/t/t5503-tagfollow.sh @@ -5,7 +5,6 @@ test_description='test automatic tag following' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # End state of the repository: @@ -161,4 +160,18 @@ test_expect_success 'new clone fetch main and tags' ' test_cmp expect actual ' +test_expect_success 'fetch specific OID with tag following' ' + git init --bare clone3.git && + ( + cd clone3.git && + git remote add origin .. && + git fetch origin $B:refs/heads/main && + + git -C .. for-each-ref >expect && + git for-each-ref >actual && + + test_cmp expect actual + ) +' + test_done diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 138e6778a47765..58074506c599b1 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -4,7 +4,6 @@ test_description='fetch/receive strict mode' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup and inject "corrupt or missing" object' ' @@ -65,12 +64,6 @@ test_expect_success 'fetch with transfer.fsckobjects' ' ) ' -cat >exp <<EOF -To dst -! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects) -Done -EOF - test_expect_success 'push without strict' ' rm -rf dst && git init dst && @@ -79,6 +72,11 @@ test_expect_success 'push without strict' ' git config fetch.fsckobjects false && git config transfer.fsckobjects false ) && + cat >exp <<-\EOF && + To dst + ! refs/heads/main:refs/heads/test [remote rejected] (missing necessary objects) + Done + EOF test_must_fail git push --porcelain dst main:refs/heads/test >act && test_cmp exp act ' @@ -95,11 +93,6 @@ test_expect_success 'push with !receive.fsckobjects' ' test_cmp exp act ' -cat >exp <<EOF -To dst -! refs/heads/main:refs/heads/test [remote rejected] (unpacker error) -EOF - test_expect_success 'push with receive.fsckobjects' ' rm -rf dst && git init dst && @@ -108,6 +101,10 @@ test_expect_success 'push with receive.fsckobjects' ' git config receive.fsckobjects true && git config transfer.fsckobjects false ) && + cat >exp <<-\EOF && + To dst + ! refs/heads/main:refs/heads/test [remote rejected] (unpacker error) + EOF test_must_fail git push --porcelain dst main:refs/heads/test >act && test_cmp exp act ' @@ -130,15 +127,14 @@ test_expect_success 'repair the "corrupt or missing" object' ' git fsck ' -cat >bogus-commit <<EOF -tree $EMPTY_TREE -author Bugs Bunny 1234567890 +0000 -committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000 - -This commit object intentionally broken -EOF - test_expect_success 'setup bogus commit' ' + cat >bogus-commit <<-EOF && + tree $EMPTY_TREE + author Bugs Bunny 1234567890 +0000 + committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000 + + This commit object intentionally broken + EOF commit="$(git hash-object --literally -t commit -w --stdin <bogus-commit)" ' @@ -168,10 +164,12 @@ test_expect_success 'fsck with unsorted skipList' ' test_expect_success 'fsck with invalid or bogus skipList input' ' git -c fsck.skipList=/dev/null -c fsck.missingEmail=ignore fsck && + test_must_fail git -c fsck.skipList -c fsck.missingEmail=ignore fsck 2>err && + test_grep "unable to parse '\'fsck.skiplist\'' from command-line config" err && test_must_fail git -c fsck.skipList=does-not-exist -c fsck.missingEmail=ignore fsck 2>err && test_grep "could not open.*: does-not-exist" err && test_must_fail git -c fsck.skipList=.git/config -c fsck.missingEmail=ignore fsck 2>err && - test_grep "invalid object name: \[core\]" err + test_grep "invalid object name: " err ' test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' ' @@ -214,6 +212,11 @@ test_expect_success 'fsck with exhaustive accepted skipList input (various types test_must_be_empty err ' +test_expect_success 'receive-pack with missing receive.fsck.skipList path' ' + test_must_fail git -c receive.fsck.skipList receive-pack dst 2>err && + test_grep "unable to parse '\'receive.fsck.skiplist\'' from command-line config" err +' + test_expect_success 'push with receive.fsck.skipList' ' git push . $commit:refs/heads/bogus && rm -rf dst && @@ -234,7 +237,7 @@ test_expect_success 'push with receive.fsck.skipList' ' test_grep "could not open.*: does-not-exist" err && git --git-dir=dst/.git config receive.fsck.skipList config && test_must_fail git push --porcelain dst bogus 2>err && - test_grep "invalid object name: \[core\]" err && + test_grep "invalid object name: " err && git --git-dir=dst/.git config receive.fsck.skipList SKIP && git push --porcelain dst bogus @@ -256,6 +259,9 @@ test_expect_success 'fetch with fetch.fsck.skipList' ' test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec && # Invalid and/or bogus skipList input + test_must_fail git --git-dir=dst/.git -c fetch.fsck.skipList fetch \ + "file://$(pwd)" $refspec 2>err && + test_grep "unable to parse '\'fetch.fsck.skiplist\'' from command-line config" err && git --git-dir=dst/.git config fetch.fsck.skipList /dev/null && test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec && git --git-dir=dst/.git config fetch.fsck.skipList does-not-exist && @@ -263,7 +269,7 @@ test_expect_success 'fetch with fetch.fsck.skipList' ' test_grep "could not open.*: does-not-exist" err && git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/config && test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err && - test_grep "invalid object name: \[core\]" err && + test_grep "invalid object name: " err && git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/SKIP && git --git-dir=dst/.git fetch "file://$(pwd)" $refspec diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 532035933f3326..bb7e0c6879ed8a 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -2,7 +2,9 @@ test_description='git remote porcelain-ish' -TEST_PASSES_SANITIZE_LEAK=true +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + . ./test-lib.sh setup_repository () { @@ -71,7 +73,7 @@ test_expect_success 'add another remote' ' cd test && git remote add -f second ../two && tokens_match "origin second" "$(git remote)" && - check_tracking_branch second main side another && + check_tracking_branch second main side another HEAD && git for-each-ref "--format=%(refname)" refs/remotes | sed -e "/^refs\/remotes\/origin\//d" \ -e "/^refs\/remotes\/second\//d" >actual && @@ -429,16 +431,90 @@ test_expect_success 'set-head --auto' ' ) ' +test_expect_success REFFILES 'set-head --auto failure' ' + test_when_finished "rm -f test/.git/refs/remotes/origin/HEAD.lock" && + ( + cd test && + touch .git/refs/remotes/origin/HEAD.lock && + test_must_fail git remote set-head --auto origin 2>err && + tail -n1 err >output && + echo "error: Could not set up refs/remotes/origin/HEAD" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects creation' ' + ( + cd test && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} is now created and points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto to update a non symbolic ref' ' + ( + cd test && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git update-ref refs/remotes/origin/HEAD HEAD && + HEAD=$(git log --pretty="%H") && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} was detached at ${SQ}${HEAD}${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects no change' ' + ( + cd test && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects change' ' + ( + cd test && + git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/ahead && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} has changed from ${SQ}ahead${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects strange ref' ' + ( + cd test && + git symbolic-ref refs/remotes/origin/HEAD refs/heads/main && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} used to point to ${SQ}refs/heads/main${SQ} (which is not a remote branch), but now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + test_expect_success 'set-head --auto has no problem w/multiple HEADs' ' ( cd test && git fetch two "refs/heads/*:refs/remotes/two/*" && git remote set-head --auto two >output 2>&1 && - echo "two/HEAD set to main" >expect && + echo "${SQ}two/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect && test_cmp expect output ) ' +test_expect_success 'set-head changes followRemoteHEAD always to warn' ' + ( + cd test && + git config set remote.origin.followRemoteHEAD "always" && + git remote set-head --auto origin && + git config get remote.origin.followRemoteHEAD >actual && + echo "warn" >expect && + test_cmp expect actual + ) +' + cat >test/expect <<\EOF refs/remotes/origin/side2 EOF @@ -453,6 +529,16 @@ test_expect_success 'set-head explicit' ' ) ' +test_expect_success 'set-head --auto reports change' ' + ( + cd test && + git remote set-head origin side2 && + git remote set-head --auto origin >output 2>&1 && + echo "${SQ}origin/HEAD${SQ} has changed from ${SQ}side2${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + cat >test/expect <<EOF Pruning origin URL: $(pwd)/one @@ -493,6 +579,26 @@ test_expect_success 'add --mirror && prune' ' ) ' +test_expect_success 'add --mirror setting HEAD' ' + mkdir headmirror && + ( + cd headmirror && + git init --bare -b notmain && + git remote add --mirror -f origin ../one && + test "$(git symbolic-ref HEAD)" = "refs/heads/main" + ) +' + +test_expect_success 'non-mirror fetch does not interfere with mirror' ' + test_when_finished rm -rf headnotmain && + ( + git init --bare -b notmain headnotmain && + cd headnotmain && + git remote add -f other ../two && + test "$(git symbolic-ref HEAD)" = "refs/heads/notmain" + ) +' + test_expect_success 'add --mirror=fetch' ' mkdir mirror-fetch && git init -b main mirror-fetch/parent && @@ -712,8 +818,10 @@ test_expect_success 'reject --no-no-tags' ' ' cat >one/expect <<\EOF + apis/HEAD -> apis/main apis/main apis/side + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -731,11 +839,14 @@ test_expect_success 'update' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side + manduca/HEAD -> manduca/main manduca/main manduca/side + megaloprepus/HEAD -> megaloprepus/main megaloprepus/main megaloprepus/side EOF @@ -743,7 +854,7 @@ EOF test_expect_success 'update with arguments' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -775,10 +886,13 @@ test_expect_success 'update --prune' ' ' cat >one/expect <<-\EOF + apis/HEAD -> apis/main apis/main apis/side + manduca/HEAD -> manduca/main manduca/main manduca/side + megaloprepus/HEAD -> megaloprepus/main megaloprepus/main megaloprepus/side EOF @@ -786,7 +900,7 @@ EOF test_expect_success 'update default' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -798,6 +912,7 @@ test_expect_success 'update default' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -806,7 +921,7 @@ EOF test_expect_success 'update default (overridden, with funny whitespace)' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -820,7 +935,7 @@ test_expect_success 'update default (overridden, with funny whitespace)' ' test_expect_success 'update (with remotes.default defined)' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -1008,7 +1123,7 @@ Pull: refs/heads/main:refs/heads/origin Pull: refs/heads/next:refs/heads/origin2 EOF -test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'migrate a remote from named file in $GIT_DIR/remotes' ' git clone one five && origin_url=$(pwd)/one && ( @@ -1034,7 +1149,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' ' ) ' -test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'migrate a remote from named file in $GIT_DIR/branches' ' git clone --template= one six && origin_url=$(pwd)/one && ( @@ -1050,7 +1165,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' ' ) ' -test_expect_success 'migrate a remote from named file in $GIT_DIR/branches (2)' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'migrate a remote from named file in $GIT_DIR/branches (2)' ' git clone --template= one seven && ( cd seven && diff --git a/t/t5506-remote-groups.sh b/t/t5506-remote-groups.sh index 0e176175a35357..16e9a1bc2f2c95 100755 --- a/t/t5506-remote-groups.sh +++ b/t/t5506-remote-groups.sh @@ -4,7 +4,6 @@ test_description='git remote group handling' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh mark() { diff --git a/t/t5507-remote-environment.sh b/t/t5507-remote-environment.sh index c6a6957c5001e9..a41d5b370b8f26 100755 --- a/t/t5507-remote-environment.sh +++ b/t/t5507-remote-environment.sh @@ -2,7 +2,6 @@ test_description='check environment showed to remote side of transports' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up "remote" push situation' ' diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh index f029ae0d286043..095df1a7535d57 100755 --- a/t/t5509-fetch-push-namespaces.sh +++ b/t/t5509-fetch-push-namespaces.sh @@ -4,7 +4,6 @@ test_description='fetch/push involving ref namespaces' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 0890b9f61c56cc..5f350facf5edbb 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -5,7 +5,6 @@ test_description='Per branch config variables affects "git fetch". ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bundle.sh @@ -35,14 +34,11 @@ test_expect_success "clone and setup child repos" ' git clone . three && ( cd three && - git config branch.main.remote two && - git config branch.main.merge refs/heads/one && - mkdir -p .git/remotes && - cat >.git/remotes/two <<-\EOF - URL: ../two/.git/ - Pull: refs/heads/main:refs/heads/two - Pull: refs/heads/one:refs/heads/one - EOF + git config set remote.two.url ../two/.git/ && + git config set remote.two.fetch refs/heads/main:refs/heads/two && + git config set --append remote.two.fetch refs/heads/one:refs/heads/one && + git config set branch.main.remote two && + git config set branch.main.merge refs/heads/one ) && git clone . bundle && git clone . seven @@ -75,6 +71,185 @@ test_expect_success "fetch test for-merge" ' cut -f -2 .git/FETCH_HEAD >actual && test_cmp expected actual' +test_expect_success "fetch test remote HEAD" ' + cd "$D" && + cd two && + git fetch && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch"' + +test_expect_success "fetch test remote HEAD in bare repository" ' + test_when_finished rm -rf barerepo && + ( + cd "$D" && + git init --bare barerepo && + cd barerepo && + git remote add upstream ../two && + git fetch upstream && + git rev-parse --verify refs/remotes/upstream/HEAD && + git rev-parse --verify refs/remotes/upstream/main && + head=$(git rev-parse refs/remotes/upstream/HEAD) && + branch=$(git rev-parse refs/remotes/upstream/main) && + test "z$head" = "z$branch" + ) +' + + +test_expect_success "fetch test remote HEAD change" ' + cd "$D" && + cd two && + git switch -c other && + git push -u origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git fetch && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch"' + +test_expect_success "fetch test followRemoteHEAD never" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git config set remote.origin.followRemoteHEAD "never" && + git fetch && + test_must_fail git rev-parse --verify refs/remotes/origin/HEAD + ) +' + +test_expect_success "fetch test followRemoteHEAD warn no change" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn" && + git fetch >output && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have ${SQ}other${SQ} locally." >expect && + test_cmp expect output && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn create" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git config set remote.origin.followRemoteHEAD "warn" && + git rev-parse --verify refs/remotes/origin/main && + output=$(git fetch) && + test "z" = "z$output" && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn detached" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git update-ref refs/remotes/origin/HEAD HEAD && + HEAD=$(git log --pretty="%H") && + git config set remote.origin.followRemoteHEAD "warn" && + git fetch >output && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have a detached HEAD pointing to" \ + "${SQ}${HEAD}${SQ} locally." >expect && + test_cmp expect output + ) +' + +test_expect_success "fetch test followRemoteHEAD warn quiet" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn" && + output=$(git fetch --quiet) && + test "z" = "z$output" && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is same" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn-if-not-main" && + actual=$(git fetch) && + test "z" = "z$actual" && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is different" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn-if-not-some/different-branch" && + git fetch >actual && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have ${SQ}other${SQ} locally." >expect && + test_cmp expect actual && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD always" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "always" && + git fetch && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" + ) +' + test_expect_success 'fetch --prune on its own works as expected' ' cd "$D" && git clone . prune && @@ -165,6 +340,23 @@ test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' git rev-parse sometag ' +test_expect_success 'fetch --tags gets tags even without a configured remote' ' + REMOTE="$(pwd)/test_tag_1" && + git init test_tag_1 && + ( + cd test_tag_1 && + test_commit foo + ) && + git init test_tag_2 && + ( + cd test_tag_2 && + git fetch --tags "file://$REMOTE" && + echo "foo" >expect && + git tag >actual && + test_cmp expect actual + ) +' + test_expect_success REFFILES 'fetch --prune fails to delete branches' ' cd "$D" && git clone . prune-fail && @@ -1062,7 +1254,12 @@ test_expect_success 'all boundary commits are excluded' ' test_tick && git merge otherside && ad=$(git log --no-walk --format=%ad HEAD) && - git bundle create twoside-boundary.bdl main --since="$ad" && + + # If the a different name hash function is used here, then no delta + # pair is found and the bundle does not expand to three objects + # when fixing the thin object. + GIT_TEST_NAME_HASH_VERSION=1 \ + git bundle create twoside-boundary.bdl main --since="$ad" && test_bundle_object_count --thin twoside-boundary.bdl 3 ' diff --git a/t/t5511-refspec.sh b/t/t5511-refspec.sh index fc55681a3f2cb5..be025b90f989f6 100755 --- a/t/t5511-refspec.sh +++ b/t/t5511-refspec.sh @@ -2,7 +2,6 @@ test_description='refspec parsing' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_refspec () { diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 64b3491e4ee6f6..5930f55186db23 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -5,7 +5,6 @@ test_description='git ls-remote' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh generate_references () { @@ -293,6 +292,8 @@ test_expect_success 'ls-remote with filtered symref (refname)' ' cat >expect <<-EOF && ref: refs/heads/main HEAD $rev HEAD + ref: refs/remotes/origin/main refs/remotes/origin/HEAD + $rev refs/remotes/origin/HEAD EOF git ls-remote --symref . HEAD >actual && test_cmp expect actual diff --git a/t/t5513-fetch-track.sh b/t/t5513-fetch-track.sh index c46c4dbaefc729..65d1e05bd62af9 100755 --- a/t/t5513-fetch-track.sh +++ b/t/t5513-fetch-track.sh @@ -2,7 +2,6 @@ test_description='fetch follows remote-tracking branches correctly' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index 579872c258db40..523aff626828ae 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -5,7 +5,6 @@ test_description='fetch --all works correctly' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_repository () { @@ -45,14 +44,17 @@ test_expect_success setup ' ' cat > test/expect << EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -97,6 +99,7 @@ cat > expect << EOF origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side @@ -112,8 +115,10 @@ test_expect_success 'git fetch --multiple (but only one remote)' ' ' cat > expect << EOF + one/HEAD -> one/main one/main one/side + two/HEAD -> two/main two/another two/main two/side @@ -141,7 +146,7 @@ test_expect_success 'git fetch --multiple (bad remote names)' ' test_expect_success 'git fetch --all (skipFetchAll)' ' (cd test4 && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -153,11 +158,14 @@ test_expect_success 'git fetch --all (skipFetchAll)' ' ' cat > expect << EOF + one/HEAD -> one/main one/main one/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -165,7 +173,7 @@ EOF test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' ' (cd test4 && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -221,14 +229,17 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' ' create_fetch_all_expect () { cat >expect <<-\EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -265,6 +276,7 @@ test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' ' create_fetch_one_expect () { cat >expect <<-\EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh index c100a809c5e59f..4e6026c6114fb8 100755 --- a/t/t5515-fetch-merge-logic.sh +++ b/t/t5515-fetch-merge-logic.sh @@ -14,7 +14,6 @@ export GIT_TEST_PROTOCOL_VERSION GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh build_script () { @@ -105,28 +104,31 @@ test_expect_success setup ' git config remote.config-glob.fetch refs/heads/*:refs/remotes/rem/* && remotes="$remotes config-glob" && - mkdir -p .git/remotes && - cat >.git/remotes/remote-explicit <<-\EOF && - URL: ../.git/ - Pull: refs/heads/main:remotes/rem/main - Pull: refs/heads/one:remotes/rem/one - Pull: two:remotes/rem/two - Pull: refs/heads/three:remotes/rem/three - EOF - remotes="$remotes remote-explicit" && - - cat >.git/remotes/remote-glob <<-\EOF && - URL: ../.git/ - Pull: refs/heads/*:refs/remotes/rem/* - EOF - remotes="$remotes remote-glob" && - - mkdir -p .git/branches && - echo "../.git" > .git/branches/branches-default && - remotes="$remotes branches-default" && - - echo "../.git#one" > .git/branches/branches-one && - remotes="$remotes branches-one" && + if test_have_prereq WITHOUT_BREAKING_CHANGES + then + mkdir -p .git/remotes && + cat >.git/remotes/remote-explicit <<-\EOF && + URL: ../.git/ + Pull: refs/heads/main:remotes/rem/main + Pull: refs/heads/one:remotes/rem/one + Pull: two:remotes/rem/two + Pull: refs/heads/three:remotes/rem/three + EOF + remotes="$remotes remote-explicit" && + + cat >.git/remotes/remote-glob <<-\EOF && + URL: ../.git/ + Pull: refs/heads/*:refs/remotes/rem/* + EOF + remotes="$remotes remote-glob" && + + mkdir -p .git/branches && + echo "../.git" > .git/branches/branches-default && + remotes="$remotes branches-default" && + + echo "../.git#one" > .git/branches/branches-one && + remotes="$remotes branches-one" + fi && for remote in $remotes ; do git config branch.br-$remote.remote $remote && diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 331778bd42cac3..85ed049627d2e6 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -19,7 +19,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) @@ -976,7 +975,7 @@ test_expect_success 'allow push to HEAD of non-bare repository (config)' ' ! grep "warning: updating the current branch" stderr ' -test_expect_success 'fetch with branches' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'fetch with branches' ' mk_empty testrepo && git branch second $the_first_commit && git checkout second && @@ -992,7 +991,7 @@ test_expect_success 'fetch with branches' ' git checkout main ' -test_expect_success 'fetch with branches containing #' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'fetch with branches containing #' ' mk_empty testrepo && mkdir testrepo/.git/branches && echo "..#second" > testrepo/.git/branches/branch2 && @@ -1006,7 +1005,7 @@ test_expect_success 'fetch with branches containing #' ' git checkout main ' -test_expect_success 'push with branches' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'push with branches' ' mk_empty testrepo && git checkout second && @@ -1023,7 +1022,7 @@ test_expect_success 'push with branches' ' ) ' -test_expect_success 'push with branches containing #' ' +test_expect_success WITHOUT_BREAKING_CHANGES 'push with branches containing #' ' mk_empty testrepo && test_when_finished "rm -rf .git/branches" && @@ -1212,18 +1211,16 @@ test_expect_success 'push --porcelain --dry-run rejected' ' ' test_expect_success 'push --prune' ' - mk_test testrepo heads/main heads/second heads/foo heads/bar && + mk_test testrepo heads/main heads/foo heads/bar && git push --prune testrepo : && check_push_result testrepo $the_commit heads/main && - check_push_result testrepo $the_first_commit heads/second && ! check_push_result testrepo $the_first_commit heads/foo heads/bar ' test_expect_success 'push --prune refspec' ' - mk_test testrepo tmp/main tmp/second tmp/foo tmp/bar && + mk_test testrepo tmp/main tmp/foo tmp/bar && git push --prune testrepo "refs/heads/*:refs/tmp/*" && check_push_result testrepo $the_commit tmp/main && - check_push_result testrepo $the_first_commit tmp/second && ! check_push_result testrepo $the_first_commit tmp/foo tmp/bar ' @@ -1395,7 +1392,8 @@ test_expect_success 'fetch follows tags by default' ' git tag -m "annotated" tag && git for-each-ref >tmp1 && sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 | - sort -k 3 >../expect + sed -n "p; s|refs/heads/main$|refs/remotes/origin/HEAD|p" | + sort -k 4 >../expect ) && test_when_finished "rm -rf dst" && git init dst && diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh index 6d4944a7282640..a448e169bd029f 100755 --- a/t/t5517-push-mirror.sh +++ b/t/t5517-push-mirror.sh @@ -5,7 +5,6 @@ test_description='pushing to a mirror repository' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) diff --git a/t/t5518-fetch-exit-status.sh b/t/t5518-fetch-exit-status.sh index c13120088fa684..5c4ac2556e7820 100755 --- a/t/t5518-fetch-exit-status.sh +++ b/t/t5518-fetch-exit-status.sh @@ -8,7 +8,6 @@ test_description='fetch exit status test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5519-push-alternates.sh b/t/t5519-push-alternates.sh index 72e97b15fabbb8..20ba604dfde162 100755 --- a/t/t5519-push-alternates.sh +++ b/t/t5519-push-alternates.sh @@ -5,7 +5,6 @@ test_description='push to a repository that borrows from elsewhere' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 1098cbd0a19218..47534f1062d203 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -5,7 +5,6 @@ test_description='pulling into void' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh modify () { diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index db00c4336b1671..5e420c208c7798 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -5,7 +5,6 @@ test_description='pull options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh index cc5496e28fd0bc..9fb73a8c3eb84b 100755 --- a/t/t5522-pull-symlink.sh +++ b/t/t5522-pull-symlink.sh @@ -2,7 +2,6 @@ test_description='pulling from symlinked subdir' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # The scenario we are building: diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh index 4ad36a31e18508..22d3e1162cde4e 100755 --- a/t/t5523-push-upstream.sh +++ b/t/t5523-push-upstream.sh @@ -4,7 +4,6 @@ test_description='push with --set-upstream' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh index 56716e29ddf1c3..b2be3605f5a3f0 100755 --- a/t/t5524-pull-msg.sh +++ b/t/t5524-pull-msg.sh @@ -2,7 +2,6 @@ test_description='git pull message generation' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh dollar='$Dollar' diff --git a/t/t5525-fetch-tagopt.sh b/t/t5525-fetch-tagopt.sh index 3a28f1ded5fdcc..45815f737850b6 100755 --- a/t/t5525-fetch-tagopt.sh +++ b/t/t5525-fetch-tagopt.sh @@ -2,7 +2,6 @@ test_description='tagopt variable affects "git fetch" and is overridden by commandline.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_clone () { diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index 2cfb5bd6bb1e86..5e566205ba4b95 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -6,7 +6,6 @@ test_description='Recursive "git fetch" for submodules' GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pwd=$(pwd) diff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh index 98ece27c6a0819..0de8eb5b6f8855 100755 --- a/t/t5527-fetch-odd-refs.sh +++ b/t/t5527-fetch-odd-refs.sh @@ -4,7 +4,6 @@ test_description='test fetching of oddly-named refs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # afterwards we will have: @@ -52,7 +51,8 @@ test_expect_success LONG_REF 'fetch handles extremely long refname' ' long main EOF - git for-each-ref --format="%(subject)" refs/remotes/long >actual && + git for-each-ref --format="%(subject)" refs/remotes/long \ + --exclude=refs/remotes/long/HEAD >actual && test_cmp expect actual ' diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh index bc2bada34c6298..2bd8759a683ba0 100755 --- a/t/t5528-push-default.sh +++ b/t/t5528-push-default.sh @@ -4,7 +4,6 @@ test_description='check various push.default settings' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup bare remotes' ' @@ -147,7 +146,7 @@ test_expect_success 'push from/to new branch fails with upstream and simple ' ' # - the default push succeeds # # A previous test expected this to fail, but for the wrong reasons: -# it expected a fail becaause the branch is new and cannot be pushed, but +# it expected to fail because the branch is new and cannot be pushed, but # in fact it was failing because of an ambiguous remote # test_expect_failure 'push from/to new branch fails with matching ' ' diff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh index 17d72578926acc..80b06a0cd2886d 100755 --- a/t/t5529-push-errors.sh +++ b/t/t5529-push-errors.sh @@ -5,7 +5,6 @@ test_description='detect some push errors early (before contacting remote)' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commits' ' diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index 7172780d5502a9..558eedf25a4c9b 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -2,7 +2,6 @@ test_description='errors in upload-pack' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index 135823630a37c6..05debd1134db49 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -204,7 +203,7 @@ test_expect_success 'push recurse-submodules last one wins on command line' ' cd work/gar/bage && >recurse-check-on-command-line-overriding-earlier-command-line && git add recurse-check-on-command-line-overriding-earlier-command-line && - git commit -m "Recurse on command-line overridiing earlier command-line junk" + git commit -m "Recurse on command-line overriding earlier command-line junk" ) && ( cd work && diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh index d664912799b43a..37558226290f43 100755 --- a/t/t5532-fetch-proxy.sh +++ b/t/t5532-fetch-proxy.sh @@ -2,7 +2,6 @@ test_description='fetching via git:// using core.gitproxy' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup remote repo' ' diff --git a/t/t5533-push-cas.sh b/t/t5533-push-cas.sh index 6365d99777ead2..cba26a872dde46 100755 --- a/t/t5533-push-cas.sh +++ b/t/t5533-push-cas.sh @@ -5,7 +5,6 @@ test_description='compare & swap push force/delete safety' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_srcdst_basic () { diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh index d43aee0c327c0b..c91a62b77afcfb 100755 --- a/t/t5534-push-signed.sh +++ b/t/t5534-push-signed.sh @@ -5,7 +5,6 @@ test_description='signed push' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh index 7122af7fdb50ac..e8f6d233ffb80b 100755 --- a/t/t5535-fetch-push-symref.sh +++ b/t/t5535-fetch-push-symref.sh @@ -2,7 +2,6 @@ test_description='avoiding conflicting update through symref aliasing' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5536-fetch-conflicts.sh b/t/t5536-fetch-conflicts.sh index 2dcbe790523cc3..23bf69617007d7 100755 --- a/t/t5536-fetch-conflicts.sh +++ b/t/t5536-fetch-conflicts.sh @@ -2,7 +2,6 @@ test_description='fetch handles conflicting refspecs correctly' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh index cae4d400f32e8b..37f7547a4cadb2 100755 --- a/t/t5537-fetch-shallow.sh +++ b/t/t5537-fetch-shallow.sh @@ -5,7 +5,6 @@ test_description='fetch/clone from a shallow clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit() { diff --git a/t/t5538-push-shallow.sh b/t/t5538-push-shallow.sh index 6adc3a20a45b77..e91fcc173e8116 100755 --- a/t/t5538-push-shallow.sh +++ b/t/t5538-push-shallow.sh @@ -5,7 +5,6 @@ test_description='push from/to a shallow clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit() { diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh index 37db3dec0c5b39..3fa05ff18540be 100755 --- a/t/t5540-http-push-webdav.sh +++ b/t/t5540-http-push-webdav.sh @@ -201,4 +201,14 @@ test_expect_failure 'push to password-protected repository (no user in URL)' ' test_cmp expect actual ' +test_expect_success 'push to password-protected repository (netrc)' ' + test_commit pw-netrc && + echo "default login user@host password pass@host" >"$HOME/.netrc" && + GIT_TRACE=1 GIT_CURL_VERBOSE=1 git push "$HTTPD_URL/auth/dumb/test_repo.git" HEAD && + git rev-parse --verify HEAD >expect && + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \ + rev-parse --verify HEAD >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 71428f3d5c760a..538b603f03a1f8 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -343,7 +343,7 @@ test_expect_success 'push over smart http with auth' ' git push "$HTTPD_URL"/auth/smart/test_repo.git && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \ log -1 --format=%s >actual && - expect_askpass both user@host && + expect_askpass both user%40host && test_cmp expect actual ' @@ -355,7 +355,7 @@ test_expect_success 'push to auth-only-for-push repo' ' git push "$HTTPD_URL"/auth-push/smart/test_repo.git && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \ log -1 --format=%s >actual && - expect_askpass both user@host && + expect_askpass both user%40host && test_cmp expect actual ' @@ -385,7 +385,7 @@ test_expect_success 'push into half-auth-complete requires password' ' git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \ log -1 --format=%s >actual && - expect_askpass both user@host && + expect_askpass both user%40host && test_cmp expect actual ' diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh index 479d103469527e..3a700b06761db4 100755 --- a/t/t5543-atomic-push.sh +++ b/t/t5543-atomic-push.sh @@ -5,7 +5,6 @@ test_description='pushing to a repository using the atomic push option' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh mk_repo_pair () { @@ -281,4 +280,34 @@ test_expect_success 'atomic push reports (reject by non-ff)' ' test_cmp expect actual ' +test_expect_success 'atomic push reports exit code failure' ' + write_script receive-pack-wrapper <<-\EOF && + git-receive-pack "$@" + exit 1 + EOF + test_must_fail git -C workbench push --atomic \ + --receive-pack="${SQ}$(pwd)${SQ}/receive-pack-wrapper" \ + up HEAD:refs/heads/no-conflict 2>err && + cat >expect <<-EOF && + To ../upstream + * [new branch] HEAD -> no-conflict + error: failed to push some refs to ${SQ}../upstream${SQ} + EOF + test_cmp expect err +' + +test_expect_success 'atomic push reports exit code failure with porcelain' ' + write_script receive-pack-wrapper <<-\EOF && + git-receive-pack "$@" + exit 1 + EOF + test_must_fail git -C workbench push --atomic --porcelain \ + --receive-pack="${SQ}$(pwd)${SQ}/receive-pack-wrapper" \ + up HEAD:refs/heads/no-conflict-porcelain 2>err && + cat >expect <<-EOF && + error: failed to push some refs to ${SQ}../upstream${SQ} + EOF + test_cmp expect err +' + test_done diff --git a/t/t5544-pack-objects-hook.sh b/t/t5544-pack-objects-hook.sh index 1a9e14bbccd3c5..89147a052e72cd 100755 --- a/t/t5544-pack-objects-hook.sh +++ b/t/t5544-pack-objects-hook.sh @@ -2,7 +2,6 @@ test_description='test custom script in place of pack-objects' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create some history to fetch' ' diff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh index 9fc9ba552f1db3..f1e61c9f09572e 100755 --- a/t/t5546-receive-limits.sh +++ b/t/t5546-receive-limits.sh @@ -2,7 +2,6 @@ test_description='check receive input limits' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Let's run tests with different unpack limits: 1 and 10000 diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh index 9f899b8c7d7bcc..0798ddab02bc8b 100755 --- a/t/t5547-push-quarantine.sh +++ b/t/t5547-push-quarantine.sh @@ -2,7 +2,6 @@ test_description='check quarantine of objects during push' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create picky dest repo' ' diff --git a/t/t5548-push-porcelain.sh b/t/t5548-push-porcelain.sh index ecb3877aa4bf1b..4c19404ebe9be6 100755 --- a/t/t5548-push-porcelain.sh +++ b/t/t5548-push-porcelain.sh @@ -4,7 +4,6 @@ # test_description='Test git push porcelain output' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Create commits in <repo> and assign each commit's oid to shell variables @@ -55,29 +54,67 @@ format_and_save_expect () { sed -e 's/^> //' -e 's/Z$//' >expect } +create_upstream_template () { + git init --bare upstream-template.git && + git clone upstream-template.git tmp_work_dir && + create_commits_in tmp_work_dir A B && + ( + cd tmp_work_dir && + git push origin \ + $B:refs/heads/main \ + $A:refs/heads/foo \ + $A:refs/heads/bar \ + $A:refs/heads/baz + ) && + rm -rf tmp_work_dir +} + +setup_upstream () { + if test $# -ne 1 + then + BUG "location of upstream repository is not provided" + fi && + rm -rf "$1" && + if ! test -d upstream-template.git + then + create_upstream_template + fi && + git clone --mirror upstream-template.git "$1" && + # The upstream repository provides services using the HTTP protocol. + if ! test "$1" = "upstream.git" + then + git -C "$1" config http.receivepack true + fi +} + setup_upstream_and_workbench () { - # Upstream after setup : main(B) foo(A) bar(A) baz(A) - # Workbench after setup : main(A) + if test $# -ne 1 + then + BUG "location of upstream repository is not provided" + fi + upstream="$1" + + # Upstream after setup: main(B) foo(A) bar(A) baz(A) + # Workbench after setup: main(A) baz(A) next(A) test_expect_success "setup upstream repository and workbench" ' - rm -rf upstream.git workbench && - git init --bare upstream.git && - git init workbench && - create_commits_in workbench A B && + setup_upstream "$upstream" && + rm -rf workbench && + git clone "$upstream" workbench && ( cd workbench && + git update-ref refs/heads/main $A && + git update-ref refs/heads/baz $A && + git update-ref refs/heads/next $A && # Try to make a stable fixed width for abbreviated commit ID, # this fixed-width oid will be replaced with "<OID>". git config core.abbrev 7 && - git remote add origin ../upstream.git && - git update-ref refs/heads/main $A && - git push origin \ - $B:refs/heads/main \ - $A:refs/heads/foo \ - $A:refs/heads/bar \ - $A:refs/heads/baz + git config advice.pushUpdateRejected false ) && - git -C "workbench" config advice.pushUpdateRejected false && - upstream=upstream.git + # The upstream repository provides services using the HTTP protocol. + if ! test "$upstream" = "upstream.git" + then + git -C workbench remote set-url origin "$HTTPD_URL/smart/upstream.git" + fi ' } @@ -89,34 +126,29 @@ run_git_push_porcelain_output_test() { ;; file) PROTOCOL="builtin protocol" - URL_PREFIX="\.\." + URL_PREFIX=".*" ;; esac # Refs of upstream : main(B) foo(A) bar(A) baz(A) # Refs of workbench: main(A) baz(A) next(A) # git-push : main(A) NULL (B) baz(A) next(A) - test_expect_success "porcelain output of successful git-push ($PROTOCOL)" ' - ( - cd workbench && - git update-ref refs/heads/main $A && - git update-ref refs/heads/baz $A && - git update-ref refs/heads/next $A && - git push --porcelain --force origin \ - main \ - :refs/heads/foo \ - $B:bar \ - baz \ - next - ) >out && + test_expect_success ".. git-push --porcelain ($PROTOCOL)" ' + test_when_finished "setup_upstream \"$upstream\"" && + test_must_fail git -C workbench push --porcelain origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && make_user_friendly_and_stable_output <out >actual && - format_and_save_expect <<-EOF && + format_and_save_expect <<-\EOF && > To <URL/of/upstream.git> > = refs/heads/baz:refs/heads/baz [up to date] > <COMMIT-B>:refs/heads/bar <COMMIT-A>..<COMMIT-B> > - :refs/heads/foo [deleted] - > + refs/heads/main:refs/heads/main <COMMIT-B>...<COMMIT-A> (forced update) > * refs/heads/next:refs/heads/next [new branch] + > ! refs/heads/main:refs/heads/main [rejected] (non-fast-forward) > Done EOF test_cmp expect actual && @@ -126,34 +158,32 @@ run_git_push_porcelain_output_test() { cat >expect <<-EOF && <COMMIT-B> refs/heads/bar <COMMIT-A> refs/heads/baz - <COMMIT-A> refs/heads/main + <COMMIT-B> refs/heads/main <COMMIT-A> refs/heads/next EOF test_cmp expect actual ' - # Refs of upstream : main(A) bar(B) baz(A) next(A) - # Refs of workbench: main(B) bar(A) baz(A) next(A) - # git-push : main(B) bar(A) NULL next(A) - test_expect_success "atomic push failed ($PROTOCOL)" ' - ( - cd workbench && - git update-ref refs/heads/main $B && - git update-ref refs/heads/bar $A && - test_must_fail git push --atomic --porcelain origin \ - main \ - bar \ - :baz \ - next - ) >out && + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git-push --porcelain --force ($PROTOCOL)" ' + test_when_finished "setup_upstream \"$upstream\"" && + git -C workbench push --porcelain --force origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && make_user_friendly_and_stable_output <out >actual && format_and_save_expect <<-EOF && - To <URL/of/upstream.git> - > = refs/heads/next:refs/heads/next [up to date] - > ! refs/heads/bar:refs/heads/bar [rejected] (non-fast-forward) - > ! (delete):refs/heads/baz [rejected] (atomic push failed) - > ! refs/heads/main:refs/heads/main [rejected] (atomic push failed) - Done + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > <COMMIT-B>:refs/heads/bar <COMMIT-A>..<COMMIT-B> + > - :refs/heads/foo [deleted] + > + refs/heads/main:refs/heads/main <COMMIT-B>...<COMMIT-A> (forced update) + > * refs/heads/next:refs/heads/next [new branch] + > Done EOF test_cmp expect actual && @@ -168,34 +198,129 @@ run_git_push_porcelain_output_test() { test_cmp expect actual ' - test_expect_success "prepare pre-receive hook ($PROTOCOL)" ' - test_hook --setup -C "$upstream" pre-receive <<-EOF - exit 1 + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git push --porcelain --atomic ($PROTOCOL)" ' + test_when_finished "setup_upstream \"$upstream\"" && + test_must_fail git -C workbench push --porcelain --atomic origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && + make_user_friendly_and_stable_output <out >actual && + format_and_save_expect <<-EOF && + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > ! <COMMIT-B>:refs/heads/bar [rejected] (atomic push failed) + > ! (delete):refs/heads/foo [rejected] (atomic push failed) + > ! refs/heads/main:refs/heads/main [rejected] (non-fast-forward) + > ! refs/heads/next:refs/heads/next [rejected] (atomic push failed) + > Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/main + EOF + test_cmp expect actual + ' + + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. pre-receive hook declined ($PROTOCOL)" ' + test_when_finished "rm -f \"$upstream/hooks/pre-receive\" && + setup_upstream \"$upstream\"" && + test_hook --setup -C "$upstream" pre-receive <<-EOF && + exit 1 + EOF + test_must_fail git -C workbench push --porcelain --force origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && + make_user_friendly_and_stable_output <out >actual && + format_and_save_expect <<-EOF && + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > ! <COMMIT-B>:refs/heads/bar [remote rejected] (pre-receive hook declined) + > ! :refs/heads/foo [remote rejected] (pre-receive hook declined) + > ! refs/heads/main:refs/heads/main [remote rejected] (pre-receive hook declined) + > ! refs/heads/next:refs/heads/next [remote rejected] (pre-receive hook declined) + > Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/main EOF + test_cmp expect actual ' - # Refs of upstream : main(A) bar(B) baz(A) next(A) - # Refs of workbench: main(B) bar(A) baz(A) next(A) - # git-push : main(B) bar(A) NULL next(A) - test_expect_success "pre-receive hook declined ($PROTOCOL)" ' + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) next(A) + test_expect_success ".. non-fastforward push ($PROTOCOL)" ' + test_when_finished "setup_upstream \"$upstream\"" && ( cd workbench && - git update-ref refs/heads/main $B && - git update-ref refs/heads/bar $A && - test_must_fail git push --porcelain --force origin \ + test_must_fail git push --porcelain origin \ main \ - bar \ - :baz \ next ) >out && make_user_friendly_and_stable_output <out >actual && format_and_save_expect <<-EOF && - To <URL/of/upstream.git> - > = refs/heads/next:refs/heads/next [up to date] - > ! refs/heads/bar:refs/heads/bar [remote rejected] (pre-receive hook declined) - > ! :refs/heads/baz [remote rejected] (pre-receive hook declined) - > ! refs/heads/main:refs/heads/main [remote rejected] (pre-receive hook declined) - Done + > To <URL/of/upstream.git> + > * refs/heads/next:refs/heads/next [new branch] + > ! refs/heads/main:refs/heads/main [rejected] (non-fast-forward) + > Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/main + <COMMIT-A> refs/heads/next + EOF + test_cmp expect actual + ' + + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git push --porcelain --atomic --force ($PROTOCOL)" ' + git -C workbench push --porcelain --atomic --force origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && + make_user_friendly_and_stable_output <out >actual && + format_and_save_expect <<-\EOF && + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > <COMMIT-B>:refs/heads/bar <COMMIT-A>..<COMMIT-B> + > - :refs/heads/foo [deleted] + > + refs/heads/main:refs/heads/main <COMMIT-B>...<COMMIT-A> (forced update) + > * refs/heads/next:refs/heads/next [new branch] + > Done EOF test_cmp expect actual && @@ -209,71 +334,174 @@ run_git_push_porcelain_output_test() { EOF test_cmp expect actual ' +} - test_expect_success "remove pre-receive hook ($PROTOCOL)" ' - rm "$upstream/hooks/pre-receive" +run_git_push_dry_run_porcelain_output_test() { + case $1 in + http) + PROTOCOL="HTTP protocol" + URL_PREFIX="http://.*" + ;; + file) + PROTOCOL="builtin protocol" + URL_PREFIX=".*" + ;; + esac + + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git-push --porcelain --dry-run ($PROTOCOL)" ' + test_must_fail git -C workbench push --porcelain --dry-run origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && + make_user_friendly_and_stable_output <out >actual && + format_and_save_expect <<-EOF && + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > <COMMIT-B>:refs/heads/bar <COMMIT-A>..<COMMIT-B> + > - :refs/heads/foo [deleted] + > * refs/heads/next:refs/heads/next [new branch] + > ! refs/heads/main:refs/heads/main [rejected] (non-fast-forward) + > Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/main + EOF + test_cmp expect actual ' - # Refs of upstream : main(A) bar(B) baz(A) next(A) - # Refs of workbench: main(B) bar(A) baz(A) next(A) - # git-push : main(B) bar(A) NULL next(A) - test_expect_success "non-fastforward push ($PROTOCOL)" ' - ( - cd workbench && - test_must_fail git push --porcelain origin \ - main \ - bar \ - :baz \ - next - ) >out && + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git-push --porcelain --dry-run --force ($PROTOCOL)" ' + git -C workbench push --porcelain --dry-run --force origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && + make_user_friendly_and_stable_output <out >actual && + format_and_save_expect <<-EOF && + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > <COMMIT-B>:refs/heads/bar <COMMIT-A>..<COMMIT-B> + > - :refs/heads/foo [deleted] + > + refs/heads/main:refs/heads/main <COMMIT-B>...<COMMIT-A> (forced update) + > * refs/heads/next:refs/heads/next [new branch] + > Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/main + EOF + test_cmp expect actual + ' + + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # git-push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git-push --porcelain --dry-run --atomic ($PROTOCOL)" ' + test_must_fail git -C workbench push --porcelain --dry-run --atomic origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && make_user_friendly_and_stable_output <out >actual && format_and_save_expect <<-EOF && - To <URL/of/upstream.git> - > = refs/heads/next:refs/heads/next [up to date] - > - :refs/heads/baz [deleted] - > refs/heads/main:refs/heads/main <COMMIT-A>..<COMMIT-B> - > ! refs/heads/bar:refs/heads/bar [rejected] (non-fast-forward) - Done + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > ! <COMMIT-B>:refs/heads/bar [rejected] (atomic push failed) + > ! (delete):refs/heads/foo [rejected] (atomic push failed) + > ! refs/heads/main:refs/heads/main [rejected] (non-fast-forward) + > ! refs/heads/next:refs/heads/next [rejected] (atomic push failed) + > Done EOF test_cmp expect actual && git -C "$upstream" show-ref >out && make_user_friendly_and_stable_output <out >actual && cat >expect <<-EOF && - <COMMIT-B> refs/heads/bar + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo + <COMMIT-B> refs/heads/main + EOF + test_cmp expect actual + ' + + # Refs of upstream : main(B) foo(A) bar(A) baz(A) + # Refs of workbench: main(A) baz(A) next(A) + # push : main(A) NULL (B) baz(A) next(A) + test_expect_success ".. git-push --porcelain --dry-run --atomic --force ($PROTOCOL)" ' + git -C workbench push --porcelain --dry-run --atomic --force origin \ + main \ + :refs/heads/foo \ + $B:bar \ + baz \ + next >out && + make_user_friendly_and_stable_output <out >actual && + format_and_save_expect <<-EOF && + > To <URL/of/upstream.git> + > = refs/heads/baz:refs/heads/baz [up to date] + > <COMMIT-B>:refs/heads/bar <COMMIT-A>..<COMMIT-B> + > - :refs/heads/foo [deleted] + > + refs/heads/main:refs/heads/main <COMMIT-B>...<COMMIT-A> (forced update) + > * refs/heads/next:refs/heads/next [new branch] + > Done + EOF + test_cmp expect actual && + + git -C "$upstream" show-ref >out && + make_user_friendly_and_stable_output <out >actual && + cat >expect <<-EOF && + <COMMIT-A> refs/heads/bar + <COMMIT-A> refs/heads/baz + <COMMIT-A> refs/heads/foo <COMMIT-B> refs/heads/main - <COMMIT-A> refs/heads/next EOF test_cmp expect actual ' } -# Initialize the upstream repository and local workbench. -setup_upstream_and_workbench +setup_upstream_and_workbench upstream.git -# Run git-push porcelain test on builtin protocol run_git_push_porcelain_output_test file +setup_upstream_and_workbench upstream.git + +run_git_push_dry_run_porcelain_output_test file + ROOT_PATH="$PWD" . "$TEST_DIRECTORY"/lib-gpg.sh . "$TEST_DIRECTORY"/lib-httpd.sh . "$TEST_DIRECTORY"/lib-terminal.sh start_httpd +setup_askpass_helper -# Re-initialize the upstream repository and local workbench. -setup_upstream_and_workbench - -test_expect_success "setup for http" ' - git -C upstream.git config http.receivepack true && - upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" && - mv upstream.git "$upstream" && +setup_upstream_and_workbench "$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" - git -C workbench remote set-url origin $HTTPD_URL/smart/upstream.git -' +run_git_push_porcelain_output_test http -setup_askpass_helper +setup_upstream_and_workbench "$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" -# Run git-push porcelain test on HTTP protocol -run_git_push_porcelain_output_test http +run_git_push_dry_run_porcelain_output_test http test_done diff --git a/t/t5549-fetch-push-http.sh b/t/t5549-fetch-push-http.sh index 6377fb6d993678..2cdebcb7356332 100755 --- a/t/t5549-fetch-push-http.sh +++ b/t/t5549-fetch-push-http.sh @@ -5,7 +5,6 @@ test_description='fetch/push functionality using the HTTP protocol' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index ea8e48f627315f..ed0ad66fade32b 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -111,13 +111,13 @@ test_expect_success 'http auth can use user/pass in URL' ' test_expect_success 'http auth can use just user in URL' ' set_askpass wrong pass@host && git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-pass && - expect_askpass pass user@host + expect_askpass pass user%40host ' test_expect_success 'http auth can request both user and pass' ' set_askpass user@host pass@host && git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-both && - expect_askpass both user@host + expect_askpass both user%40host ' test_expect_success 'http auth respects credential helper config' ' @@ -135,14 +135,14 @@ test_expect_success 'http auth can get username from config' ' test_config_global "credential.$HTTPD_URL.username" user@host && set_askpass wrong pass@host && git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-user && - expect_askpass pass user@host + expect_askpass pass user%40host ' test_expect_success 'configured username does not override URL' ' test_config_global "credential.$HTTPD_URL.username" wrong && set_askpass wrong pass@host && git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-user2 && - expect_askpass pass user@host + expect_askpass pass user%40host ' test_expect_success 'set up repo with http submodules' ' @@ -163,7 +163,7 @@ test_expect_success 'cmdline credential config passes to submodule via clone' ' set_askpass wrong pass@host && git -c "credential.$HTTPD_URL.username=user@host" \ clone --recursive super super-clone && - expect_askpass pass user@host + expect_askpass pass user%40host ' test_expect_success 'cmdline credential config passes submodule via fetch' ' @@ -174,7 +174,7 @@ test_expect_success 'cmdline credential config passes submodule via fetch' ' git -C super-clone \ -c "credential.$HTTPD_URL.username=user@host" \ fetch --recurse-submodules && - expect_askpass pass user@host + expect_askpass pass user%40host ' test_expect_success 'cmdline credential config passes submodule update' ' @@ -191,7 +191,7 @@ test_expect_success 'cmdline credential config passes submodule update' ' git -C super-clone \ -c "credential.$HTTPD_URL.username=user@host" \ submodule update && - expect_askpass pass user@host + expect_askpass pass user%40host ' test_expect_success 'fetch changes via http' ' @@ -306,6 +306,14 @@ test_expect_success 'fetch notices corrupt idx' ' ) ' +# usage: count_fetches <nr> <extension> <trace_file> +count_fetches () { + # ignore grep exit code; it may return non-zero if we are expecting no + # matches + grep "GET .*objects/pack/pack-[a-z0-9]*.$2" "$3" >trace.count + test_line_count = "$1" trace.count +} + test_expect_success 'fetch can handle previously-fetched .idx files' ' git checkout --orphan branch1 && echo base >file && @@ -320,8 +328,14 @@ test_expect_success 'fetch can handle previously-fetched .idx files' ' git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch2 && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d && git --bare init clone_packed_branches.git && - git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch1:branch1 && - git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch2:branch2 + GIT_TRACE_CURL=$PWD/one.trace git --git-dir=clone_packed_branches.git \ + fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch1:branch1 && + count_fetches 2 idx one.trace && + count_fetches 1 pack one.trace && + GIT_TRACE_CURL=$PWD/two.trace git --git-dir=clone_packed_branches.git \ + fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch2:branch2 && + count_fetches 1 idx two.trace && + count_fetches 1 pack two.trace ' test_expect_success 'did not use upload-pack service' ' @@ -343,12 +357,12 @@ test_expect_success 'git client shows text/plain with a charset' ' grep "this is the error message" stderr ' -test_expect_success 'http error messages are reencoded' ' +test_expect_success ICONV 'http error messages are reencoded' ' test_must_fail git clone "$HTTPD_URL/error/utf16" 2>stderr && grep "this is the error message" stderr ' -test_expect_success 'reencoding is robust to whitespace oddities' ' +test_expect_success ICONV 'reencoding is robust to whitespace oddities' ' test_must_fail git clone "$HTTPD_URL/error/odd-spacing" 2>stderr && grep "this is the error message" stderr ' @@ -506,4 +520,14 @@ test_expect_success 'fetching via http alternates works' ' git -c http.followredirects=true clone "$HTTPD_URL/dumb/alt-child.git" ' +test_expect_success 'dumb http can fetch index v1' ' + server=$HTTPD_DOCUMENT_ROOT_PATH/idx-v1.git && + git init --bare "$server" && + git -C "$server" --work-tree=. commit --allow-empty -m foo && + git -C "$server" -c pack.indexVersion=1 gc && + + git clone "$HTTPD_URL/dumb/idx-v1.git" && + git -C idx-v1 fsck +' + test_done diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index ceb3336a5c494f..761fdfcfe6c49d 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -181,7 +181,7 @@ test_expect_success 'clone from password-protected repository' ' echo two >expect && set_askpass user@host pass@host && git clone --bare "$HTTPD_URL/auth/smart/repo.git" smart-auth && - expect_askpass both user@host && + expect_askpass both user%40host && git --git-dir=smart-auth log -1 --format=%s >actual && test_cmp expect actual ' @@ -221,7 +221,7 @@ test_expect_success 'clone from auth-only-for-objects repository' ' echo two >expect && set_askpass user@host pass@host && git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth && - expect_askpass both user@host && + expect_askpass both user%40host && git --git-dir=half-auth log -1 --format=%s >actual && test_cmp expect actual ' @@ -246,14 +246,14 @@ test_expect_success 'redirects send auth to new location' ' set_askpass user@host pass@host && git -c credential.useHttpPath=true \ clone $HTTPD_URL/smart-redir-auth/repo.git repo-redir-auth && - expect_askpass both user@host auth/smart/repo.git + expect_askpass both user%40host auth/smart/repo.git ' test_expect_success 'GIT_TRACE_CURL redacts auth details' ' rm -rf redact-auth trace && set_askpass user@host pass@host && GIT_TRACE_CURL="$(pwd)/trace" git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth && - expect_askpass both user@host && + expect_askpass both user%40host && # Ensure that there is no "Basic" followed by a base64 string, but that # the auth details are redacted @@ -265,7 +265,7 @@ test_expect_success 'GIT_CURL_VERBOSE redacts auth details' ' rm -rf redact-auth trace && set_askpass user@host pass@host && GIT_CURL_VERBOSE=1 git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth 2>trace && - expect_askpass both user@host && + expect_askpass both user%40host && # Ensure that there is no "Basic" followed by a base64 string, but that # the auth details are redacted @@ -278,7 +278,7 @@ test_expect_success 'GIT_TRACE_CURL does not redact auth details if GIT_TRACE_RE set_askpass user@host pass@host && GIT_TRACE_REDACT=0 GIT_TRACE_CURL="$(pwd)/trace" \ git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth && - expect_askpass both user@host && + expect_askpass both user%40host && grep -i "Authorization: Basic [0-9a-zA-Z+/]" trace ' @@ -592,7 +592,7 @@ test_expect_success 'http auth remembers successful credentials' ' # the first request prompts the user... set_askpass user@host pass@host && git ls-remote "$HTTPD_URL/auth/smart/repo.git" >/dev/null && - expect_askpass both user@host && + expect_askpass both user%40host && # ...and the second one uses the stored value rather than # prompting the user. @@ -623,7 +623,7 @@ test_expect_success 'http auth forgets bogus credentials' ' # us to prompt the user again. set_askpass user@host pass@host && git ls-remote "$HTTPD_URL/auth/smart/repo.git" >/dev/null && - expect_askpass both user@host + expect_askpass both user%40host ' test_expect_success 'client falls back from v2 to v0 to match server' ' diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh index 4f2e5ae8dfa5af..eeddb85b1deaea 100755 --- a/t/t5552-skipping-fetch-negotiator.sh +++ b/t/t5552-skipping-fetch-negotiator.sh @@ -2,7 +2,6 @@ test_description='test skipping fetch negotiator' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'fetch.negotiationalgorithm config' ' diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh index 33e919a17e1670..70e3376d31b431 100755 --- a/t/t5553-set-upstream.sh +++ b/t/t5553-set-upstream.sh @@ -4,7 +4,6 @@ test_description='"git fetch/pull --set-upstream" basic tests.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_config () { diff --git a/t/t5554-noop-fetch-negotiator.sh b/t/t5554-noop-fetch-negotiator.sh index 06991e8e8aabc2..17e73b606d5324 100755 --- a/t/t5554-noop-fetch-negotiator.sh +++ b/t/t5554-noop-fetch-negotiator.sh @@ -2,7 +2,6 @@ test_description='test noop fetch negotiator' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'noop negotiator does not emit any "have"' ' diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh index 3dcb3340a36bb0..e47ea1ad106048 100755 --- a/t/t5555-http-smart-common.sh +++ b/t/t5555-http-smart-common.sh @@ -2,7 +2,6 @@ test_description='test functionality common to smart fetch & push' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5557-http-get.sh b/t/t5557-http-get.sh index 76a4bbd16afb08..67fcc23f1105c1 100755 --- a/t/t5557-http-get.sh +++ b/t/t5557-http-get.sh @@ -2,7 +2,6 @@ test_description='test downloading a file by URL' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh index cd05321e1764b5..3816ed5058d901 100755 --- a/t/t5558-clone-bundle-uri.sh +++ b/t/t5558-clone-bundle-uri.sh @@ -945,7 +945,7 @@ test_expect_success 'creationToken heuristic with failed downloads (clone)' ' --bundle-uri="$HTTPD_URL/bundle-list" \ "$HTTPD_URL/smart/fetch.git" download-3 && - # As long as we have continguous successful downloads, + # As long as we have contiguous successful downloads, # we _do_ set these configs. test_cmp_config -C download-3 "$HTTPD_URL/bundle-list" fetch.bundleuri && test_cmp_config -C download-3 3 fetch.bundlecreationtoken && @@ -1189,7 +1189,7 @@ test_expect_success 'creationToken heuristic with failed downloads (fetch)' ' GIT_TRACE2_EVENT="$(pwd)/trace-fetch-3.txt" \ git -C fetch-3 fetch origin && - # As long as we have continguous successful downloads, + # As long as we have contiguous successful downloads, # we _do_ set the maximum creation token. test_cmp_config -C fetch-3 6 fetch.bundlecreationtoken && diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh index f75068de64851f..d30cf4f5b8398e 100755 --- a/t/t5560-http-backend-noserver.sh +++ b/t/t5560-http-backend-noserver.sh @@ -4,7 +4,6 @@ test_description='test git-http-backend-noserver' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh HTTPD_DOCUMENT_ROOT_PATH="$TRASH_DIRECTORY" diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh index e1d3b8caed0739..9c57d843152dd5 100755 --- a/t/t5561-http-backend.sh +++ b/t/t5561-http-backend.sh @@ -4,7 +4,6 @@ test_description='test git-http-backend' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh index 7ee9858a78b6fb..f3b158274c4cc7 100755 --- a/t/t5562-http-backend-content-length.sh +++ b/t/t5562-http-backend-content-length.sh @@ -2,7 +2,6 @@ test_description='test git-http-backend respects CONTENT_LENGTH' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_lazy_prereq GZIP 'gzip --version' diff --git a/t/t5562/invoke-with-content-length.pl b/t/t5562/invoke-with-content-length.pl index 9babb9a375e5fb..211e29fadeeb1d 100644 --- a/t/t5562/invoke-with-content-length.pl +++ b/t/t5562/invoke-with-content-length.pl @@ -1,4 +1,4 @@ -use 5.008001; +require v5.26; use strict; use warnings; diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh index ba03f6a09fcf3d..317f33af5a7e60 100755 --- a/t/t5563-simple-http-auth.sh +++ b/t/t5563-simple-http-auth.sh @@ -2,7 +2,6 @@ test_description='test http auth header and credential helper interop' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh index 4aef99bc28a46e..b27e481f95bc4d 100755 --- a/t/t5564-http-proxy.sh +++ b/t/t5564-http-proxy.sh @@ -2,7 +2,6 @@ test_description="test fetching through http proxy" -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh index c5f08b67996b0d..8df4001b7221e4 100755 --- a/t/t5570-git-daemon.sh +++ b/t/t5570-git-daemon.sh @@ -4,10 +4,34 @@ test_description='test fetching over git protocol' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-git-daemon.sh + +test_expect_success 'daemon rejects invalid --init-timeout values' ' + for arg in "3a" "-3" + do + test_must_fail git daemon --init-timeout="$arg" 2>err && + test_grep "fatal: invalid init-timeout ${SQ}$arg${SQ}, expecting a non-negative integer" err || + return 1 + done +' + +test_expect_success 'daemon rejects invalid --timeout values' ' + for arg in "3a" "-3" + do + test_must_fail git daemon --timeout="$arg" 2>err && + test_grep "fatal: invalid timeout ${SQ}$arg${SQ}, expecting a non-negative integer" err || + return 1 + done +' + +test_expect_success 'daemon rejects invalid --max-connections values' ' + arg='3a' && + test_must_fail git daemon --max-connections=3a 2>err && + test_grep "fatal: invalid max-connections ${SQ}$arg${SQ}, expecting an integer" err +' + start_git_daemon check_verbose_connect () { diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh index 448134c4bf72bd..a11b20e378223e 100755 --- a/t/t5571-pre-push-hook.sh +++ b/t/t5571-pre-push-hook.sh @@ -4,7 +4,6 @@ test_description='check pre-push hooks' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5572-pull-submodule.sh b/t/t5572-pull-submodule.sh index 916e58c16696ba..f7650e8475e815 100755 --- a/t/t5572-pull-submodule.sh +++ b/t/t5572-pull-submodule.sh @@ -5,7 +5,6 @@ test_description='pull can handle submodules' GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh @@ -230,6 +229,7 @@ test_expect_success 'branch has no merge base with remote-tracking counterpart' test_create_repo a-submodule && test_commit -C a-submodule foo && + test_commit -C a-submodule bar && test_create_repo parent && git -C parent submodule add "$(pwd)/a-submodule" && @@ -246,4 +246,23 @@ test_expect_success 'branch has no merge base with remote-tracking counterpart' git -C child pull --recurse-submodules --rebase ' +test_expect_success 'fetch submodule remote of different name from superproject' ' + git -C child remote rename origin o1 && + git -C child submodule update --init && + + # Needs to create unreachable commit from current master branch. + git -C a-submodule checkout -b newmain HEAD^ && + test_commit -C a-submodule echo && + test_commit -C a-submodule moreecho && + subc=$(git -C a-submodule rev-parse --short HEAD) && + + git -C parent/a-submodule fetch && + git -C parent/a-submodule checkout "$subc" && + git -C parent commit -m "update submodule" a-submodule && + git -C a-submodule reset --hard HEAD^^ && + + git -C child pull --no-recurse-submodules && + git -C child submodule update +' + test_done diff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh index ab05f38a998239..a76b54d7de05cf 100755 --- a/t/t5573-pull-verify-signatures.sh +++ b/t/t5573-pull-verify-signatures.sh @@ -2,7 +2,6 @@ test_description='pull signature verification tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-gpg.sh" diff --git a/t/t5574-fetch-output.sh b/t/t5574-fetch-output.sh index f7707326ea1589..5883839a04e991 100755 --- a/t/t5574-fetch-output.sh +++ b/t/t5574-fetch-output.sh @@ -5,7 +5,6 @@ test_description='git fetch output format' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'fetch with invalid output format configuration' ' diff --git a/t/t5580-unc-paths.sh b/t/t5580-unc-paths.sh index d7537a162b21fe..65ef1a3628ee94 100755 --- a/t/t5580-unc-paths.sh +++ b/t/t5580-unc-paths.sh @@ -4,7 +4,6 @@ test_description='various Windows-only path tests' 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 CYGWIN diff --git a/t/t5581-http-curl-verbose.sh b/t/t5581-http-curl-verbose.sh index 724f61005427b3..cded79c16b5d60 100755 --- a/t/t5581-http-curl-verbose.sh +++ b/t/t5581-http-curl-verbose.sh @@ -4,7 +4,6 @@ test_description='test GIT_CURL_VERBOSE' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5582-fetch-negative-refspec.sh b/t/t5582-fetch-negative-refspec.sh index 7a80e47c2b70a8..ae32f8178a8025 100755 --- a/t/t5582-fetch-negative-refspec.sh +++ b/t/t5582-fetch-negative-refspec.sh @@ -282,4 +282,8 @@ test_expect_success '--prefetch succeeds when refspec becomes empty' ' git -C one fetch --prefetch ' +test_expect_success '--prefetch succeeds with empty command line refspec' ' + git -C one fetch --prefetch origin +refs/tags/extra +' + test_done diff --git a/t/t5583-push-branches.sh b/t/t5583-push-branches.sh index 320f49c753f413..e7e1b6dab66fb3 100755 --- a/t/t5583-push-branches.sh +++ b/t/t5583-push-branches.sh @@ -5,7 +5,6 @@ test_description='check the consisitency of behavior of --all and --branches' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh delete_refs() { diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh index c814afa5656cca..34b3df4027593b 100755 --- a/t/t5600-clone-fail-cleanup.sh +++ b/t/t5600-clone-fail-cleanup.sh @@ -13,7 +13,6 @@ Unless the directory already exists, in which case we clean up only what we wrote. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh corrupt_repo () { diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 5d7ea147f1abc5..d0c18660e33113 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -530,19 +530,30 @@ do ' done +# Parsing of paths that look like IPv6 addresses is broken on Cygwin. +expectation_for_ipv6_tests=success +if test_have_prereq CYGWIN +then + expectation_for_ipv6_tests=failure +fi + #ipv6 for repo in rep rep/home/project 123 do - test_expect_success "clone [::1]:$repo" ' + test_expect_$expectation_for_ipv6_tests "clone [::1]:$repo" ' test_clone_url [::1]:$repo ::1 "$repo" ' done -#home directory -test_expect_success "clone host:/~repo" ' + +# Home directory. All tests that use "~repo" are broken in our CI job when the +# leak sanitizer is enabled. It seems like either a bug in the sanitizer or in +# glibc, but when executing getpwnam(3p) with an invalid username we eventually +# start recursing in a call to free(3p), until bust the stack and segfault. +test_expect_success !SANITIZE_LEAK "clone host:/~repo" ' test_clone_url host:/~repo host "~repo" ' -test_expect_success "clone [::1]:/~repo" ' +test_expect_$expectation_for_ipv6_tests !SANITIZE_LEAK "clone [::1]:/~repo" ' test_clone_url [::1]:/~repo ::1 "~repo" ' @@ -562,9 +573,9 @@ do test_clone_url "ssh://host.xz$tcol/home/user/repo" host.xz /home/user/repo ' # from home directory - test_expect_success "clone ssh://host.xz$tcol/~repo" ' - test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo" -' + test_expect_success !SANITIZE_LEAK "clone ssh://host.xz$tcol/~repo" ' + test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo" + ' done # with port number @@ -573,7 +584,7 @@ test_expect_success 'clone ssh://host.xz:22/home/user/repo' ' ' # from home directory with port number -test_expect_success 'clone ssh://host.xz:22/~repo' ' +test_expect_success !SANITIZE_LEAK 'clone ssh://host.xz:22/~repo' ' test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo" ' @@ -590,8 +601,8 @@ done for tuah in ::1 [::1] user@::1 user@[::1] [user@::1] do euah=$(echo $tuah | tr -d "[]") - test_expect_success "clone ssh://$tuah/~repo" " - test_clone_url ssh://$tuah/~repo $euah '~repo' + test_expect_success !SANITIZE_LEAK "clone ssh://$tuah/~repo" " + test_clone_url ssh://$tuah/~repo $euah '~repo' " done @@ -608,8 +619,8 @@ done for tuah in [::1] user@[::1] [user@::1] do euah=$(echo $tuah | tr -d "[]") - test_expect_success "clone ssh://$tuah:22/~repo" " - test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo' + test_expect_success !SANITIZE_LEAK "clone ssh://$tuah:22/~repo" " + test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo' " done diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh index 56329aa160e752..cbcceab9d56b59 100755 --- a/t/t5602-clone-remote-exec.sh +++ b/t/t5602-clone-remote-exec.sh @@ -2,7 +2,6 @@ test_description=clone -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5603-clone-dirname.sh b/t/t5603-clone-dirname.sh index 8ca1f0942378d2..80eb4e04f8b89a 100755 --- a/t/t5603-clone-dirname.sh +++ b/t/t5603-clone-dirname.sh @@ -2,7 +2,6 @@ test_description='check output directory names used by git-clone' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # we use a fake ssh wrapper that ignores the arguments diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 9b32db8478ab77..470bfb610ce075 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -7,7 +7,6 @@ test_description='test clone --reference' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh base_dir=$(pwd) @@ -131,7 +130,7 @@ test_expect_success 'cloning with multiple references drops duplicates' ' test_expect_success 'clone with reference from a tagged repository' ' ( - cd A && git tag -a -m tagged HEAD + cd A && git tag -a -m tagged foo ) && git clone --reference=A A I ' @@ -156,10 +155,10 @@ test_expect_success 'fetch with incomplete alternates' ' git remote add J "file://$base_dir/J" && GIT_TRACE_PACKET=$U.K git fetch J ) && - main_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/main) && + main_object=$(git -C A rev-parse --verify refs/heads/main) && test -s "$U.K" && ! grep " want $main_object" "$U.K" && - tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) && + tag_object=$(git -C A rev-parse --verify refs/tags/foo) && ! grep " want $tag_object" "$U.K" ' diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh index d9a320abd21657..4605703496e6bf 100755 --- a/t/t5605-clone-local.sh +++ b/t/t5605-clone-local.sh @@ -4,7 +4,6 @@ test_description='test local clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh repo_is_hardlinked() { @@ -154,6 +153,16 @@ test_expect_success 'cloning a local path with --no-local does not hardlink' ' ! repo_is_hardlinked force-nonlocal ' +test_expect_success 'cloning a local path with --no-local from a different user succeeds' ' + git clone --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ + --no-local a nonlocal-otheruser 2>err && + ! repo_is_hardlinked nonlocal-otheruser && + # Verify that this is a git repository. + git -C nonlocal-otheruser rev-parse --show-toplevel && + ! test_grep "detected dubious ownership" err + +' + test_expect_success 'cloning locally respects "-u" for fetching refs' ' test_must_fail git clone --bare -u false a should_not_work.git ' diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh index e93e0d0cc397a3..8a1523773684bc 100755 --- a/t/t5606-clone-options.sh +++ b/t/t5606-clone-options.sh @@ -4,7 +4,6 @@ test_description='basic clone options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index 7ceaa8194d83f4..82e3621ec53edc 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -4,7 +4,6 @@ test_description='some bundle related tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -171,6 +170,13 @@ test_expect_success 'clone bundle with different fsckObjects configurations' ' test_must_fail git -c transfer.fsckObjects=true \ clone bundle-fsck/bad.bundle bundle-transfer-fsck 2>err && + test_grep "missingEmail" err && + + git -c fetch.fsckObjects=true -c fetch.fsck.missingEmail=ignore \ + clone bundle-fsck/bad.bundle bundle-fsck-ignore && + + test_must_fail git -c fetch.fsckObjects=true -c fetch.fsck.missingEmail=error \ + clone bundle-fsck/bad.bundle bundle-fsck-error 2>err && test_grep "missingEmail" err ' diff --git a/t/t5609-clone-branch.sh b/t/t5609-clone-branch.sh index 252e1f7c20f2b8..f86a674a0321e7 100755 --- a/t/t5609-clone-branch.sh +++ b/t/t5609-clone-branch.sh @@ -4,7 +4,6 @@ test_description='clone --branch option' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_HEAD() { diff --git a/t/t5610-clone-detached.sh b/t/t5610-clone-detached.sh index 022ed3d87c3715..a7ec21eda5aabf 100755 --- a/t/t5610-clone-detached.sh +++ b/t/t5610-clone-detached.sh @@ -4,7 +4,6 @@ test_description='test cloning a repository with detached HEAD' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh head_is_detached() { diff --git a/t/t5611-clone-config.sh b/t/t5611-clone-config.sh index 298d4befab84f2..4873089a8c95c7 100755 --- a/t/t5611-clone-config.sh +++ b/t/t5611-clone-config.sh @@ -4,7 +4,6 @@ test_description='tests for git clone -c key=value' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'clone -c sets config in cloned repo' ' diff --git a/t/t5612-clone-refspec.sh b/t/t5612-clone-refspec.sh index 72762de9774caa..3126cfd7e9d6bd 100755 --- a/t/t5612-clone-refspec.sh +++ b/t/t5612-clone-refspec.sh @@ -4,7 +4,6 @@ test_description='test refspec written by clone-command' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5613-info-alternate.sh b/t/t5613-info-alternate.sh index 7708cbafa982ef..c752804a8e90cc 100755 --- a/t/t5613-info-alternate.sh +++ b/t/t5613-info-alternate.sh @@ -5,7 +5,6 @@ test_description='test transitive info/alternate entries' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'preparing first repository' ' diff --git a/t/t5614-clone-submodules-shallow.sh b/t/t5614-clone-submodules-shallow.sh index c2a2bb453eeabc..0c85ef834ab90e 100755 --- a/t/t5614-clone-submodules-shallow.sh +++ b/t/t5614-clone-submodules-shallow.sh @@ -2,7 +2,6 @@ test_description='Test shallow cloning of repos with submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pwd=$(pwd) diff --git a/t/t5615-alternate-env.sh b/t/t5615-alternate-env.sh index 83513e46a3556b..9d6aa2187f2aaa 100755 --- a/t/t5615-alternate-env.sh +++ b/t/t5615-alternate-env.sh @@ -2,7 +2,6 @@ test_description='handling of alternates in environment variables' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_obj () { diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index c53e93be2f7779..4650451964339d 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -5,7 +5,6 @@ test_description='git partial clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # create a normal "src" repo where we can later create new commits. @@ -694,6 +693,36 @@ test_expect_success 'lazy-fetch in submodule succeeds' ' git -C client restore --recurse-submodules --source=HEAD^ :/ ' +test_expect_success 'after fetching descendants of non-promisor commits, gc works' ' + # Setup + git init full && + git -C full config uploadpack.allowfilter 1 && + git -C full config uploadpack.allowanysha1inwant 1 && + touch full/foo && + git -C full add foo && + git -C full commit -m "commit 1" && + git -C full checkout --detach && + + # Partial clone and push commit to remote + git clone "file://$(pwd)/full" --filter=blob:none partial && + echo "hello" > partial/foo && + git -C partial commit -a -m "commit 2" && + git -C partial push && + + # gc in partial repo + git -C partial gc --prune=now && + + # Create another commit in normal repo + git -C full checkout main && + echo " world" >> full/foo && + git -C full commit -a -m "commit 3" && + + # Pull from remote in partial repo, and run gc again + git -C partial pull && + git -C partial gc --prune=now +' + + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5617-clone-submodules-remote.sh b/t/t5617-clone-submodules-remote.sh index 5a4d7936a72aac..688433824934d8 100755 --- a/t/t5617-clone-submodules-remote.sh +++ b/t/t5617-clone-submodules-remote.sh @@ -5,7 +5,6 @@ test_description='Test cloning repos with submodules using remote-tracking branc GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pwd=$(pwd) diff --git a/t/t5618-alternate-refs.sh b/t/t5618-alternate-refs.sh index f905db0a3fdf40..2fb6d549d394ee 100755 --- a/t/t5618-alternate-refs.sh +++ b/t/t5618-alternate-refs.sh @@ -2,7 +2,6 @@ test_description='test handling of --alternate-refs traversal' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Avoid test_commit because we want a specific and known set of refs: diff --git a/t/t5620-backfill.sh b/t/t5620-backfill.sh new file mode 100755 index 00000000000000..58c81556e72c89 --- /dev/null +++ b/t/t5620-backfill.sh @@ -0,0 +1,211 @@ +#!/bin/sh + +test_description='git backfill on partial clones' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +# We create objects in the 'src' repo. +test_expect_success 'setup repo for object creation' ' + echo "{print \$1}" >print_1.awk && + echo "{print \$2}" >print_2.awk && + + git init src && + + mkdir -p src/a/b/c && + mkdir -p src/d/e && + + for i in 1 2 + do + for n in 1 2 3 4 + do + echo "Version $i of file $n" > src/file.$n.txt && + echo "Version $i of file a/$n" > src/a/file.$n.txt && + echo "Version $i of file a/b/$n" > src/a/b/file.$n.txt && + echo "Version $i of file a/b/c/$n" > src/a/b/c/file.$n.txt && + echo "Version $i of file d/$n" > src/d/file.$n.txt && + echo "Version $i of file d/e/$n" > src/d/e/file.$n.txt && + git -C src add . && + git -C src commit -m "Iteration $n" || return 1 + done + done +' + +# Clone 'src' into 'srv.bare' so we have a bare repo to be our origin +# server for the partial clone. +test_expect_success 'setup bare clone for server' ' + git clone --bare "file://$(pwd)/src" srv.bare && + git -C srv.bare config --local uploadpack.allowfilter 1 && + git -C srv.bare config --local uploadpack.allowanysha1inwant 1 +' + +# do basic partial clone from "srv.bare" +test_expect_success 'do partial clone 1, backfill gets all objects' ' + git clone --no-checkout --filter=blob:none \ + --single-branch --branch=main \ + "file://$(pwd)/srv.bare" backfill1 && + + # Backfill with no options gets everything reachable from HEAD. + GIT_TRACE2_EVENT="$(pwd)/backfill-file-trace" git \ + -C backfill1 backfill && + + # We should have engaged the partial clone machinery + test_trace2_data promisor fetch_count 48 <backfill-file-trace && + + # No more missing objects! + git -C backfill1 rev-list --quiet --objects --missing=print HEAD >revs2 && + test_line_count = 0 revs2 +' + +test_expect_success 'do partial clone 2, backfill min batch size' ' + git clone --no-checkout --filter=blob:none \ + --single-branch --branch=main \ + "file://$(pwd)/srv.bare" backfill2 && + + GIT_TRACE2_EVENT="$(pwd)/batch-trace" git \ + -C backfill2 backfill --min-batch-size=20 && + + # Batches were used + test_trace2_data promisor fetch_count 20 <batch-trace >matches && + test_line_count = 2 matches && + test_trace2_data promisor fetch_count 8 <batch-trace && + + # No more missing objects! + git -C backfill2 rev-list --quiet --objects --missing=print HEAD >revs2 && + test_line_count = 0 revs2 +' + +test_expect_success 'backfill --sparse without sparse-checkout fails' ' + git init not-sparse && + test_must_fail git -C not-sparse backfill --sparse 2>err && + grep "problem loading sparse-checkout" err +' + +test_expect_success 'backfill --sparse' ' + git clone --sparse --filter=blob:none \ + --single-branch --branch=main \ + "file://$(pwd)/srv.bare" backfill3 && + + # Initial checkout includes four files at root. + git -C backfill3 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 44 missing && + + # Initial sparse-checkout is just the files at root, so we get the + # older versions of the four files at tip. + GIT_TRACE2_EVENT="$(pwd)/sparse-trace1" git \ + -C backfill3 backfill --sparse && + test_trace2_data promisor fetch_count 4 <sparse-trace1 && + test_trace2_data path-walk paths 5 <sparse-trace1 && + git -C backfill3 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 40 missing && + + # Expand the sparse-checkout to include 'd' recursively. This + # engages the algorithm to skip the trees for 'a'. Note that + # the "sparse-checkout set" command downloads the objects at tip + # to satisfy the current checkout. + git -C backfill3 sparse-checkout set d && + GIT_TRACE2_EVENT="$(pwd)/sparse-trace2" git \ + -C backfill3 backfill --sparse && + test_trace2_data promisor fetch_count 8 <sparse-trace2 && + test_trace2_data path-walk paths 15 <sparse-trace2 && + git -C backfill3 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 24 missing && + + # Disabling the --sparse option (on by default) will download everything + git -C backfill3 backfill --no-sparse && + git -C backfill3 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 0 missing +' + +test_expect_success 'backfill --sparse without cone mode (positive)' ' + git clone --no-checkout --filter=blob:none \ + --single-branch --branch=main \ + "file://$(pwd)/srv.bare" backfill4 && + + # No blobs yet + git -C backfill4 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 48 missing && + + # Define sparse-checkout by filename regardless of parent directory. + # This downloads 6 blobs to satisfy the checkout. + git -C backfill4 sparse-checkout set --no-cone "**/file.1.txt" && + git -C backfill4 checkout main && + + # Track new blob count + git -C backfill4 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 42 missing && + + GIT_TRACE2_EVENT="$(pwd)/no-cone-trace1" git \ + -C backfill4 backfill --sparse && + test_trace2_data promisor fetch_count 6 <no-cone-trace1 && + + # This walk needed to visit all directories to search for these paths. + test_trace2_data path-walk paths 12 <no-cone-trace1 && + git -C backfill4 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 36 missing +' + +test_expect_success 'backfill --sparse without cone mode (negative)' ' + git clone --no-checkout --filter=blob:none \ + --single-branch --branch=main \ + "file://$(pwd)/srv.bare" backfill5 && + + # No blobs yet + git -C backfill5 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 48 missing && + + # Define sparse-checkout by filename regardless of parent directory. + # This downloads 18 blobs to satisfy the checkout + git -C backfill5 sparse-checkout set --no-cone "**/file*" "!**/file.1.txt" && + git -C backfill5 checkout main && + + # Track new blob count + git -C backfill5 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 30 missing && + + GIT_TRACE2_EVENT="$(pwd)/no-cone-trace2" git \ + -C backfill5 backfill --sparse && + test_trace2_data promisor fetch_count 18 <no-cone-trace2 && + + # This walk needed to visit all directories to search for these paths, plus + # 12 extra "file.?.txt" paths than the previous test. + test_trace2_data path-walk paths 24 <no-cone-trace2 && + git -C backfill5 rev-list --quiet --objects --missing=print HEAD >missing && + test_line_count = 12 missing +' + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success 'create a partial clone over HTTP' ' + SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && + rm -rf "$SERVER" repo && + git clone --bare "file://$(pwd)/src" "$SERVER" && + test_config -C "$SERVER" uploadpack.allowfilter 1 && + test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 && + + git clone --no-checkout --filter=blob:none \ + "$HTTPD_URL/smart/server" backfill-http +' + +test_expect_success 'backfilling over HTTP succeeds' ' + GIT_TRACE2_EVENT="$(pwd)/backfill-http-trace" git \ + -C backfill-http backfill && + + # We should have engaged the partial clone machinery + test_trace2_data promisor fetch_count 48 <backfill-http-trace && + + # Confirm all objects are present, none missing. + git -C backfill-http rev-list --objects --all >rev-list-out && + awk "{print \$1;}" <rev-list-out >oids && + GIT_TRACE2_EVENT="$(pwd)/walk-trace" git -C backfill-http \ + cat-file --batch-check <oids >batch-out && + ! grep missing batch-out +' + +# DO NOT add non-httpd-specific tests here, because the last part of this +# test script is only executed when httpd is available and enabled. + +test_done diff --git a/t/t5621-clone-revision.sh b/t/t5621-clone-revision.sh new file mode 100755 index 00000000000000..db3b8cff558f0b --- /dev/null +++ b/t/t5621-clone-revision.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +test_description='tests for git clone --revision' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit --no-tag "initial commit" README "Hello" && + test_commit --annotate "second commit" README "Hello world" v1.0 && + test_commit --no-tag "third commit" README "Hello world!" && + git switch -c feature v1.0 && + test_commit --no-tag "feature commit" README "Hello world!" && + git switch main +' + +test_expect_success 'clone with --revision being a branch' ' + test_when_finished "rm -rf dst" && + git clone --revision=refs/heads/feature . dst && + git rev-parse refs/heads/feature >expect && + git -C dst rev-parse HEAD >actual && + test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null && + test_cmp expect actual && + git -C dst for-each-ref refs >expect && + test_must_be_empty expect && + test_must_fail git -C dst config remote.origin.fetch +' + +test_expect_success 'clone with --depth and --revision being a branch' ' + test_when_finished "rm -rf dst" && + git clone --no-local --depth=1 --revision=refs/heads/feature . dst && + git rev-parse refs/heads/feature >expect && + git -C dst rev-parse HEAD >actual && + test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null && + test_cmp expect actual && + git -C dst for-each-ref refs >expect && + test_must_be_empty expect && + test_must_fail git -C dst config remote.origin.fetch && + git -C dst rev-list HEAD >actual && + test_line_count = 1 actual +' + +test_expect_success 'clone with --revision being a tag' ' + test_when_finished "rm -rf dst" && + git clone --revision=refs/tags/v1.0 . dst && + git rev-parse refs/tags/v1.0^{} >expect && + git -C dst rev-parse HEAD >actual && + test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null && + test_cmp expect actual && + git -C dst for-each-ref refs >expect && + test_must_be_empty expect && + test_must_fail git -C dst config remote.origin.fetch +' + +test_expect_success 'clone with --revision being HEAD' ' + test_when_finished "rm -rf dst" && + git clone --revision=HEAD . dst && + git rev-parse HEAD >expect && + git -C dst rev-parse HEAD >actual && + test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null && + test_cmp expect actual && + git -C dst for-each-ref refs >expect && + test_must_be_empty expect && + test_must_fail git -C dst config remote.origin.fetch +' + +test_expect_success 'clone with --revision being a raw commit hash' ' + test_when_finished "rm -rf dst" && + oid=$(git rev-parse refs/heads/feature) && + git clone --revision=$oid . dst && + echo $oid >expect && + git -C dst rev-parse HEAD >actual && + test_must_fail git -C dst symbolic-ref -q HEAD >/dev/null && + test_cmp expect actual && + git -C dst for-each-ref refs >expect && + test_must_be_empty expect && + test_must_fail git -C dst config remote.origin.fetch +' + +test_expect_success 'clone with --revision and --bare' ' + test_when_finished "rm -rf dst" && + git clone --revision=refs/heads/main --bare . dst && + oid=$(git rev-parse refs/heads/main) && + git -C dst cat-file -t $oid >actual && + echo "commit" >expect && + test_cmp expect actual && + git -C dst for-each-ref refs >expect && + test_must_be_empty expect && + test_must_fail git -C dst config remote.origin.fetch +' + +test_expect_success 'clone with --revision being a short raw commit hash' ' + test_when_finished "rm -rf dst" && + oid=$(git rev-parse --short refs/heads/feature) && + test_must_fail git clone --revision=$oid . dst 2>err && + test_grep "fatal: Remote revision $oid not found in upstream origin" err +' + +test_expect_success 'clone with --revision being a tree hash' ' + test_when_finished "rm -rf dst" && + oid=$(git rev-parse refs/heads/feature^{tree}) && + test_must_fail git clone --revision=$oid . dst 2>err && + test_grep "error: object $oid is a tree, not a commit" err +' + +test_expect_success 'clone with --revision being the parent of a ref fails' ' + test_when_finished "rm -rf dst" && + test_must_fail git clone --revision=refs/heads/main^ . dst +' + +test_expect_success 'clone with --revision and --branch fails' ' + test_when_finished "rm -rf dst" && + test_must_fail git clone --revision=refs/heads/main --branch=main . dst +' + +test_expect_success 'clone with --revision and --mirror fails' ' + test_when_finished "rm -rf dst" && + test_must_fail git clone --revision=refs/heads/main --mirror . dst +' + +test_done diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh index c48830de8fe204..678a346ed06780 100755 --- a/t/t5701-git-serve.sh +++ b/t/t5701-git-serve.sh @@ -5,27 +5,42 @@ test_description='test protocol v2 server commands' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -test_expect_success 'test capability advertisement' ' +test_expect_success 'setup to generate files with expected content' ' + printf "agent=git/%s" "$(git version | cut -d" " -f3)" >agent_capability && + test_oid_cache <<-EOF && wrong_algo sha1:sha256 wrong_algo sha256:sha1 EOF + + if test_have_prereq WINDOWS + then + printf "agent=FAKE\n" >agent_capability + else + printf -- "-%s\n" $(uname -s | test_redact_non_printables) >>agent_capability + fi && cat >expect.base <<-EOF && version 2 - agent=git/$(git version | cut -d" " -f3) + $(cat agent_capability) ls-refs=unborn fetch=shallow wait-for-done server-option object-format=$(test_oid algo) EOF - cat >expect.trailer <<-EOF && + cat >expect.trailer <<-EOF 0000 EOF +' + +test_expect_success 'test capability advertisement' ' cat expect.base expect.trailer >expect && + if test_have_prereq WINDOWS + then + GIT_USER_AGENT=FAKE && export GIT_USER_AGENT + fi && GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \ --advertise-capabilities >out && test-tool pkt-line unpack <out >actual && @@ -356,6 +371,10 @@ test_expect_success 'test capability advertisement with uploadpack.advertiseBund expect.extra \ expect.trailer >expect && + if test_have_prereq WINDOWS + then + GIT_USER_AGENT=FAKE && export GIT_USER_AGENT + fi && GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \ --advertise-capabilities >out && test-tool pkt-line unpack <out >actual && diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 1ef540f73d3475..d3df81e7852d7d 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -185,6 +185,43 @@ test_expect_success 'server-options are sent when using ls-remote' ' grep "server-option=world" log ' +test_expect_success 'server-options from configuration are used by ls-remote' ' + test_when_finished "rm -rf log myclone" && + git clone "file://$(pwd)/file_parent" myclone && + cat >expect <<-EOF && + $(git -C file_parent rev-parse refs/heads/main)$(printf "\t")refs/heads/main + EOF + + # Default server options from configuration are used + git -C myclone config --add remote.origin.serverOption foo && + git -C myclone config --add remote.origin.serverOption bar && + GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ + ls-remote origin main >actual && + test_cmp expect actual && + test_grep "ls-remote> server-option=foo" log && + test_grep "ls-remote> server-option=bar" log && + rm -f log && + + # Empty value of remote.<name>.serverOption clears the list + git -C myclone config --add remote.origin.serverOption "" && + git -C myclone config --add remote.origin.serverOption tar && + GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ + ls-remote origin main >actual && + test_cmp expect actual && + test_grep "ls-remote> server-option=tar" log && + test_grep ! "ls-remote> server-option=foo" log && + test_grep ! "ls-remote> server-option=bar" log && + rm -f log && + + # Server option from command line overrides those from configuration + GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ + ls-remote -o hello -o world origin main >actual && + test_cmp expect actual && + test_grep "ls-remote> server-option=hello" log && + test_grep "ls-remote> server-option=world" log && + test_grep ! "ls-remote> server-option=tar" log +' + test_expect_success 'warn if using server-option with ls-remote with legacy protocol' ' test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \ ls-remote -o hello -o world "file://$(pwd)/file_parent" main 2>err && @@ -381,6 +418,54 @@ test_expect_success 'server-options are sent when fetching' ' grep "server-option=world" log ' +test_expect_success 'server-options are sent when fetch multiple remotes' ' + test_when_finished "rm -f log server_options_sent" && + git clone "file://$(pwd)/file_parent" child_multi_remotes && + git -C child_multi_remotes remote add another "file://$(pwd)/file_parent" && + GIT_TRACE_PACKET="$(pwd)/log" git -C child_multi_remotes -c protocol.version=2 \ + fetch -o hello --all && + grep "fetch> server-option=hello" log >server_options_sent && + test_line_count = 2 server_options_sent +' + +test_expect_success 'server-options from configuration are used by git-fetch' ' + test_when_finished "rm -rf log myclone" && + git clone "file://$(pwd)/file_parent" myclone && + git -C file_parent log -1 --format=%s >expect && + + # Default server options from configuration are used + git -C myclone config --add remote.origin.serverOption foo && + git -C myclone config --add remote.origin.serverOption bar && + GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ + fetch origin main && + git -C myclone log -1 --format=%s origin/main >actual && + test_cmp expect actual && + test_grep "fetch> server-option=foo" log && + test_grep "fetch> server-option=bar" log && + rm -f log && + + # Empty value of remote.<name>.serverOption clears the list + git -C myclone config --add remote.origin.serverOption "" && + git -C myclone config --add remote.origin.serverOption tar && + GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ + fetch origin main && + git -C myclone log -1 --format=%s origin/main >actual && + test_cmp expect actual && + test_grep "fetch> server-option=tar" log && + test_grep ! "fetch> server-option=foo" log && + test_grep ! "fetch> server-option=bar" log && + rm -f log && + + # Server option from command line overrides those from configuration + GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \ + fetch -o hello -o world origin main && + git -C myclone log -1 --format=%s origin/main >actual && + test_cmp expect actual && + test_grep "fetch> server-option=hello" log && + test_grep "fetch> server-option=world" log && + test_grep ! "fetch> server-option=tar" log +' + test_expect_success 'warn if using server-option with fetch with legacy protocol' ' test_when_finished "rm -rf temp_child" && @@ -404,6 +489,37 @@ test_expect_success 'server-options are sent when cloning' ' grep "server-option=world" log ' +test_expect_success 'server-options from configuration are used by git-clone' ' + test_when_finished "rm -rf log myclone" && + + # Default server options from configuration are used + GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ + -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \ + clone "file://$(pwd)/file_parent" myclone && + test_grep "clone> server-option=foo" log && + test_grep "clone> server-option=bar" log && + rm -rf log myclone && + + # Empty value of remote.<name>.serverOption clears the list + GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ + -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \ + -c remote.origin.serverOption= -c remote.origin.serverOption=tar \ + clone "file://$(pwd)/file_parent" myclone && + test_grep "clone> server-option=tar" log && + test_grep ! "clone> server-option=foo" log && + test_grep ! "clone> server-option=bar" log && + rm -rf log myclone && + + # Server option from command line overrides those from configuration + GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ + -c remote.origin.serverOption=tar \ + clone --server-option=hello --server-option=world \ + "file://$(pwd)/file_parent" myclone && + test_grep "clone> server-option=hello" log && + test_grep "clone> server-option=world" log && + test_grep ! "clone> server-option=tar" log +' + test_expect_success 'warn if using server-option with clone with legacy protocol' ' test_when_finished "rm -rf myclone" && @@ -415,6 +531,23 @@ test_expect_success 'warn if using server-option with clone with legacy protocol test_grep "server options require protocol version 2 or later" err ' +test_expect_success 'server-option configuration with legacy protocol is ok' ' + test_when_finished "rm -rf myclone" && + + env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \ + -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \ + clone "file://$(pwd)/file_parent" myclone +' + +test_expect_success 'invalid server-option configuration' ' + test_when_finished "rm -rf myclone" && + + test_must_fail git -c protocol.version=2 \ + -c remote.origin.serverOption \ + clone "file://$(pwd)/file_parent" myclone 2>err && + test_grep "error: missing value for '\''remote.origin.serveroption'\''" err +' + test_expect_success 'upload-pack respects config using protocol v2' ' git init server && write_script server/.git/hook <<-\EOF && diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index f75fae52c83d8b..191097171bcbd4 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -2,7 +2,6 @@ test_description='upload-pack ref-in-want' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh get_actual_refs () { diff --git a/t/t5704-protocol-violations.sh b/t/t5704-protocol-violations.sh index 11be64fc038113..2b33fced23ff8f 100755 --- a/t/t5704-protocol-violations.sh +++ b/t/t5704-protocol-violations.sh @@ -5,7 +5,6 @@ of these cases it will generally be acceptable for one side to break off communications if the other side says something unexpected. We are mostly making sure that we do not segfault or otherwise behave badly.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'extra delim packet in v2 ls-refs args' ' diff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh index b8a722ec27e73a..ed38c76c29059d 100755 --- a/t/t5705-session-id-in-capabilities.sh +++ b/t/t5705-session-id-in-capabilities.sh @@ -2,7 +2,6 @@ test_description='session ID in capabilities' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh REPO="$(pwd)/repo" diff --git a/t/t5710-promisor-remote-capability.sh b/t/t5710-promisor-remote-capability.sh new file mode 100755 index 00000000000000..d2cc69a17e4668 --- /dev/null +++ b/t/t5710-promisor-remote-capability.sh @@ -0,0 +1,312 @@ +#!/bin/sh + +test_description='handling of promisor remote advertisement' + +. ./test-lib.sh + +GIT_TEST_MULTI_PACK_INDEX=0 +GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL=0 + +# Setup the repository with three commits, this way HEAD is always +# available and we can hide commit 1 or 2. +test_expect_success 'setup: create "template" repository' ' + git init template && + test_commit -C template 1 && + test_commit -C template 2 && + test_commit -C template 3 && + test-tool genrandom foo 10240 >template/foo && + git -C template add foo && + git -C template commit -m foo +' + +# A bare repo will act as a server repo with unpacked objects. +test_expect_success 'setup: create bare "server" repository' ' + git clone --bare --no-local template server && + mv server/objects/pack/pack-* . && + packfile=$(ls pack-*.pack) && + git -C server unpack-objects --strict <"$packfile" +' + +check_missing_objects () { + git -C "$1" rev-list --objects --all --missing=print > all.txt && + perl -ne 'print if s/^[?]//' all.txt >missing.txt && + test_line_count = "$2" missing.txt && + if test "$2" -lt 2 + then + test "$3" = "$(cat missing.txt)" + else + test -f "$3" && + sort <"$3" >expected_sorted && + sort <missing.txt >actual_sorted && + test_cmp expected_sorted actual_sorted + fi +} + +initialize_server () { + count="$1" + missing_oids="$2" + + # Repack everything first + git -C server -c repack.writebitmaps=false repack -a -d && + + # Remove promisor file in case they exist, useful when reinitializing + rm -rf server/objects/pack/*.promisor && + + # Repack without the largest object and create a promisor pack on server + git -C server -c repack.writebitmaps=false repack -a -d \ + --filter=blob:limit=5k --filter-to="$(pwd)/pack" && + promisor_file=$(ls server/objects/pack/*.pack | sed "s/\.pack/.promisor/") && + >"$promisor_file" && + + # Check objects missing on the server + check_missing_objects server "$count" "$missing_oids" +} + +copy_to_lop () { + oid_path="$(test_oid_to_path $1)" && + path="server/objects/$oid_path" && + path2="lop/objects/$oid_path" && + mkdir -p $(dirname "$path2") && + cp "$path" "$path2" +} + +test_expect_success "setup for testing promisor remote advertisement" ' + # Create another bare repo called "lop" (for Large Object Promisor) + git init --bare lop && + + # Copy the largest object from server to lop + obj="HEAD:foo" && + oid="$(git -C server rev-parse $obj)" && + copy_to_lop "$oid" && + + initialize_server 1 "$oid" && + + # Configure lop as promisor remote for server + git -C server remote add lop "file://$(pwd)/lop" && + git -C server config remote.lop.promisor true && + + git -C lop config uploadpack.allowFilter true && + git -C lop config uploadpack.allowAnySHA1InWant true && + git -C server config uploadpack.allowFilter true && + git -C server config uploadpack.allowAnySHA1InWant true +' + +test_expect_success "clone with promisor.advertise set to 'true'" ' + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=All \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is still missing on the server + check_missing_objects server 1 "$oid" +' + +test_expect_success "clone with promisor.advertise set to 'false'" ' + git -C server config promisor.advertise false && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=All \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is not missing on the server + check_missing_objects server 0 "" && + + # Reinitialize server so that the largest object is missing again + initialize_server 1 "$oid" +' + +test_expect_success "clone with promisor.acceptfromserver set to 'None'" ' + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=None \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is not missing on the server + check_missing_objects server 0 "" && + + # Reinitialize server so that the largest object is missing again + initialize_server 1 "$oid" +' + +test_expect_success "init + fetch with promisor.advertise set to 'true'" ' + git -C server config promisor.advertise true && + + test_when_finished "rm -rf client" && + mkdir client && + git -C client init && + git -C client config remote.lop.promisor true && + git -C client config remote.lop.fetch "+refs/heads/*:refs/remotes/lop/*" && + git -C client config remote.lop.url "file://$(pwd)/lop" && + git -C client config remote.server.url "file://$(pwd)/server" && + git -C client config remote.server.fetch "+refs/heads/*:refs/remotes/server/*" && + git -C client config promisor.acceptfromserver All && + GIT_NO_LAZY_FETCH=0 git -C client fetch --filter="blob:limit=5k" server && + + # Check that the largest object is still missing on the server + check_missing_objects server 1 "$oid" +' + +test_expect_success "clone with promisor.acceptfromserver set to 'KnownName'" ' + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=KnownName \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is still missing on the server + check_missing_objects server 1 "$oid" +' + +test_expect_success "clone with 'KnownName' and different remote names" ' + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.serverTwo.promisor=true \ + -c remote.serverTwo.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.serverTwo.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=KnownName \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is not missing on the server + check_missing_objects server 0 "" && + + # Reinitialize server so that the largest object is missing again + initialize_server 1 "$oid" +' + +test_expect_success "clone with promisor.acceptfromserver set to 'KnownUrl'" ' + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=KnownUrl \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is still missing on the server + check_missing_objects server 1 "$oid" +' + +test_expect_success "clone with 'KnownUrl' and different remote urls" ' + ln -s lop serverTwo && + + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/serverTwo" \ + -c promisor.acceptfromserver=KnownUrl \ + --no-local --filter="blob:limit=5k" server client && + test_when_finished "rm -rf client" && + + # Check that the largest object is not missing on the server + check_missing_objects server 0 "" && + + # Reinitialize server so that the largest object is missing again + initialize_server 1 "$oid" +' + +test_expect_success "clone with promisor.advertise set to 'true' but don't delete the client" ' + git -C server config promisor.advertise true && + + # Clone from server to create a client + GIT_NO_LAZY_FETCH=0 git clone -c remote.lop.promisor=true \ + -c remote.lop.fetch="+refs/heads/*:refs/remotes/lop/*" \ + -c remote.lop.url="file://$(pwd)/lop" \ + -c promisor.acceptfromserver=All \ + --no-local --filter="blob:limit=5k" server client && + + # Check that the largest object is still missing on the server + check_missing_objects server 1 "$oid" +' + +test_expect_success "setup for subsequent fetches" ' + # Generate new commit with large blob + test-tool genrandom bar 10240 >template/bar && + git -C template add bar && + git -C template commit -m bar && + + # Fetch new commit with large blob + git -C server fetch origin && + git -C server update-ref HEAD FETCH_HEAD && + git -C server rev-parse HEAD >expected_head && + + # Repack everything twice and remove .promisor files before + # each repack. This makes sure everything gets repacked + # into a single packfile. The second repack is necessary + # because the first one fetches from lop and creates a new + # packfile and its associated .promisor file. + + rm -f server/objects/pack/*.promisor && + git -C server -c repack.writebitmaps=false repack -a -d && + rm -f server/objects/pack/*.promisor && + git -C server -c repack.writebitmaps=false repack -a -d && + + # Unpack everything + rm pack-* && + mv server/objects/pack/pack-* . && + packfile=$(ls pack-*.pack) && + git -C server unpack-objects --strict <"$packfile" && + + # Copy new large object to lop + obj_bar="HEAD:bar" && + oid_bar="$(git -C server rev-parse $obj_bar)" && + copy_to_lop "$oid_bar" && + + # Reinitialize server so that the 2 largest objects are missing + printf "%s\n" "$oid" "$oid_bar" >expected_missing.txt && + initialize_server 2 expected_missing.txt && + + # Create one more client + cp -r client client2 +' + +test_expect_success "subsequent fetch from a client when promisor.advertise is true" ' + git -C server config promisor.advertise true && + + GIT_NO_LAZY_FETCH=0 git -C client pull origin && + + git -C client rev-parse HEAD >actual && + test_cmp expected_head actual && + + cat client/bar >/dev/null && + + check_missing_objects server 2 expected_missing.txt +' + +test_expect_success "subsequent fetch from a client when promisor.advertise is false" ' + git -C server config promisor.advertise false && + + GIT_NO_LAZY_FETCH=0 git -C client2 pull origin && + + git -C client2 rev-parse HEAD >actual && + test_cmp expected_head actual && + + cat client2/bar >/dev/null && + + check_missing_objects server 1 "$oid" +' + +test_done diff --git a/t/t5750-bundle-uri-parse.sh b/t/t5750-bundle-uri-parse.sh index 81bdf58b944434..80a3f83ffb7e60 100755 --- a/t/t5750-bundle-uri-parse.sh +++ b/t/t5750-bundle-uri-parse.sh @@ -3,7 +3,6 @@ test_description="Test bundle-uri bundle_uri_parse_line()" TEST_NO_CREATE_REPO=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'bundle_uri_parse_line() just URIs' ' diff --git a/t/t5802-connect-helper.sh b/t/t5802-connect-helper.sh index dd3e6235cd2a44..a7be375bceb8d3 100755 --- a/t/t5802-connect-helper.sh +++ b/t/t5802-connect-helper.sh @@ -2,7 +2,6 @@ test_description='ext::cmd remote "connect" helper' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5810-proto-disable-local.sh b/t/t5810-proto-disable-local.sh index 862610256fb082..96a2c46e7a6bd5 100755 --- a/t/t5810-proto-disable-local.sh +++ b/t/t5810-proto-disable-local.sh @@ -2,7 +2,6 @@ test_description='test disabling of local paths in clone/fetch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-proto-disable.sh" diff --git a/t/t5811-proto-disable-git.sh b/t/t5811-proto-disable-git.sh index ed773e7432694b..b0061e6a373f4d 100755 --- a/t/t5811-proto-disable-git.sh +++ b/t/t5811-proto-disable-git.sh @@ -2,7 +2,6 @@ test_description='test disabling of git-over-tcp in clone/fetch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-proto-disable.sh" . "$TEST_DIRECTORY/lib-git-daemon.sh" diff --git a/t/t5812-proto-disable-http.sh b/t/t5812-proto-disable-http.sh index f69959c64ca708..96187efaa82ac6 100755 --- a/t/t5812-proto-disable-http.sh +++ b/t/t5812-proto-disable-http.sh @@ -2,7 +2,6 @@ test_description='test disabling of git-over-http in clone/fetch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-proto-disable.sh" . "$TEST_DIRECTORY/lib-httpd.sh" diff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh index 2e975dc70ec2c8..045e2fe6ce376a 100755 --- a/t/t5813-proto-disable-ssh.sh +++ b/t/t5813-proto-disable-ssh.sh @@ -2,7 +2,6 @@ test_description='test disabling of git-over-ssh in clone/fetch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-proto-disable.sh" diff --git a/t/t5814-proto-disable-ext.sh b/t/t5814-proto-disable-ext.sh index 6fe1a98b2a14f8..9587a842bc2408 100755 --- a/t/t5814-proto-disable-ext.sh +++ b/t/t5814-proto-disable-ext.sh @@ -2,7 +2,6 @@ test_description='test disabling of remote-helper paths in clone/fetch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-proto-disable.sh" diff --git a/t/t5815-submodule-protos.sh b/t/t5815-submodule-protos.sh index fe899ee82d74a2..081a07cbae13dd 100755 --- a/t/t5815-submodule-protos.sh +++ b/t/t5815-submodule-protos.sh @@ -2,7 +2,6 @@ test_description='test protocol filtering with submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-proto-disable.sh diff --git a/t/t5900-repo-selection.sh b/t/t5900-repo-selection.sh index a84faac242d040..923fc90f877bd0 100755 --- a/t/t5900-repo-selection.sh +++ b/t/t5900-repo-selection.sh @@ -2,7 +2,6 @@ test_description='selecting remote repo in ambiguous cases' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh reset() { diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index f6d17ee9025100..6289a2e8b03890 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -5,7 +5,6 @@ test_description='miscellaneous rev-list tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh index 3553bbbfe73bd0..73a2465aa0eca6 100755 --- a/t/t6001-rev-list-graft.sh +++ b/t/t6001-rev-list-graft.sh @@ -5,7 +5,6 @@ test_description='Revision traversal vs grafts and path limiter' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index 162cf50778d619..daa009c9a1b4b6 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -4,7 +4,6 @@ # test_description='Tests git rev-list --bisect functionality' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions @@ -309,4 +308,9 @@ test_expect_success '--bisect-all --first-parent' ' test_cmp expect actual ' +test_expect_success '--bisect without any revisions' ' + git rev-list --bisect HEAD..HEAD >out && + test_must_be_empty out +' + test_done diff --git a/t/t6003-rev-list-topo-order.sh b/t/t6003-rev-list-topo-order.sh index 5cf2cee74dbcf3..0d7055d46d4690 100755 --- a/t/t6003-rev-list-topo-order.sh +++ b/t/t6003-rev-list-topo-order.sh @@ -5,7 +5,6 @@ test_description='Tests git rev-list --topo-order functionality' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh index ee0306aeec0b6e..6cde997e13cbab 100755 --- a/t/t6005-rev-list-count.sh +++ b/t/t6005-rev-list-count.sh @@ -2,7 +2,6 @@ test_description='git rev-list --max-count and --skip test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index f1623b1c06d0fa..eb93d68d7dc319 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -8,26 +8,45 @@ test_description='git rev-list --pretty=format test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh test_tick -# Tested non-UTF-8 encoding -test_encoding="ISO8859-1" - -# String "added" in German -# (translated with Google Translate), -# encoded in UTF-8, used as a commit log message below. -added_utf8_part=$(printf "\303\274") -added_utf8_part_iso88591=$(echo "$added_utf8_part" | iconv -f utf-8 -t $test_encoding) -added=$(printf "added (hinzugef${added_utf8_part}gt) foo") -added_iso88591=$(echo "$added" | iconv -f utf-8 -t $test_encoding) -# same but "changed" -changed_utf8_part=$(printf "\303\244") -changed_utf8_part_iso88591=$(echo "$changed_utf8_part" | iconv -f utf-8 -t $test_encoding) -changed=$(printf "changed (ge${changed_utf8_part}ndert) foo") -changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding) + +if test_have_prereq ICONV +then + # Tested non-UTF-8 encoding + test_encoding="ISO8859-1" + + # String "added" in German + # (translated with Google Translate), + # encoded in UTF-8, used as a commit log message below. + added_utf8_part=$(printf "\303\274") + added_utf8_part_iso88591=$(echo "$added_utf8_part" | iconv -f utf-8 -t $test_encoding) + added=$(printf "added (hinzugef${added_utf8_part}gt) foo") + added_iso88591=$(echo "$added" | iconv -f utf-8 -t $test_encoding) + # same but "changed" + changed_utf8_part=$(printf "\303\244") + changed_utf8_part_iso88591=$(echo "$changed_utf8_part" | iconv -f utf-8 -t $test_encoding) + changed=$(printf "changed (ge${changed_utf8_part}ndert) foo") + changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding) +else + # Tested non-UTF-8 encoding + test_encoding="UTF-8" + + # String "added" in German + # (translated with Google Translate), + # encoded in UTF-8, used as a commit log message below. + added_utf8_part="u" + added_utf8_part_iso88591="u" + added=$(printf "added (hinzugef${added_utf8_part}gt) foo") + added_iso88591="$added" + # same but "changed" + changed_utf8_part="a" + changed_utf8_part_iso88591="a" + changed=$(printf "changed (ge${changed_utf8_part}ndert) foo") + changed_iso88591="$changed" +fi # Count of char to truncate # Number is chosen so, that non-ACSII characters @@ -55,7 +74,7 @@ test_expect_success 'setup' ' git config --unset i18n.commitEncoding ' -# usage: test_format [argument...] name format_string [failure] <expected_output +# usage: test_format [argument...] name format_string [success|failure] [prereq] <expected_output test_format () { local args= while true @@ -69,7 +88,7 @@ test_format () { esac done cat >expect.$1 - test_expect_${3:-success} "format $1" " + test_expect_${3:-success} $4 "format $1" " git rev-list $args --pretty=format:'$2' main >output.$1 && test_cmp expect.$1 output.$1 " @@ -198,7 +217,7 @@ Thu, 7 Apr 2005 15:13:13 -0700 1112911993 EOF -test_format encoding %e <<EOF +test_format encoding %e success ICONV <<EOF commit $head2 $test_encoding commit $head1 @@ -374,7 +393,7 @@ test_expect_success 'setup complex body' ' head3_short=$(git rev-parse --short $head3) ' -test_format complex-encoding %e <<EOF +test_format complex-encoding %e success ICONV <<EOF commit $head3 $test_encoding commit $head2 diff --git a/t/t6007-rev-list-cherry-pick-file.sh b/t/t6007-rev-list-cherry-pick-file.sh index 2d337d7287a3c2..6f3e5439771fa6 100755 --- a/t/t6007-rev-list-cherry-pick-file.sh +++ b/t/t6007-rev-list-cherry-pick-file.sh @@ -5,7 +5,6 @@ test_description='test git rev-list --cherry-pick -- file' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # A---B---D---F diff --git a/t/t6008-rev-list-submodule.sh b/t/t6008-rev-list-submodule.sh index 2cdef6fdf985c1..a0a070b404293a 100755 --- a/t/t6008-rev-list-submodule.sh +++ b/t/t6008-rev-list-submodule.sh @@ -8,7 +8,6 @@ test_description='git rev-list involving submodules that this repo has' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh index 91db8fafe83e38..9c9a8459af9130 100755 --- a/t/t6009-rev-list-parent.sh +++ b/t/t6009-rev-list-parent.sh @@ -5,7 +5,6 @@ test_description='ancestor culling and limiting by parent number' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_revlist () { diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh index f96ea82e78636f..44c726ea397cf1 100755 --- a/t/t6010-merge-base.sh +++ b/t/t6010-merge-base.sh @@ -6,7 +6,6 @@ test_description='Merge base and parent list computation. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh M=1130000000 diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh index b2e422cf0f7eaa..bad02cf5b83dbc 100755 --- a/t/t6011-rev-list-with-bad-commit.sh +++ b/t/t6011-rev-list-with-bad-commit.sh @@ -2,7 +2,6 @@ test_description='git rev-list should notice bad commits' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Note: diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh index de1e87f1621d5d..4cecb6224cb464 100755 --- a/t/t6012-rev-list-simplify.sh +++ b/t/t6012-rev-list-simplify.sh @@ -177,7 +177,7 @@ test_expect_success '--full-diff is not affected by --parents' ' # \ / /\ / # `---X--' `---Y--' # -# This example is explained in Documentation/rev-list-options.txt +# This example is explained in Documentation/rev-list-options.adoc test_expect_success 'setup rebuild repo' ' rm -rf .git * && diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh index 4128269c1d481b..39793cbbd661af 100755 --- a/t/t6013-rev-list-reverse-parents.sh +++ b/t/t6013-rev-list-reverse-parents.sh @@ -5,7 +5,6 @@ test_description='--reverse combines with --parents' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t6014-rev-list-all.sh b/t/t6014-rev-list-all.sh index 16b8bd1d090eae..c9bedd29cba4aa 100755 --- a/t/t6014-rev-list-all.sh +++ b/t/t6014-rev-list-all.sh @@ -2,7 +2,6 @@ test_description='--all includes detached HEADs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t6017-rev-list-stdin.sh b/t/t6017-rev-list-stdin.sh index a0a40fe55cd8f7..4821b90e7479ad 100755 --- a/t/t6017-rev-list-stdin.sh +++ b/t/t6017-rev-list-stdin.sh @@ -8,7 +8,6 @@ test_description='log family learns --stdin' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check () { diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index 3b181f771c25a3..bb55c7e3c3c30d 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -5,7 +5,6 @@ test_description='rev-list/rev-parse --glob' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit () { diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh index 34b5cd62c201d9..b3807e8f35f03c 100755 --- a/t/t6020-bundle-misc.sh +++ b/t/t6020-bundle-misc.sh @@ -8,7 +8,6 @@ test_description='Test git-bundle' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bundle.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -247,7 +246,11 @@ test_expect_success 'create bundle with --since option' ' EOF test_cmp expect actual && - git bundle create since.bdl \ + # If a different name hash function is used, then one fewer + # delta base is found and this counts a different number + # of objects after performing --fix-thin. + GIT_TEST_NAME_HASH_VERSION=1 \ + git bundle create since.bdl \ --since "Thu Apr 7 15:27:00 2005 -0700" \ --all && @@ -505,6 +508,50 @@ test_expect_success 'unfiltered bundle with --objects' ' test_cmp expect actual ' +test_expect_success 'full bundle upto annotated tag' ' + git bundle create v2.bdl \ + v2 && + + git bundle verify v2.bdl | + make_user_friendly_and_stable_output >actual && + + format_and_save_expect <<-EOF && + The bundle contains this ref: + <TAG-2> refs/tags/v2 + The bundle records a complete history. + $HASH_MESSAGE + EOF + test_cmp expect actual +' + +test_expect_success 'clone from full bundle upto annotated tag' ' + git clone --mirror v2.bdl tag-clone.git && + git -C tag-clone.git show-ref | + make_user_friendly_and_stable_output >actual && + cat >expect <<-\EOF && + <TAG-2> refs/tags/v2 + EOF + test_cmp expect actual +' + +test_expect_success 'incremental bundle between two annotated tags' ' + git bundle create v1-v2.bdl \ + v1..v2 && + + git bundle verify v1-v2.bdl | + make_user_friendly_and_stable_output >actual && + + format_and_save_expect <<-EOF && + The bundle contains this ref: + <TAG-2> refs/tags/v2 + The bundle requires these 2 refs: + <COMMIT-E> Z + <COMMIT-B> Z + $HASH_MESSAGE + EOF + test_cmp expect actual +' + for filter in "blob:none" "tree:0" "tree:1" "blob:limit=100" do test_expect_success "filtered bundle: $filter" ' diff --git a/t/t6021-rev-list-exclude-hidden.sh b/t/t6021-rev-list-exclude-hidden.sh index 51df02105d7b83..5fe942a2936830 100755 --- a/t/t6021-rev-list-exclude-hidden.sh +++ b/t/t6021-rev-list-exclude-hidden.sh @@ -2,7 +2,6 @@ test_description='git rev-list --exclude-hidden test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6022-rev-list-missing.sh b/t/t6022-rev-list-missing.sh index 127180e1c9a246..3e2790d4c826d8 100755 --- a/t/t6022-rev-list-missing.sh +++ b/t/t6022-rev-list-missing.sh @@ -2,7 +2,6 @@ test_description='handling of missing objects in rev-list' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # We setup the repository with two commits, this way HEAD is always @@ -146,4 +145,57 @@ do done done +for obj in "HEAD~1" "HEAD^{tree}" "HEAD:foo" "HEAD:foo/bar" "HEAD:baz baz" +do + test_expect_success "--missing=print-info with missing '$obj'" ' + test_when_finished rm -rf missing-info && + + git init missing-info && + ( + cd missing-info && + git commit --allow-empty -m first && + + mkdir foo && + echo bar >foo/bar && + echo baz >"baz baz" && + echo bat >bat\" && + git add -A && + git commit -m second && + + oid="$(git rev-parse "$obj")" && + path=".git/objects/$(test_oid_to_path $oid)" && + type_info=" type=$(git cat-file -t $oid)" && + + case $obj in + HEAD:foo) + path_info=" path=foo" + ;; + HEAD:foo/bar) + path_info=" path=foo/bar" + ;; + "HEAD:baz baz") + path_info=" path=\"baz baz\"" + ;; + "HEAD:bat\"") + path_info=" path=\"bat\\\"\"" + ;; + esac && + + # Before the object is made missing, we use rev-list to + # get the expected oids. + git rev-list --objects --no-object-names \ + HEAD ^"$obj" >expect.raw && + echo "?$oid$path_info$type_info" >>expect.raw && + + mv "$path" "$path.hidden" && + git rev-list --objects --no-object-names \ + --missing=print-info HEAD >actual.raw && + + sort actual.raw >actual && + sort expect.raw >expect && + test_cmp expect actual + ) + ' +done + test_done diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh index acc281c116815e..0b719bbae68ed5 100755 --- a/t/t6040-tracking-info.sh +++ b/t/t6040-tracking-info.sh @@ -5,7 +5,6 @@ test_description='remote tracking stats' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh advance () { diff --git a/t/t6041-bisect-submodule.sh b/t/t6041-bisect-submodule.sh index 3946e18089a2a5..82013fc9037c1d 100755 --- a/t/t6041-bisect-submodule.sh +++ b/t/t6041-bisect-submodule.sh @@ -2,7 +2,6 @@ test_description='bisect can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index d7702fc7562332..aa1b5351873ee5 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -7,7 +7,6 @@ test_description='Tests replace refs functionality' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-gpg.sh" @@ -98,30 +97,42 @@ test_expect_success 'set up buggy branch' ' ' test_expect_success 'replace the author' ' - git cat-file commit $HASH2 | grep "author A U Thor" && - R=$(git cat-file commit $HASH2 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) && - git cat-file commit $R | grep "author O Thor" && + git cat-file commit $HASH2 >actual && + test_grep "author A U Thor" actual && + R=$(sed -e "s/A U/O/" actual | git hash-object -t commit --stdin -w) && + git cat-file commit $R >actual && + test_grep "author O Thor" actual && git update-ref refs/replace/$HASH2 $R && - git show HEAD~5 | grep "O Thor" && - git show $HASH2 | grep "O Thor" + git show HEAD~5 >actual && + test_grep "O Thor" actual && + git show $HASH2 >actual && + test_grep "O Thor" actual ' test_expect_success 'test --no-replace-objects option' ' - git cat-file commit $HASH2 | grep "author O Thor" && - git --no-replace-objects cat-file commit $HASH2 | grep "author A U Thor" && - git show $HASH2 | grep "O Thor" && - git --no-replace-objects show $HASH2 | grep "A U Thor" + git cat-file commit $HASH2 >actual && + test_grep "author O Thor" actual && + git --no-replace-objects cat-file commit $HASH2 >actual && + test_grep "author A U Thor" actual && + git show $HASH2 >actual && + test_grep "O Thor" actual && + git --no-replace-objects show $HASH2 >actual && + test_grep "A U Thor" actual ' test_expect_success 'test GIT_NO_REPLACE_OBJECTS env variable' ' - GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 | grep "author A U Thor" && - GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 | grep "A U Thor" + GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 >actual && + test_grep "author A U Thor" actual && + GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 >actual && + test_grep "A U Thor" actual ' test_expect_success 'test core.usereplacerefs config option' ' test_config core.usereplacerefs false && - git cat-file commit $HASH2 | grep "author A U Thor" && - git show $HASH2 | grep "A U Thor" + git cat-file commit $HASH2 >actual && + test_grep "author A U Thor" actual && + git show $HASH2 >actual && + test_grep "A U Thor" actual ' cat >tag.sig <<EOF @@ -148,14 +159,18 @@ test_expect_success 'repack, clone and fetch work' ' git clone --no-hardlinks . clone_dir && ( cd clone_dir && - git show HEAD~5 | grep "A U Thor" && - git show $HASH2 | grep "A U Thor" && + git show HEAD~5 >actual && + test_grep "A U Thor" actual && + git show $HASH2 >actual && + test_grep "A U Thor" actual && git cat-file commit $R && git repack -a -d && test_must_fail git cat-file commit $R && git fetch ../ "refs/replace/*:refs/replace/*" && - git show HEAD~5 | grep "O Thor" && - git show $HASH2 | grep "O Thor" && + git show HEAD~5 >actual && + test_grep "O Thor" actual && + git show $HASH2 >actual && + test_grep "O Thor" actual && git cat-file commit $R ) ' @@ -169,13 +184,15 @@ test_expect_success '"git replace" listing and deleting' ' test_must_fail git replace --delete && test_must_fail git replace -l -d $HASH2 && git replace -d $HASH2 && - git show $HASH2 | grep "A U Thor" && + git show $HASH2 >actual && + test_grep "A U Thor" actual && test -z "$(git replace -l)" ' test_expect_success '"git replace" replacing' ' git replace $HASH2 $R && - git show $HASH2 | grep "O Thor" && + git show $HASH2 >actual && + test_grep "O Thor" actual && test_must_fail git replace $HASH2 $R && git replace -f $HASH2 $R && test_must_fail git replace -f && @@ -186,7 +203,8 @@ test_expect_success '"git replace" resolves sha1' ' SHORTHASH2=$(git rev-parse --short=8 $HASH2) && git replace -d $SHORTHASH2 && git replace $SHORTHASH2 $R && - git show $HASH2 | grep "O Thor" && + git show $HASH2 >actual && + test_grep "O Thor" actual && test_must_fail git replace $HASH2 $R && git replace -f $HASH2 $R && test_must_fail git replace --force && @@ -209,10 +227,12 @@ test_expect_success '"git replace" resolves sha1' ' # test_expect_success 'create parallel branch without the bug' ' git replace -d $HASH2 && - git show $HASH2 | grep "A U Thor" && + git show $HASH2 >actual && + test_grep "A U Thor" actual && git checkout $HASH1 && git cherry-pick $HASH2 && - git show $HASH5 | git apply && + git show $HASH5 >actual && + git apply actual && git commit --amend -m "hello: 4 more lines WITHOUT the bug" hello && PARA2=$(git rev-parse --verify HEAD) && git cherry-pick $HASH3 && @@ -225,7 +245,8 @@ test_expect_success 'create parallel branch without the bug' ' git checkout main && cur=$(git rev-parse --verify HEAD) && test "$cur" = "$HASH7" && - git log --pretty=oneline | grep $PARA2 && + git log --pretty=oneline >actual && + test_grep $PARA2 actual && git remote add cloned ./clone_dir ' @@ -234,23 +255,30 @@ test_expect_success 'push to cloned repo' ' ( cd clone_dir && git checkout parallel && - git log --pretty=oneline | grep $PARA2 + git log --pretty=oneline >actual && + test_grep $PARA2 actual ) ' test_expect_success 'push branch with replacement' ' - git cat-file commit $PARA3 | grep "author A U Thor" && - S=$(git cat-file commit $PARA3 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) && - git cat-file commit $S | grep "author O Thor" && + git cat-file commit $PARA3 >actual && + test_grep "author A U Thor" actual && + S=$(sed -e "s/A U/O/" actual | git hash-object -t commit --stdin -w) && + git cat-file commit $S >actual && + test_grep "author O Thor" actual && git replace $PARA3 $S && - git show $HASH6~2 | grep "O Thor" && - git show $PARA3 | grep "O Thor" && + git show $HASH6~2 >actual && + test_grep "O Thor" actual && + git show $PARA3 >actual && + test_grep "O Thor" actual && git push cloned $HASH6^:refs/heads/parallel2 && ( cd clone_dir && git checkout parallel2 && - git log --pretty=oneline | grep $PARA3 && - git show $PARA3 | grep "A U Thor" + git log --pretty=oneline >actual && + test_grep $PARA3 actual && + git show $PARA3 >actual && + test_grep "A U Thor" actual ) ' @@ -260,14 +288,14 @@ test_expect_success 'fetch branch with replacement' ' cd clone_dir && git fetch origin refs/heads/tofetch:refs/heads/parallel3 && git log --pretty=oneline parallel3 >output.txt && - ! grep $PARA3 output.txt && + test_grep ! $PARA3 output.txt && git show $PARA3 >para3.txt && - grep "A U Thor" para3.txt && + test_grep "A U Thor" para3.txt && git fetch origin "refs/replace/*:refs/replace/*" && git log --pretty=oneline parallel3 >output.txt && - grep $PARA3 output.txt && + test_grep $PARA3 output.txt && git show $PARA3 >para3.txt && - grep "O Thor" para3.txt + test_grep "O Thor" para3.txt ) ' @@ -284,8 +312,8 @@ test_expect_success 'bisect and replacements' ' ' test_expect_success 'index-pack and replacements' ' - git --no-replace-objects rev-list --objects HEAD | - git --no-replace-objects pack-objects test- && + git --no-replace-objects rev-list --objects HEAD >actual && + git --no-replace-objects pack-objects test- <actual && git index-pack test-*.pack ' @@ -319,7 +347,8 @@ test_expect_success '-f option bypasses the type check' ' ' test_expect_success 'git cat-file --batch works on replace objects' ' - git replace | grep $PARA3 && + git replace >actual && + test_grep $PARA3 actual && echo $PARA3 | git cat-file --batch ' @@ -344,7 +373,8 @@ test_expect_success 'test --format medium' ' echo "$PARA3 -> $S" && echo "$MYTAG -> $HASH1" } | sort >expected && - git replace -l --format medium | sort >actual && + git replace -l --format medium >output && + sort output >actual && test_cmp expected actual ' @@ -356,7 +386,8 @@ test_expect_success 'test --format long' ' echo "$PARA3 (commit) -> $S (commit)" && echo "$MYTAG (tag) -> $HASH1 (commit)" } | sort >expected && - git replace --format=long | sort >actual && + git replace --format=long >output && + sort output >actual && test_cmp expected actual ' @@ -374,12 +405,16 @@ test_expect_success 'setup fake editors' ' test_expect_success '--edit with and without already replaced object' ' test_must_fail env GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" && GIT_EDITOR=./fakeeditor git replace --force --edit "$PARA3" && - git replace -l | grep "$PARA3" && - git cat-file commit "$PARA3" | grep "A fake Thor" && + git replace -l >actual && + test_grep "$PARA3" actual && + git cat-file commit "$PARA3" >actual && + test_grep "A fake Thor" actual && git replace -d "$PARA3" && GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" && - git replace -l | grep "$PARA3" && - git cat-file commit "$PARA3" | grep "A fake Thor" + git replace -l >actual && + test_grep "$PARA3" actual && + git cat-file commit "$PARA3" >actual && + test_grep "A fake Thor" actual ' test_expect_success '--edit and change nothing or command failed' ' @@ -387,8 +422,10 @@ test_expect_success '--edit and change nothing or command failed' ' test_must_fail env GIT_EDITOR=true git replace --edit "$PARA3" && test_must_fail env GIT_EDITOR="./failingfakeeditor" git replace --edit "$PARA3" && GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" && - git replace -l | grep "$PARA3" && - git cat-file commit "$PARA3" | grep "A fake Thor" + git replace -l >actual && + test_grep "$PARA3" actual && + git cat-file commit "$PARA3" >actual && + test_grep "A fake Thor" actual ' test_expect_success 'replace ref cleanup' ' @@ -468,7 +505,8 @@ test_expect_success GPG 'set up a merge commit with a mergetag' ' git checkout main && git merge -s ours test_tag && HASH10=$(git rev-parse --verify HEAD) && - git cat-file commit $HASH10 | grep "^mergetag object" + git cat-file commit $HASH10 >actual && + test_grep "^mergetag object" actual ' test_expect_success GPG '--graft on a commit with a mergetag' ' diff --git a/t/t6060-merge-index.sh b/t/t6060-merge-index.sh index 1a8b64cce18239..e6b3e6ec775993 100755 --- a/t/t6060-merge-index.sh +++ b/t/t6060-merge-index.sh @@ -2,7 +2,6 @@ test_description='basic git merge-index / git-merge-one-file tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup diverging branches' ' diff --git a/t/t6100-rev-list-in-order.sh b/t/t6100-rev-list-in-order.sh index 88ed7bd75a75f0..e934bc239c534d 100755 --- a/t/t6100-rev-list-in-order.sh +++ b/t/t6100-rev-list-in-order.sh @@ -2,7 +2,6 @@ test_description='rev-list testing in-commit-order' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a commit history with trees, blobs' ' diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index d20723d627629f..5f55ab98d352fc 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -8,7 +8,6 @@ test_description='Test git rev-parse with different parent options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true TEST_CREATE_REPO_NO_TEMPLATE=1 . ./test-lib.sh diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh index 5d28507efc687b..22dfd6d978ef53 100755 --- a/t/t6102-rev-list-unexpected-objects.sh +++ b/t/t6102-rev-list-unexpected-objects.sh @@ -2,7 +2,6 @@ test_description='git rev-list should handle unexpected object types' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup well-formed objects' ' diff --git a/t/t6110-rev-list-sparse.sh b/t/t6110-rev-list-sparse.sh index ddefc7f24ee9ca..13c1da53528367 100755 --- a/t/t6110-rev-list-sparse.sh +++ b/t/t6110-rev-list-sparse.sh @@ -4,7 +4,6 @@ test_description='operations that cull histories in unusual ways' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh index a9656a1ec8a6d7..902854cbfaacce 100755 --- a/t/t6113-rev-list-bitmap-filters.sh +++ b/t/t6113-rev-list-bitmap-filters.sh @@ -2,7 +2,6 @@ test_description='rev-list combining bitmaps and filters' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bitmap.sh diff --git a/t/t6114-keep-packs.sh b/t/t6114-keep-packs.sh index 44246f8a63e55f..a584522ef29fa3 100755 --- a/t/t6114-keep-packs.sh +++ b/t/t6114-keep-packs.sh @@ -2,7 +2,6 @@ test_description='rev-list with .keep packs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6115-rev-list-du.sh b/t/t6115-rev-list-du.sh index 21c4a211b15a83..3385fe9f130762 100755 --- a/t/t6115-rev-list-du.sh +++ b/t/t6115-rev-list-du.sh @@ -2,7 +2,6 @@ test_description='basic tests of rev-list --disk-usage' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # we want a mix of reachable and unreachable, as well as diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 05ed2510d96868..76843a61691cb5 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -14,11 +14,11 @@ test_description='test describe' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_describe () { indir= && + outcome=success && while test $# != 0 do case "$1" in @@ -26,6 +26,9 @@ check_describe () { indir="$2" shift ;; + --expect-failure) + outcome=failure + ;; *) break ;; @@ -36,7 +39,7 @@ check_describe () { expect="$1" shift describe_opts="$@" - test_expect_success "describe $describe_opts" ' + test_expect_${outcome} "describe $describe_opts" ' git ${indir:+ -C "$indir"} describe $describe_opts >raw && sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual && echo "$expect" >expect && @@ -79,11 +82,13 @@ check_describe R-2-gHASH HEAD^^ check_describe A-3-gHASH HEAD^^2 check_describe B HEAD^^2^ check_describe R-1-gHASH HEAD^^^ +check_describe R-1-gHASH R-1-g$(git rev-parse --short HEAD^^)~1 check_describe c-7-gHASH --tags HEAD check_describe c-6-gHASH --tags HEAD^ check_describe e-1-gHASH --tags HEAD^^ check_describe c-2-gHASH --tags HEAD^^2 +check_describe c-2-gHASH --tags c-2-g$(git rev-parse --short HEAD^^2)^0 check_describe B --tags HEAD^^2^ check_describe e --tags HEAD^^^ check_describe e --tags --exact-match HEAD^^^ @@ -617,7 +622,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' ' # B # o -# \ +# H \ # o-----o---o----x # A # @@ -627,6 +632,7 @@ test_expect_success 'setup: describe commits with disjoint bases' ' cd disjoint1 && echo o >> file && git add file && git commit -m o && + git tag H -a -m H && echo A >> file && git add file && git commit -m A && git tag A -a -m A && echo o >> file && git add file && git commit -m o && @@ -639,8 +645,9 @@ test_expect_success 'setup: describe commits with disjoint bases' ' ' check_describe -C disjoint1 "A-3-gHASH" HEAD +check_describe -C disjoint1 --expect-failure "A-3-gHASH" --candidates=2 HEAD -# B +# H B # o---o---o------------. # \ # o---o---x @@ -658,6 +665,7 @@ test_expect_success 'setup: describe commits with disjoint bases 2' ' git checkout --orphan branch && echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o && echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o && + git tag H -a -m H && echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B && git tag B -a -m B && git merge --no-ff --allow-unrelated-histories main -m x @@ -665,6 +673,7 @@ test_expect_success 'setup: describe commits with disjoint bases 2' ' ' check_describe -C disjoint2 "B-3-gHASH" HEAD +check_describe -C disjoint2 --expect-failure "B-3-gHASH" --candidates=2 HEAD test_expect_success 'setup misleading taggerdates' ' GIT_COMMITTER_DATE="2006-12-12 12:31" git tag -a -m "another tag" newer-tag-older-commit unique-file~1 @@ -708,4 +717,36 @@ test_expect_success 'describe --broken --dirty with a file with changed stat' ' ) ' +test_expect_success '--always with no refs falls back to commit hash' ' + git rev-parse HEAD >expect && + git describe --no-abbrev --always --match=no-such-tag >actual && + test_cmp expect actual +' + +test_expect_success '--exact-match does not show --always fallback' ' + test_must_fail git describe --exact-match --always +' + +test_expect_success 'avoid being fooled by describe-like filename' ' + test_when_finished rm out && + + git rev-parse --short HEAD >out && + FILENAME=filename-g$(cat out) && + touch $FILENAME && + git add $FILENAME && + git commit -m "Add $FILENAME" && + + git cat-file -t HEAD:$FILENAME >actual && + + echo blob >expect && + test_cmp expect actual +' + +test_expect_success 'do not be fooled by invalid describe format ' ' + test_when_finished rm out && + + git rev-parse --short HEAD >out && + test_must_fail git cat-file -t "refs/tags/super-invalid/./../...../ ~^:/?*[////\\\\\\&}/busted.lock-42-g"$(cat out) +' + test_done diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh index 82de25d549a07e..a7f2603cb4a9b5 100755 --- a/t/t6130-pathspec-noglob.sh +++ b/t/t6130-pathspec-noglob.sh @@ -2,7 +2,6 @@ test_description='test globbing (and noglob) of pathspec limiting' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create commits with glob characters' ' diff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh index 770cce026cb158..e64d9380838232 100755 --- a/t/t6131-pathspec-icase.sh +++ b/t/t6131-pathspec-icase.sh @@ -2,7 +2,6 @@ test_description='test case insensitive pathspec limiting' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test_have_prereq CASE_INSENSITIVE_FS diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh index f31c09c056fc6c..9fdafeb1e907f4 100755 --- a/t/t6132-pathspec-exclude.sh +++ b/t/t6132-pathspec-exclude.sh @@ -2,7 +2,6 @@ test_description='test case exclude pathspec' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6133-pathspec-rev-dwim.sh b/t/t6133-pathspec-rev-dwim.sh index 6dd4bbbf9fc9ba..0f722fb340da55 100755 --- a/t/t6133-pathspec-rev-dwim.sh +++ b/t/t6133-pathspec-rev-dwim.sh @@ -2,7 +2,6 @@ test_description='test dwim of revs versus pathspecs in revision parser' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6134-pathspec-in-submodule.sh b/t/t6134-pathspec-in-submodule.sh index 16ce4cfcc64204..9b62a0a65f16af 100755 --- a/t/t6134-pathspec-in-submodule.sh +++ b/t/t6134-pathspec-in-submodule.sh @@ -2,7 +2,6 @@ test_description='test case exclude pathspec' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a submodule' ' diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh index 794bc7daf05047..67d8c72147c8b8 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -2,7 +2,6 @@ test_description='test labels in pathspecs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a tree' ' diff --git a/t/t6136-pathspec-in-bare.sh b/t/t6136-pathspec-in-bare.sh index 2db37a65969535..1284fe014358e1 100755 --- a/t/t6136-pathspec-in-bare.sh +++ b/t/t6136-pathspec-in-bare.sh @@ -2,7 +2,6 @@ test_description='diagnosing out-of-scope pathspec' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a bare and non-bare repository' ' diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index ac57b0e4ae3769..011e5df1e6e9f1 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -8,7 +8,6 @@ test_description='fmt-merge-msg test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-gpg.sh" @@ -608,34 +607,34 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git checkout main^0 && git commit --allow-empty -m "One step ahead" && - git tag -a -m "An annotated one" annote HEAD && + git tag -a -m "An annotated one" annotate HEAD && git checkout main && - git fetch . annote && + git fetch . annotate && git fmt-merge-msg <.git/FETCH_HEAD >actual && { cat <<-\EOF - Merge tag '\''annote'\'' + Merge tag '\''annotate'\'' An annotated one - * tag '\''annote'\'': + * tag '\''annotate'\'': One step ahead EOF } >expected && test_cmp expected actual && test_when_finished "git reset --hard" && - annote=$(git rev-parse annote) && - git merge --no-commit --no-ff $annote && + annotate=$(git rev-parse annotate) && + git merge --no-commit --no-ff $annotate && { cat <<-EOF - Merge tag '\''$annote'\'' + Merge tag '\''$annotate'\'' An annotated one - * tag '\''$annote'\'': + * tag '\''$annotate'\'': One step ahead EOF } >expected && diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index b3163629c55793..a5c77943854738 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -5,7 +5,6 @@ test_description='for-each-ref test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GNUPGHOME_NOT_USED=$GNUPGHOME . "$TEST_DIRECTORY"/lib-gpg.sh @@ -770,7 +769,7 @@ test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' refs/heads/master >actual && test_cmp expect actual && - # Make sure the hash used is atleast 14 digits long + # Make sure the hash used is at least 14 digits long sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && test 15 -le $(wc -c <hexpart) && diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh index 83b8a19d94176d..e06feb06e91956 100755 --- a/t/t6301-for-each-ref-errors.sh +++ b/t/t6301-for-each-ref-errors.sh @@ -2,7 +2,6 @@ test_description='for-each-ref errors for broken refs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh ZEROS=$ZERO_OID diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 7f44d3c3f22898..bb02b86c163559 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -2,7 +2,6 @@ test_description='test for-each-refs usage of ref-filter APIs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh @@ -14,7 +13,7 @@ test_expect_success 'setup some history and refs' ' git checkout -b side && test_commit four && git tag -m "An annotated tag" annotated-tag && - git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag && + git tag -m "Annotated doubly" doubly-annotated-tag annotated-tag && # Note that these "signed" tags might not actually be signed. # Tests which care about the distinction should be marked @@ -343,7 +342,7 @@ test_expect_success 'check `%(contents:lines=1)`' ' side |four odd/spot |three annotated-tag |An annotated tag - doubly-annotated-tag |Annonated doubly + doubly-annotated-tag |Annotated doubly doubly-signed-tag |Signed doubly four |four one |one @@ -379,7 +378,7 @@ test_expect_success 'check `%(contents:lines=99999)`' ' side |four odd/spot |three annotated-tag |An annotated tag - doubly-annotated-tag |Annonated doubly + doubly-annotated-tag |Annotated doubly doubly-signed-tag |Signed doubly four |four one |one diff --git a/t/t6400-merge-df.sh b/t/t6400-merge-df.sh index 27d6efdc9a6d37..3de4ef6bd9e640 100755 --- a/t/t6400-merge-df.sh +++ b/t/t6400-merge-df.sh @@ -7,7 +7,6 @@ test_description='Test merge with directory/file conflicts' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare repository' ' diff --git a/t/t6401-merge-criss-cross.sh b/t/t6401-merge-criss-cross.sh index 1962310408b122..c8e5ff28e80833 100755 --- a/t/t6401-merge-criss-cross.sh +++ b/t/t6401-merge-criss-cross.sh @@ -9,7 +9,6 @@ test_description='Test criss-cross merge' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare repository' ' diff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh index 729aac9842d1f7..2738b50c2a9e01 100755 --- a/t/t6402-merge-rename.sh +++ b/t/t6402-merge-rename.sh @@ -4,7 +4,6 @@ test_description='Merge-recursive merging renames' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh modify () { diff --git a/t/t6403-merge-file.sh b/t/t6403-merge-file.sh index fb872c5a1136fc..06ab4d7aede081 100755 --- a/t/t6403-merge-file.sh +++ b/t/t6403-merge-file.sh @@ -2,7 +2,6 @@ test_description='RCS merge replacement: merge-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6404-recursive-merge.sh b/t/t6404-recursive-merge.sh index 36215518b6eb1a..ae687f2ce541b9 100755 --- a/t/t6404-recursive-merge.sh +++ b/t/t6404-recursive-merge.sh @@ -4,7 +4,6 @@ test_description='Test merge without common ancestors' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This scenario is based on a real-world repository of Shawn Pearce. @@ -88,7 +87,7 @@ test_expect_success 'result contains a conflict' ' ' test_expect_success 'virtual trees were processed' ' - # TODO: fragile test, relies on ambigious merge-base resolution + # TODO: fragile test, relies on ambiguous merge-base resolution git ls-files --stage >out && cat >expect <<-EOF && diff --git a/t/t6405-merge-symlinks.sh b/t/t6405-merge-symlinks.sh index 29e2b25ce5de25..7435fce71e0040 100755 --- a/t/t6405-merge-symlinks.sh +++ b/t/t6405-merge-symlinks.sh @@ -11,7 +11,6 @@ if core.symlinks is false.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6406-merge-attr.sh b/t/t6406-merge-attr.sh index 9bf952493471e5..66e01464b5ebb9 100755 --- a/t/t6406-merge-attr.sh +++ b/t/t6406-merge-attr.sh @@ -8,7 +8,6 @@ test_description='per path merge controlled by merge attribute' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -118,6 +117,14 @@ test_expect_success 'retry the merge with longer context' ' grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual ' +test_expect_success 'invalid conflict-marker-size 3a' ' + cp .gitattributes .gitattributes.bak && + echo "text conflict-marker-size=3a" >>.gitattributes && + test_when_finished "mv .gitattributes.bak .gitattributes" && + git checkout -m text 2>err && + test_grep "warning: invalid marker-size ${SQ}3a${SQ}, expecting an integer" err +' + test_expect_success 'custom merge backend' ' echo "* merge=union" >.gitattributes && diff --git a/t/t6407-merge-binary.sh b/t/t6407-merge-binary.sh index 0753fc95f45efb..e8a28717cece32 100755 --- a/t/t6407-merge-binary.sh +++ b/t/t6407-merge-binary.sh @@ -5,7 +5,6 @@ test_description='ask merge-recursive to merge binary files' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6408-merge-up-to-date.sh b/t/t6408-merge-up-to-date.sh index 8a1ba6d23a7dc4..7763c1ba98080d 100755 --- a/t/t6408-merge-up-to-date.sh +++ b/t/t6408-merge-up-to-date.sh @@ -2,7 +2,6 @@ test_description='merge fast-forward and up to date' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6409-merge-subtree.sh b/t/t6409-merge-subtree.sh index 528615b981f899..e9ba6f1690d015 100755 --- a/t/t6409-merge-subtree.sh +++ b/t/t6409-merge-subtree.sh @@ -5,7 +5,6 @@ test_description='subtree merge strategy' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6411-merge-filemode.sh b/t/t6411-merge-filemode.sh index b6182723aae158..6ae2489286c278 100755 --- a/t/t6411-merge-filemode.sh +++ b/t/t6411-merge-filemode.sh @@ -4,7 +4,6 @@ test_description='merge: handle file mode' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up mode change in one branch' ' diff --git a/t/t6412-merge-large-rename.sh b/t/t6412-merge-large-rename.sh index d0863a8fb51016..ca018d11f54797 100755 --- a/t/t6412-merge-large-rename.sh +++ b/t/t6412-merge-large-rename.sh @@ -4,7 +4,6 @@ test_description='merging with large rename matrix' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh count() { diff --git a/t/t6413-merge-crlf.sh b/t/t6413-merge-crlf.sh index 647ea1e8382913..cd6adf6caacfcb 100755 --- a/t/t6413-merge-crlf.sh +++ b/t/t6413-merge-crlf.sh @@ -11,7 +11,6 @@ test_description='merge conflict in crlf repo GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6414-merge-rename-nocruft.sh b/t/t6414-merge-rename-nocruft.sh index 69fc1c9e697a9d..d7e3c1fa6e6348 100755 --- a/t/t6414-merge-rename-nocruft.sh +++ b/t/t6414-merge-rename-nocruft.sh @@ -4,7 +4,6 @@ test_description='Merge-recursive merging renames' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6415-merge-dir-to-symlink.sh b/t/t6415-merge-dir-to-symlink.sh index ae00492c768217..2655e295f5ae45 100755 --- a/t/t6415-merge-dir-to-symlink.sh +++ b/t/t6415-merge-dir-to-symlink.sh @@ -4,7 +4,6 @@ test_description='merging when a directory was replaced with a symlink' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create a commit where dir a/b changed to symlink' ' diff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh index 5f414abc89267d..17b54d625d0e46 100755 --- a/t/t6416-recursive-corner-cases.sh +++ b/t/t6416-recursive-corner-cases.sh @@ -5,7 +5,6 @@ test_description='recursive merge corner cases involving criss-cross merges' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6417-merge-ours-theirs.sh b/t/t6417-merge-ours-theirs.sh index 482b73a998ff2a..62d1406119e8c2 100755 --- a/t/t6417-merge-ours-theirs.sh +++ b/t/t6417-merge-ours-theirs.sh @@ -4,7 +4,6 @@ test_description='Merge-recursive ours and theirs variants' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6418-merge-text-auto.sh b/t/t6418-merge-text-auto.sh index 48a62cb85568bf..41288a60ceb549 100755 --- a/t/t6418-merge-text-auto.sh +++ b/t/t6418-merge-text-auto.sh @@ -15,7 +15,6 @@ test_description='CRLF merge conflict across text=auto change GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_have_prereq SED_STRIPS_CR && SED_OPTIONS=-b diff --git a/t/t6421-merge-partial-clone.sh b/t/t6421-merge-partial-clone.sh index 30349a466e7aad..b99f29ef9baded 100755 --- a/t/t6421-merge-partial-clone.sh +++ b/t/t6421-merge-partial-clone.sh @@ -26,7 +26,6 @@ test_description="limiting blob downloads when merging with partial clones" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh index 80d7b5eabaf02e..62b49c67e22e8c 100755 --- a/t/t6422-merge-rename-corner-cases.sh +++ b/t/t6422-merge-rename-corner-cases.sh @@ -6,7 +6,6 @@ test_description="recursive merge corner cases w/ renames but not criss-crosses" GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh index 4aaaf38be684fd..94080c65d12b03 100755 --- a/t/t6423-merge-rename-directories.sh +++ b/t/t6423-merge-rename-directories.sh @@ -25,7 +25,6 @@ test_description="recursive merge with directory renames" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh @@ -5072,7 +5071,8 @@ test_expect_success '12i: Directory rename causes rename-to-self' ' test_path_is_file source/bar && test_path_is_file source/baz && - git ls-files | uniq >tracked && + git ls-files >actual && + uniq <actual >tracked && test_line_count = 3 tracked && git status --porcelain -uno >actual && @@ -5130,7 +5130,8 @@ test_expect_success '12j: Directory rename to root causes rename-to-self' ' test_path_is_file bar && test_path_is_file baz && - git ls-files | uniq >tracked && + git ls-files >actual && + uniq <actual >tracked && test_line_count = 3 tracked && git status --porcelain -uno >actual && @@ -5188,7 +5189,8 @@ test_expect_success '12k: Directory rename with sibling causes rename-to-self' ' test_path_is_file dirA/bar && test_path_is_file dirA/baz && - git ls-files | uniq >tracked && + git ls-files >actual && + uniq <actual >tracked && test_line_count = 3 tracked && git status --porcelain -uno >actual && diff --git a/t/t6425-merge-rename-delete.sh b/t/t6425-merge-rename-delete.sh index b95b064311b676..c15d031b165b23 100755 --- a/t/t6425-merge-rename-delete.sh +++ b/t/t6425-merge-rename-delete.sh @@ -4,7 +4,6 @@ test_description='Merge-recursive rename/delete conflict message' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'rename/delete' ' diff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh index 62f0180325352b..b059475ed03344 100755 --- a/t/t6426-merge-skip-unneeded-updates.sh +++ b/t/t6426-merge-skip-unneeded-updates.sh @@ -22,7 +22,6 @@ test_description="merge cases" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6427-diff3-conflict-markers.sh b/t/t6427-diff3-conflict-markers.sh index a13271b34902bc..dd5fe6a4021962 100755 --- a/t/t6427-diff3-conflict-markers.sh +++ b/t/t6427-diff3-conflict-markers.sh @@ -5,7 +5,6 @@ test_description='recursive merge diff3 style conflict markers' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Setup: diff --git a/t/t6428-merge-conflicts-sparse.sh b/t/t6428-merge-conflicts-sparse.sh index 8a79bc2e921d43..9919c3fa7cd435 100755 --- a/t/t6428-merge-conflicts-sparse.sh +++ b/t/t6428-merge-conflicts-sparse.sh @@ -22,7 +22,6 @@ test_description="merge cases" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh index cb1c4ceef76341..0f39ed0d08a342 100755 --- a/t/t6429-merge-sequence-rename-caching.sh +++ b/t/t6429-merge-sequence-rename-caching.sh @@ -2,7 +2,6 @@ test_description="remember regular & dir renames in sequence of merges" -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # diff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh index 555f00f78a1905..ca15e6dd6da94b 100755 --- a/t/t6430-merge-recursive.sh +++ b/t/t6430-merge-recursive.sh @@ -5,7 +5,6 @@ test_description='merge-recursive backend test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6431-merge-criscross.sh b/t/t6431-merge-criscross.sh index 3fe14cd73e895f..3824756a02ec31 100755 --- a/t/t6431-merge-criscross.sh +++ b/t/t6431-merge-criscross.sh @@ -2,7 +2,6 @@ test_description='merge-recursive backend test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # A <- create some files diff --git a/t/t6432-merge-recursive-space-options.sh b/t/t6432-merge-recursive-space-options.sh index c93538b0c38462..db4b77e63d23c4 100755 --- a/t/t6432-merge-recursive-space-options.sh +++ b/t/t6432-merge-recursive-space-options.sh @@ -14,7 +14,6 @@ test_description='merge-recursive space options GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_have_prereq SED_STRIPS_CR && SED_OPTIONS=-b diff --git a/t/t6433-merge-toplevel.sh b/t/t6433-merge-toplevel.sh index ed7866d3e955a3..0f611c40031cd6 100755 --- a/t/t6433-merge-toplevel.sh +++ b/t/t6433-merge-toplevel.sh @@ -5,7 +5,6 @@ test_description='"git merge" top-level frontend' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh t3033_reset () { diff --git a/t/t6434-merge-recursive-rename-options.sh b/t/t6434-merge-recursive-rename-options.sh index df1d0c156c54a3..6e913c30a136f5 100755 --- a/t/t6434-merge-recursive-rename-options.sh +++ b/t/t6434-merge-recursive-rename-options.sh @@ -22,14 +22,13 @@ R075 2-old 2-new R100 3-old 3-new Actual similarity indices are parsed from diff output. We rely on the fact that -they are rounded down (see, e.g., Documentation/diff-generate-patch.txt, which +they are rounded down (see, e.g., Documentation/diff-generate-patch.adoc, which mentions this in a different context). ' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh get_expected_stages () { diff --git a/t/t6435-merge-sparse.sh b/t/t6435-merge-sparse.sh index 78628fb248ab61..fde4aa3cd1ab66 100755 --- a/t/t6435-merge-sparse.sh +++ b/t/t6435-merge-sparse.sh @@ -3,7 +3,6 @@ test_description='merge with sparse files' TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # test_file $filename $content diff --git a/t/t6436-merge-overwrite.sh b/t/t6436-merge-overwrite.sh index ccc620477d494b..4f4376421e7da2 100755 --- a/t/t6436-merge-overwrite.sh +++ b/t/t6436-merge-overwrite.sh @@ -7,7 +7,6 @@ Do not overwrite changes.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh index 7a3f1cb27c12b4..4815559157b2fc 100755 --- a/t/t6437-submodule-merge.sh +++ b/t/t6437-submodule-merge.sh @@ -8,7 +8,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6438-submodule-directory-file-conflicts.sh b/t/t6438-submodule-directory-file-conflicts.sh index 3594190af84c1b..8df67a0ef99d26 100755 --- a/t/t6438-submodule-directory-file-conflicts.sh +++ b/t/t6438-submodule-directory-file-conflicts.sh @@ -2,7 +2,6 @@ test_description='merge can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t6439-merge-co-error-msgs.sh b/t/t6439-merge-co-error-msgs.sh index 0cbec57cdabc48..55bd744a3f4738 100755 --- a/t/t6439-merge-co-error-msgs.sh +++ b/t/t6439-merge-co-error-msgs.sh @@ -5,7 +5,6 @@ test_description='unpack-trees error messages' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh @@ -65,7 +64,7 @@ Please move or remove them before you merge. Aborting EOF -test_expect_success 'untracked files or local changes ovewritten by merge' ' +test_expect_success 'untracked files or local changes overwritten by merge' ' git add two && git add three && git add four && diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index ee074b99b708c3..bef472cb8dc37b 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -3,7 +3,6 @@ test_description='basic git gc tests ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -339,6 +338,39 @@ test_expect_success 'gc.maxCruftSize sets appropriate repack options' ' test_subcommand $cruft_max_size_opts --max-cruft-size=3145728 <trace2.txt ' +test_expect_success '--expire-to sets repack --expire-to' ' + rm -rf expired && + mkdir expired && + expire_to="$(pwd)/expired/pack" && + GIT_TRACE2_EVENT=$(pwd)/trace2.txt git -C cruft--max-size gc --cruft --expire-to="$expire_to" && + test_subcommand $cruft_max_size_opts --expire-to="$expire_to" <trace2.txt +' + +test_expect_success '--expire-to with --prune=now sets repack --expire-to' ' + rm -rf expired && + mkdir expired && + expire_to="$(pwd)/expired/pack" && + GIT_TRACE2_EVENT=$(pwd)/trace2.txt git -C cruft--max-size gc --cruft --prune=now --expire-to="$expire_to" && + test_subcommand git repack -d -l --cruft --cruft-expiration=now --expire-to="$expire_to" <trace2.txt +' + + +test_expect_success '--expire-to with --no-cruft sets repack -A' ' + rm -rf expired && + mkdir expired && + expire_to="$(pwd)/expired/pack" && + GIT_TRACE2_EVENT=$(pwd)/trace2.txt git -C cruft--max-size gc --no-cruft --expire-to="$expire_to" && + test_subcommand git repack -d -l -A --unpack-unreachable=2.weeks.ago <trace2.txt +' + +test_expect_success '--expire-to with --no-cruft sets repack -a' ' + rm -rf expired && + mkdir expired && + expire_to="$(pwd)/expired/pack" && + GIT_TRACE2_EVENT=$(pwd)/trace2.txt git -C cruft--max-size gc --no-cruft --prune=now --expire-to="$expire_to" && + test_subcommand git repack -d -l -a <trace2.txt +' + run_and_wait_for_gc () { # We read stdout from gc for the side effect of waiting until the # background gc process exits, closing its fd 9. Furthermore, the diff --git a/t/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh index 4521508b83a656..ddef1ca3915c35 100755 --- a/t/t6501-freshen-objects.sh +++ b/t/t6501-freshen-objects.sh @@ -28,7 +28,6 @@ test_description='check pruning of dependent objects' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # We care about reachability, so we do not want to use diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh index 2591f8b8b39bf4..6638d1aa1dcebe 100755 --- a/t/t6600-test-reach.sh +++ b/t/t6600-test-reach.sh @@ -733,4 +733,33 @@ test_expect_success 'for-each-ref is-base:multiple' ' --format="%(refname)[%(is-base:commit-2-3)-%(is-base:commit-6-5)]" --stdin ' +test_expect_success 'for-each-ref is-base: --sort' ' + cat >input <<-\EOF && + refs/heads/commit-1-1 + refs/heads/commit-4-2 + refs/heads/commit-4-4 + refs/heads/commit-8-4 + EOF + + cat >expect <<-\EOF && + refs/heads/commit-1-1 + refs/heads/commit-4-4 + refs/heads/commit-8-4 + refs/heads/commit-4-2 + EOF + run_all_modes git for-each-ref \ + --format="%(refname)" --stdin \ + --sort=refname --sort=is-base:commit-2-3 && + + cat >expect <<-\EOF && + refs/heads/commit-4-2 + refs/heads/commit-1-1 + refs/heads/commit-4-4 + refs/heads/commit-8-4 + EOF + run_all_modes git for-each-ref \ + --format="%(refname)" --stdin \ + --sort=refname --sort=-is-base:commit-2-3 +' + test_done diff --git a/t/t6601-path-walk.sh b/t/t6601-path-walk.sh new file mode 100755 index 00000000000000..c89b0f1e19d9fb --- /dev/null +++ b/t/t6601-path-walk.sh @@ -0,0 +1,400 @@ +#!/bin/sh + +TEST_PASSES_SANITIZE_LEAK=true + +test_description='direct path-walk API tests' + +. ./test-lib.sh + +test_expect_success 'setup test repository' ' + git checkout -b base && + + # Make some objects that will only be reachable + # via non-commit tags. + mkdir child && + echo file >child/file && + git add child && + git commit -m "will abandon" && + git tag -a -m "tree" tree-tag HEAD^{tree} && + echo file2 >file2 && + git add file2 && + git commit --amend -m "will abandon" && + git tag tree-tag2 HEAD^{tree} && + + echo blob >file && + blob_oid=$(git hash-object -t blob -w --stdin <file) && + git tag -a -m "blob" blob-tag "$blob_oid" && + echo blob2 >file2 && + blob2_oid=$(git hash-object -t blob -w --stdin <file2) && + git tag blob-tag2 "$blob2_oid" && + + rm -fr child file file2 && + + mkdir left && + mkdir right && + echo a >a && + echo b >left/b && + echo c >right/c && + git add . && + git commit --amend -m "first" && + git tag -m "first" first HEAD && + + echo d >right/d && + git add right && + git commit -m "second" && + git tag -a -m "second (under)" second.1 HEAD && + git tag -a -m "second (top)" second.2 second.1 && + + # Set up file/dir collision in history. + rm a && + mkdir a && + echo a >a/a && + echo bb >left/b && + git add a left && + git commit -m "third" && + git tag -a -m "third" third && + + git checkout -b topic HEAD~1 && + echo cc >right/c && + git commit -a -m "topic" && + git tag -a -m "fourth" fourth +' + +test_expect_success 'all' ' + test-tool path-walk -- --all >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 0:commit::$(git rev-parse base) + 0:commit::$(git rev-parse base~1) + 0:commit::$(git rev-parse base~2) + 1:tag:/tags:$(git rev-parse refs/tags/first) + 1:tag:/tags:$(git rev-parse refs/tags/second.1) + 1:tag:/tags:$(git rev-parse refs/tags/second.2) + 1:tag:/tags:$(git rev-parse refs/tags/third) + 1:tag:/tags:$(git rev-parse refs/tags/fourth) + 1:tag:/tags:$(git rev-parse refs/tags/tree-tag) + 1:tag:/tags:$(git rev-parse refs/tags/blob-tag) + 2:blob:/tagged-blobs:$(git rev-parse refs/tags/blob-tag^{}) + 2:blob:/tagged-blobs:$(git rev-parse refs/tags/blob-tag2^{}) + 3:tree::$(git rev-parse topic^{tree}) + 3:tree::$(git rev-parse base^{tree}) + 3:tree::$(git rev-parse base~1^{tree}) + 3:tree::$(git rev-parse base~2^{tree}) + 3:tree::$(git rev-parse refs/tags/tree-tag^{}) + 3:tree::$(git rev-parse refs/tags/tree-tag2^{}) + 4:blob:a:$(git rev-parse base~2:a) + 5:blob:file2:$(git rev-parse refs/tags/tree-tag2^{}:file2) + 6:tree:a/:$(git rev-parse base:a) + 7:tree:child/:$(git rev-parse refs/tags/tree-tag:child) + 8:blob:child/file:$(git rev-parse refs/tags/tree-tag:child/file) + 9:tree:left/:$(git rev-parse base:left) + 9:tree:left/:$(git rev-parse base~2:left) + 10:blob:left/b:$(git rev-parse base~2:left/b) + 10:blob:left/b:$(git rev-parse base:left/b) + 11:tree:right/:$(git rev-parse topic:right) + 11:tree:right/:$(git rev-parse base~1:right) + 11:tree:right/:$(git rev-parse base~2:right) + 12:blob:right/c:$(git rev-parse base~2:right/c) + 12:blob:right/c:$(git rev-parse topic:right/c) + 13:blob:right/d:$(git rev-parse base~1:right/d) + blobs:10 + commits:4 + tags:7 + trees:13 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'indexed objects' ' + test_when_finished git reset --hard && + + # stage change into index, adding a blob but + # also invalidating the cache-tree for the root + # and the "left" directory. + echo bogus >left/c && + git add left && + + test-tool path-walk -- --indexed-objects >out && + + cat >expect <<-EOF && + 0:blob:a:$(git rev-parse HEAD:a) + 1:blob:left/b:$(git rev-parse HEAD:left/b) + 2:blob:left/c:$(git rev-parse :left/c) + 3:blob:right/c:$(git rev-parse HEAD:right/c) + 4:blob:right/d:$(git rev-parse HEAD:right/d) + 5:tree:right/:$(git rev-parse topic:right) + blobs:5 + commits:0 + tags:0 + trees:1 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'branches and indexed objects mix well' ' + test_when_finished git reset --hard && + + # stage change into index, adding a blob but + # also invalidating the cache-tree for the root + # and the "right" directory. + echo fake >right/d && + git add right && + + test-tool path-walk -- --indexed-objects --branches >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 0:commit::$(git rev-parse base) + 0:commit::$(git rev-parse base~1) + 0:commit::$(git rev-parse base~2) + 1:tree::$(git rev-parse topic^{tree}) + 1:tree::$(git rev-parse base^{tree}) + 1:tree::$(git rev-parse base~1^{tree}) + 1:tree::$(git rev-parse base~2^{tree}) + 2:tree:a/:$(git rev-parse refs/tags/third:a) + 3:tree:left/:$(git rev-parse base:left) + 3:tree:left/:$(git rev-parse base~2:left) + 4:blob:left/b:$(git rev-parse base:left/b) + 4:blob:left/b:$(git rev-parse base~2:left/b) + 5:tree:right/:$(git rev-parse topic:right) + 5:tree:right/:$(git rev-parse base~1:right) + 5:tree:right/:$(git rev-parse base~2:right) + 6:blob:right/c:$(git rev-parse base~2:right/c) + 6:blob:right/c:$(git rev-parse topic:right/c) + 7:blob:right/d:$(git rev-parse base~1:right/d) + 7:blob:right/d:$(git rev-parse :right/d) + 8:blob:a:$(git rev-parse base~2:a) + blobs:7 + commits:4 + tags:0 + trees:10 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'base & topic, sparse' ' + cat >patterns <<-EOF && + /* + !/*/ + /left/ + EOF + + test-tool path-walk --stdin-pl -- base topic <patterns >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 0:commit::$(git rev-parse base) + 0:commit::$(git rev-parse base~1) + 0:commit::$(git rev-parse base~2) + 1:tree::$(git rev-parse topic^{tree}) + 1:tree::$(git rev-parse base^{tree}) + 1:tree::$(git rev-parse base~1^{tree}) + 1:tree::$(git rev-parse base~2^{tree}) + 2:blob:a:$(git rev-parse base~2:a) + 3:tree:left/:$(git rev-parse base:left) + 3:tree:left/:$(git rev-parse base~2:left) + 4:blob:left/b:$(git rev-parse base~2:left/b) + 4:blob:left/b:$(git rev-parse base:left/b) + blobs:3 + commits:4 + tags:0 + trees:6 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'topic only' ' + test-tool path-walk -- topic >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 0:commit::$(git rev-parse base~1) + 0:commit::$(git rev-parse base~2) + 1:tree::$(git rev-parse topic^{tree}) + 1:tree::$(git rev-parse base~1^{tree}) + 1:tree::$(git rev-parse base~2^{tree}) + 2:blob:a:$(git rev-parse base~2:a) + 3:tree:left/:$(git rev-parse base~2:left) + 4:blob:left/b:$(git rev-parse base~2:left/b) + 5:tree:right/:$(git rev-parse topic:right) + 5:tree:right/:$(git rev-parse base~1:right) + 5:tree:right/:$(git rev-parse base~2:right) + 6:blob:right/c:$(git rev-parse base~2:right/c) + 6:blob:right/c:$(git rev-parse topic:right/c) + 7:blob:right/d:$(git rev-parse base~1:right/d) + blobs:5 + commits:3 + tags:0 + trees:7 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'topic, not base' ' + test-tool path-walk -- topic --not base >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 1:tree::$(git rev-parse topic^{tree}) + 2:blob:a:$(git rev-parse topic:a):UNINTERESTING + 3:tree:left/:$(git rev-parse topic:left):UNINTERESTING + 4:blob:left/b:$(git rev-parse topic:left/b):UNINTERESTING + 5:tree:right/:$(git rev-parse topic:right) + 6:blob:right/c:$(git rev-parse topic:right/c) + 7:blob:right/d:$(git rev-parse topic:right/d):UNINTERESTING + blobs:4 + commits:1 + tags:0 + trees:3 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'fourth, blob-tag2, not base' ' + test-tool path-walk -- fourth blob-tag2 --not base >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 1:tag:/tags:$(git rev-parse fourth) + 2:blob:/tagged-blobs:$(git rev-parse refs/tags/blob-tag2^{}) + 3:tree::$(git rev-parse topic^{tree}) + 4:blob:a:$(git rev-parse base~1:a):UNINTERESTING + 5:tree:left/:$(git rev-parse base~1:left):UNINTERESTING + 6:blob:left/b:$(git rev-parse base~1:left/b):UNINTERESTING + 7:tree:right/:$(git rev-parse topic:right) + 8:blob:right/c:$(git rev-parse topic:right/c) + 9:blob:right/d:$(git rev-parse base~1:right/d):UNINTERESTING + blobs:5 + commits:1 + tags:1 + trees:3 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'topic, not base, only blobs' ' + test-tool path-walk --no-trees --no-commits \ + -- topic --not base >out && + + cat >expect <<-EOF && + 0:blob:a:$(git rev-parse topic:a):UNINTERESTING + 1:blob:left/b:$(git rev-parse topic:left/b):UNINTERESTING + 2:blob:right/c:$(git rev-parse topic:right/c) + 3:blob:right/d:$(git rev-parse topic:right/d):UNINTERESTING + blobs:4 + commits:0 + tags:0 + trees:0 + EOF + + test_cmp_sorted expect out +' + +# No, this doesn't make a lot of sense for the path-walk API, +# but it is possible to do. +test_expect_success 'topic, not base, only commits' ' + test-tool path-walk --no-blobs --no-trees \ + -- topic --not base >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + commits:1 + blobs:0 + tags:0 + trees:0 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'topic, not base, only trees' ' + test-tool path-walk --no-blobs --no-commits \ + -- topic --not base >out && + + cat >expect <<-EOF && + 0:tree::$(git rev-parse topic^{tree}) + 1:tree:left/:$(git rev-parse topic:left):UNINTERESTING + 2:tree:right/:$(git rev-parse topic:right) + commits:0 + blobs:0 + tags:0 + trees:3 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'topic, not base, boundary' ' + test-tool path-walk -- --boundary topic --not base >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 0:commit::$(git rev-parse base~1):UNINTERESTING + 1:tree::$(git rev-parse topic^{tree}) + 1:tree::$(git rev-parse base~1^{tree}):UNINTERESTING + 2:blob:a:$(git rev-parse base~1:a):UNINTERESTING + 3:tree:left/:$(git rev-parse base~1:left):UNINTERESTING + 4:blob:left/b:$(git rev-parse base~1:left/b):UNINTERESTING + 5:tree:right/:$(git rev-parse topic:right) + 5:tree:right/:$(git rev-parse base~1:right):UNINTERESTING + 6:blob:right/c:$(git rev-parse base~1:right/c):UNINTERESTING + 6:blob:right/c:$(git rev-parse topic:right/c) + 7:blob:right/d:$(git rev-parse base~1:right/d):UNINTERESTING + blobs:5 + commits:2 + tags:0 + trees:5 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'topic, not base, boundary with pruning' ' + test-tool path-walk --prune -- --boundary topic --not base >out && + + cat >expect <<-EOF && + 0:commit::$(git rev-parse topic) + 0:commit::$(git rev-parse base~1):UNINTERESTING + 1:tree::$(git rev-parse topic^{tree}) + 1:tree::$(git rev-parse base~1^{tree}):UNINTERESTING + 2:tree:right/:$(git rev-parse topic:right) + 2:tree:right/:$(git rev-parse base~1:right):UNINTERESTING + 3:blob:right/c:$(git rev-parse base~1:right/c):UNINTERESTING + 3:blob:right/c:$(git rev-parse topic:right/c) + blobs:2 + commits:2 + tags:0 + trees:4 + EOF + + test_cmp_sorted expect out +' + +test_expect_success 'trees are reported exactly once' ' + test_when_finished "rm -rf unique-trees" && + test_create_repo unique-trees && + ( + cd unique-trees && + mkdir initial && + test_commit initial/file && + git switch -c move-to-top && + git mv initial/file.t ./ && + test_tick && + git commit -m moved && + git update-ref refs/heads/other HEAD + ) && + test-tool -C unique-trees path-walk -- --all >out && + tree=$(git -C unique-trees rev-parse HEAD:) && + grep "$tree" out >out-filtered && + test_line_count = 1 out-filtered +' + +test_done diff --git a/t/t6700-tree-depth.sh b/t/t6700-tree-depth.sh index 9e70a7c763a210..0f6a2ad9b593f4 100755 --- a/t/t6700-tree-depth.sh +++ b/t/t6700-tree-depth.sh @@ -2,7 +2,6 @@ test_description='handling of deep trees in various commands' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # We'll test against two depths here: a small one that will let us check the diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 86258f9f4307a3..25334b506228f0 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -2,7 +2,6 @@ test_description='git mv in subdirs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-data.sh @@ -551,4 +550,16 @@ test_expect_success 'moving nested submodules' ' git status ' +test_expect_failure 'nonsense mv triggers assertion failure and partially updated index' ' + test_when_finished git reset --hard HEAD && + git reset --hard HEAD && + mkdir -p a && + mkdir -p b && + >a/a.txt && + git add a/a.txt && + test_must_fail git mv a/a.txt a b && + git status --porcelain >actual && + grep "^A[ ]*a/a.txt$" actual +' + test_done diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh index 57969ce805a548..4d3f221224fb39 100755 --- a/t/t7002-mv-sparse-checkout.sh +++ b/t/t7002-mv-sparse-checkout.sh @@ -2,7 +2,6 @@ test_description='git mv in sparse working trees' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_sparse_checkout () { @@ -33,7 +32,7 @@ test_expect_success 'setup' " hint: If you intend to update such entries, try one of the following: hint: * Use the --sparse option. hint: * Disable or modify the sparsity rules. - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF cat >dirty_error_header <<-EOF && @@ -46,7 +45,7 @@ test_expect_success 'setup' " hint: To correct the sparsity of these paths, do the following: hint: * Use \"git add --sparse <paths>\" to update the index hint: * Use \"git sparse-checkout reapply\" to apply the sparsity rules - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF " diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index b1316e62f46ded..10835631ca7644 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -91,6 +91,18 @@ test_expect_success 'creating a tag using default HEAD should succeed' ' test_must_fail git reflog exists refs/tags/mytag ' +test_expect_success 'HEAD is forbidden as a tagname' ' + test_when_finished "git update-ref --no-deref -d refs/tags/HEAD || :" && + test_must_fail git tag HEAD && + test_must_fail git tag -a -m "useless" HEAD +' + +test_expect_success '"git tag" can remove a tag named HEAD' ' + test_when_finished "git update-ref --no-deref -d refs/tags/HEAD || :" && + git update-ref refs/tags/HEAD HEAD && + git tag -d HEAD +' + test_expect_success 'creating a tag with --create-reflog should create reflog' ' git log -1 \ --format="format:tag: tagging %h (%s, %cd)%n" \ @@ -1850,7 +1862,7 @@ test_expect_success 'recursive tagging should give advice' ' hint: already a tag. If you meant to tag the object that it points to, use: hint: hint: git tag -f nested annotated-v4.0^{} - hint: Disable this message with "git config advice.nestedTag false" + hint: Disable this message with "git config set advice.nestedTag false" EOF git tag -m nested nested annotated-v4.0 2>actual && test_cmp expect actual diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index b9822294fedb7c..5fcf281dfbf8d6 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -2,7 +2,6 @@ test_description='GIT_EDITOR, core.editor, and stuff' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh unset EDITOR VISUAL GIT_EDITOR diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index a0296d6ca4019e..932c26cb45b6e3 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -2,7 +2,6 @@ test_description='Test automatic use of a pager.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pager.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t7007-show.sh b/t/t7007-show.sh index f908a4d1abc5dc..d6cc69e0f2cbd5 100755 --- a/t/t7007-show.sh +++ b/t/t7007-show.sh @@ -2,7 +2,6 @@ test_description='git show' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7008-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh index 0ce8fd2c895dda..93fbc92b8dbc29 100755 --- a/t/t7008-filter-branch-null-sha1.sh +++ b/t/t7008-filter-branch-null-sha1.sh @@ -2,7 +2,6 @@ test_description='filter-branch removal of trees with null sha1' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: base commits' ' diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh index d9add2162e9c64..520f96d09fb717 100755 --- a/t/t7010-setup.sh +++ b/t/t7010-setup.sh @@ -2,7 +2,6 @@ test_description='setup taking and sanitizing funny paths' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh index 4adac5acd57c56..1ff2714cb49908 100755 --- a/t/t7011-skip-worktree-reading.sh +++ b/t/t7011-skip-worktree-reading.sh @@ -5,7 +5,6 @@ test_description='skip-worktree bit test' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect.full <<EOF @@ -32,24 +31,24 @@ setup_absent() { } test_absent() { - echo "100644 $EMPTY_BLOB 0 1" > expected && - git ls-files --stage 1 > result && + echo "100644 $EMPTY_BLOB 0 1" >expected && + git ls-files --stage 1 >result && test_cmp expected result && test ! -f 1 } setup_dirty() { git update-index --force-remove 1 && - echo dirty > 1 && + echo dirty >1 && git update-index --add --cacheinfo 100644 $EMPTY_BLOB 1 && git update-index --skip-worktree 1 } test_dirty() { - echo "100644 $EMPTY_BLOB 0 1" > expected && - git ls-files --stage 1 > result && + echo "100644 $EMPTY_BLOB 0 1" >expected && + git ls-files --stage 1 >result && test_cmp expected result && - echo dirty > expected + echo dirty >expected test_cmp expected 1 } @@ -59,7 +58,7 @@ test_expect_success 'setup' ' touch ./1 ./2 sub/1 sub/2 && git add 1 2 sub/1 sub/2 && git update-index --skip-worktree 1 sub/1 && - git ls-files -t > result && + git ls-files -t >result && test_cmp expect.skip result ' @@ -86,7 +85,7 @@ test_expect_success 'update-index --remove' ' setup_dirty && git update-index --remove 1 && test -z "$(git ls-files 1)" && - echo dirty > expected && + echo dirty >expected && test_cmp expected 1 ' @@ -110,16 +109,16 @@ test_expect_success 'ls-files --modified' ' test -z "$(git ls-files -m)" ' -echo ":000000 100644 $ZERO_OID $EMPTY_BLOB A 1" > expected +echo ":000000 100644 $ZERO_OID $EMPTY_BLOB A 1" >expected test_expect_success 'diff-index does not examine skip-worktree absent entries' ' setup_absent && - git diff-index HEAD -- 1 > result && + git diff-index HEAD -- 1 >result && test_cmp expected result ' test_expect_success 'diff-index does not examine skip-worktree dirty entries' ' setup_dirty && - git diff-index HEAD -- 1 > result && + git diff-index HEAD -- 1 >result && test_cmp expected result ' diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh index d984200c1733b5..cd5c20fe51b372 100755 --- a/t/t7012-skip-worktree-writing.sh +++ b/t/t7012-skip-worktree-writing.sh @@ -5,7 +5,6 @@ test_description='test worktree writing operations when skip-worktree is used' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh index effa826744bf58..6f526c37c2776e 100755 --- a/t/t7030-verify-tag.sh +++ b/t/t7030-verify-tag.sh @@ -4,7 +4,6 @@ test_description='signed tag tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-gpg.sh" diff --git a/t/t7031-verify-tag-signed-ssh.sh b/t/t7031-verify-tag-signed-ssh.sh index 20913b37134426..80359d48f7ca19 100755 --- a/t/t7031-verify-tag-signed-ssh.sh +++ b/t/t7031-verify-tag-signed-ssh.sh @@ -116,7 +116,7 @@ test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag succeeds with tag date ! grep "${GPGSSH_BAD_SIGNATURE}" actual ' -test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag failes with tag date outside of key validity' ' +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag fails with tag date outside of key validity' ' test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && test_must_fail git verify-tag timeboxedinvalid-signed 2>actual && ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh index aaeb4a533440df..0f4344c55e6421 100755 --- a/t/t7060-wtstatus.sh +++ b/t/t7060-wtstatus.sh @@ -5,7 +5,6 @@ test_description='basic work tree status reporting' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7062-wtstatus-ignorecase.sh b/t/t7062-wtstatus-ignorecase.sh index caf372a3d42ac3..73709dbeee2879 100755 --- a/t/t7062-wtstatus-ignorecase.sh +++ b/t/t7062-wtstatus-ignorecase.sh @@ -2,7 +2,6 @@ test_description='git-status with core.ignorecase=true' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'status with hash collisions' ' diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh index 06c130122236aa..8bbc5ce6d9886c 100755 --- a/t/t7064-wtstatus-pv2.sh +++ b/t/t7064-wtstatus-pv2.sh @@ -4,7 +4,6 @@ test_description='git status --porcelain=v2 This test exercises porcelain V2 output for git status.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh @@ -77,7 +76,7 @@ test_expect_success 'before initial commit, things added (-z)' ' test_cmp expect actual ' -test_expect_success 'make first commit, comfirm HEAD oid and branch' ' +test_expect_success 'make first commit, confirm HEAD oid and branch' ' git commit -m initial && H0=$(git rev-parse HEAD) && cat >expect <<-EOF && diff --git a/t/t7101-reset-empty-subdirs.sh b/t/t7101-reset-empty-subdirs.sh index 89cf98b30c8f96..33d5d5b76e7d17 100755 --- a/t/t7101-reset-empty-subdirs.sh +++ b/t/t7101-reset-empty-subdirs.sh @@ -5,7 +5,6 @@ test_description='git reset should cull empty subdirs' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-data.sh diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 2add26d76844de..0503a64d3f23cb 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -10,24 +10,33 @@ Documented tests for git reset' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -commit_msg () { - # String "modify 2nd file (changed)" partly in German - # (translated with Google Translate), - # encoded in UTF-8, used as a commit log message below. - msg="modify 2nd file (ge\303\244ndert)\n" - if test -n "$1" - then - printf "$msg" | iconv -f utf-8 -t "$1" - else - printf "$msg" - fi -} - -# Tested non-UTF-8 encoding -test_encoding="ISO8859-1" +if test_have_prereq ICONV +then + commit_msg () { + # String "modify 2nd file (changed)" partly in German + # (translated with Google Translate), + # encoded in UTF-8, used as a commit log message below. + msg="modify 2nd file (ge\303\244ndert)\n" + if test -n "$1" + then + printf "$msg" | iconv -f utf-8 -t "$1" + else + printf "$msg" + fi + } + + # Tested non-UTF-8 encoding + test_encoding="ISO8859-1" +else + commit_msg () { + echo "modify 2nd file (geandert)" + } + + # Tested non-UTF-8 encoding + test_encoding="UTF-8" +fi test_expect_success 'creating initial files and commits' ' test_tick && diff --git a/t/t7103-reset-bare.sh b/t/t7103-reset-bare.sh index 18bbd9975ebfda..871e438118a4bc 100755 --- a/t/t7103-reset-bare.sh +++ b/t/t7103-reset-bare.sh @@ -2,7 +2,6 @@ test_description='git reset in a bare repository' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup non-bare' ' diff --git a/t/t7104-reset-hard.sh b/t/t7104-reset-hard.sh index cf9697eba9a6ae..7948ec392b3599 100755 --- a/t/t7104-reset-hard.sh +++ b/t/t7104-reset-hard.sh @@ -2,7 +2,6 @@ test_description='reset --hard unmerged' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index f4f3b7a677aa16..fced8adabd4795 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -2,7 +2,6 @@ test_description='git reset --patch' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-patch-mode.sh test_expect_success 'setup' ' diff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh index 88d1c8adf42eec..df20c0f0ccd210 100755 --- a/t/t7106-reset-unborn-branch.sh +++ b/t/t7106-reset-unborn-branch.sh @@ -2,7 +2,6 @@ test_description='git reset should work on unborn branch' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh index 020db201d57c3c..9162f591fb2b86 100755 --- a/t/t7107-reset-pathspec-file.sh +++ b/t/t7107-reset-pathspec-file.sh @@ -2,7 +2,6 @@ test_description='reset --pathspec-from-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh index 7ee180f81da4f9..9a335071af6c0d 100755 --- a/t/t7110-reset-merge.sh +++ b/t/t7110-reset-merge.sh @@ -5,7 +5,6 @@ test_description='Tests for "git reset" with "--merge" and "--keep" options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -271,13 +270,13 @@ test_expect_success '--merge is ok with added/deleted merge' ' git reset --hard third && rm -f file2 && test_must_fail git merge branch3 && - ! test -f file2 && - test -f file3 && + test_path_is_missing file2 && + test_path_is_file file3 && git diff --exit-code file3 && git diff --exit-code branch3 file3 && git reset --merge HEAD && - ! test -f file3 && - ! test -f file2 && + test_path_is_missing file3 && + test_path_is_missing file2 && git diff --exit-code --cached ' @@ -285,8 +284,8 @@ test_expect_success '--keep fails with added/deleted merge' ' git reset --hard third && rm -f file2 && test_must_fail git merge branch3 && - ! test -f file2 && - test -f file3 && + test_path_is_missing file2 && + test_path_is_file file3 && git diff --exit-code file3 && git diff --exit-code branch3 file3 && test_must_fail git reset --keep HEAD 2>err.log && diff --git a/t/t7111-reset-table.sh b/t/t7111-reset-table.sh index 01b7c3503ca882..07b919731ae87a 100755 --- a/t/t7111-reset-table.sh +++ b/t/t7111-reset-table.sh @@ -5,7 +5,6 @@ test_description='Tests to check that "reset" options follow a known table' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t7112-reset-submodule.sh b/t/t7112-reset-submodule.sh index b0d3d93b0b48b1..a3e2413bc33953 100755 --- a/t/t7112-reset-submodule.sh +++ b/t/t7112-reset-submodule.sh @@ -2,7 +2,6 @@ test_description='reset can handle submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t7113-post-index-change-hook.sh b/t/t7113-post-index-change-hook.sh index 58e55a7c779161..c10d94fe3d3b01 100755 --- a/t/t7113-post-index-change-hook.sh +++ b/t/t7113-post-index-change-hook.sh @@ -5,7 +5,6 @@ test_description='post index change hook' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 2d984eb4c6a167..9bcf7c0b40461f 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -23,7 +23,6 @@ Test switching across them. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick @@ -225,7 +224,7 @@ test_expect_success 'switch to another branch while carrying a deletion' ' ' test_expect_success 'checkout to detach HEAD (with advice declined)' ' - git config advice.detachedHead false && + git config set advice.detachedHead false && rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && @@ -245,7 +244,7 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' ' ' test_expect_success 'checkout to detach HEAD' ' - git config advice.detachedHead true && + git config set advice.detachedHead true && rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 0aae0dee67078b..00d4070156243b 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -5,7 +5,6 @@ test_description='git clean basic tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh git config clean.requireForce no @@ -29,15 +28,15 @@ test_expect_success 'git clean with skip-worktree .gitignore' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so && + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so && git update-index --no-skip-worktree .gitignore && git checkout .gitignore ' @@ -47,15 +46,15 @@ test_expect_success 'git clean' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -64,15 +63,15 @@ test_expect_success 'git clean src/' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean src/ && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -81,15 +80,15 @@ test_expect_success 'git clean src/ src/' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean src/ src/ && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -98,16 +97,16 @@ test_expect_success 'git clean with prefix' ' mkdir -p build docs src/test && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so src/test/1.c && (cd src/ && git clean) && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test ! -f src/part3.c && - test -f src/test/1.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_missing src/part3.c && + test_path_is_file src/test/1.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -163,16 +162,16 @@ test_expect_success 'git clean -d with prefix and path' ' mkdir -p build docs src/feature && touch a.out src/part3.c src/feature/file.c docs/manual.txt obj.o build/lib.so && (cd src/ && git clean -d feature/) && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test -f src/part3.c && - test ! -f src/feature/file.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_file src/part3.c && + test_path_is_missing src/feature/file.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -182,16 +181,16 @@ test_expect_success SYMLINKS 'git clean symbolic link' ' touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && ln -s docs/manual.txt src/part4.c && git clean && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test ! -f src/part4.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_missing src/part4.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -199,13 +198,13 @@ test_expect_success 'git clean with wildcard' ' touch a.clean b.clean other.c && git clean "*.clean" && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.clean && - test ! -f b.clean && - test -f other.c + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.clean && + test_path_is_missing b.clean && + test_path_is_file other.c ' @@ -214,15 +213,15 @@ test_expect_success 'git clean -n' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -n && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_file src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -231,15 +230,15 @@ test_expect_success 'git clean -d' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -d && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test ! -d docs && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_missing docs && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -248,16 +247,16 @@ test_expect_success 'git clean -d src/ examples/' ' mkdir -p build docs examples && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so examples/1.c && git clean -d src/ examples/ && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test ! -f src/part3.c && - test ! -f examples/1.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_missing src/part3.c && + test_path_is_missing examples/1.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -266,15 +265,15 @@ test_expect_success 'git clean -x' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -x && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test ! -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_missing obj.o && + test_path_is_file build/lib.so ' @@ -283,15 +282,15 @@ test_expect_success 'git clean -d -x' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -d -x && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test ! -d docs && - test ! -f obj.o && - test ! -d build + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_missing docs && + test_path_is_missing obj.o && + test_path_is_missing build ' @@ -300,15 +299,15 @@ test_expect_success 'git clean -d -x with ignored tracked directory' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -d -x -e src && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test -f src/part3.c && - test ! -d docs && - test ! -f obj.o && - test ! -d build + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_file src/part3.c && + test_path_is_missing docs && + test_path_is_missing obj.o && + test_path_is_missing build ' @@ -317,15 +316,15 @@ test_expect_success 'git clean -X' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -X && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test -f src/part3.c && - test -f docs/manual.txt && - test ! -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_file src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_missing obj.o && + test_path_is_file build/lib.so ' @@ -334,15 +333,15 @@ test_expect_success 'git clean -d -X' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -d -X && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test -f src/part3.c && - test -f docs/manual.txt && - test ! -f obj.o && - test ! -d build + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_file src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_missing obj.o && + test_path_is_missing build ' @@ -351,15 +350,15 @@ test_expect_success 'git clean -d -X with ignored tracked directory' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -d -X -e src && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test ! -f obj.o && - test ! -d build + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_missing obj.o && + test_path_is_missing build ' @@ -382,29 +381,29 @@ test_expect_success 'clean.requireForce and -n' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && git clean -n && - test -f Makefile && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test -f a.out && - test -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file Makefile && + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_file a.out && + test_path_is_file src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' test_expect_success 'clean.requireForce and -f' ' git clean -f && - test -f README && - test -f src/part1.c && - test -f src/part2.c && - test ! -f a.out && - test ! -f src/part3.c && - test -f docs/manual.txt && - test -f obj.o && - test -f build/lib.so + test_path_is_file README && + test_path_is_file src/part1.c && + test_path_is_file src/part2.c && + test_path_is_missing a.out && + test_path_is_missing src/part3.c && + test_path_is_file docs/manual.txt && + test_path_is_file obj.o && + test_path_is_file build/lib.so ' @@ -453,11 +452,11 @@ test_expect_success 'nested git work tree' ' test_commit deeply.nested deeper.world ) && git clean -f -d && - test -f foo/.git/index && - test -f foo/hello.world && - test -f baz/boo/.git/index && - test -f baz/boo/deeper.world && - ! test -d bar + test_path_is_file foo/.git/index && + test_path_is_file foo/hello.world && + test_path_is_file baz/boo/.git/index && + test_path_is_file baz/boo/deeper.world && + test_path_is_missing bar ' test_expect_success 'should clean things that almost look like git but are not' ' @@ -624,9 +623,9 @@ test_expect_success 'force removal of nested git work tree' ' test_commit deeply.nested deeper.world ) && git clean -f -f -d && - ! test -d foo && - ! test -d bar && - ! test -d baz + test_path_is_missing foo && + test_path_is_missing bar && + test_path_is_missing baz ' test_expect_success 'git clean -e' ' @@ -638,10 +637,10 @@ test_expect_success 'git clean -e' ' touch known 1 2 3 && git add known && git clean -f -e 1 -e 2 && - test -e 1 && - test -e 2 && - ! (test -e 3) && - test -e known + test_path_exists 1 && + test_path_exists 2 && + test_path_is_missing 3 && + test_path_exists known ) ' @@ -649,7 +648,7 @@ test_expect_success SANITY 'git clean -d with an unreadable empty directory' ' mkdir foo && chmod a= foo && git clean -dfx foo && - ! test -d foo + test_path_is_missing foo ' test_expect_success 'git clean -d respects pathspecs (dir is prefix of pathspec)' ' @@ -747,7 +746,7 @@ test_expect_success MINGW 'handle clean & core.longpaths = false nicely' ' test_must_fail git clean -xdf 2>.git/err && # grepping for a strerror string is unportable but it is OK here with # MINGW prereq - test_grep "too long" .git/err + test_grep -e "too long" -e "No such file or directory" .git/err ' test_expect_success 'clean untracked paths by pathspec' ' diff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh index 4afe53c66ae57a..f743e5b8f44e79 100755 --- a/t/t7301-clean-interactive.sh +++ b/t/t7301-clean-interactive.sh @@ -2,7 +2,6 @@ test_description='git clean -i basic tests' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 098d8833b6599d..d6a501d4535417 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -12,7 +12,6 @@ subcommands of git submodule. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup - enable local submodules' ' @@ -213,7 +212,7 @@ test_expect_success 'submodule add to .gitignored path fails' ' The following paths are ignored by one of your .gitignore files: submod hint: Use -f if you really want to add them. - hint: Disable this message with "git config advice.addIgnoredFile false" + hint: Disable this message with "git config set advice.addIgnoredFile false" EOF # Does not use test_commit due to the ignore echo "*" > .gitignore && diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 542b3331a78f4d..9c3cc4cf4046be 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -17,7 +17,6 @@ This test script tries to verify the sanity of summary subcommand of git submodu # various reasons, one of them being that there are lots of commands taking place # outside of 'test_expect_success' block, which is no longer in good-style. -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh add_file () { diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh index aa2fdc31d1a672..25b33a1e8753b4 100755 --- a/t/t7402-submodule-rebase.sh +++ b/t/t7402-submodule-rebase.sh @@ -5,7 +5,6 @@ test_description='Test rebasing, stashing, etc. with submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 19b6135d117440..bf97d4f851134a 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -11,7 +11,6 @@ These tests exercise the "git submodule sync" subcommand. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 297c6c3b5cc4b8..c562bad042ab2d 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -1093,7 +1093,9 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s ) && git clone super4 super5 && (cd super5 && - git submodule update --quiet --init --depth=1 submodule3 >out 2>err && + # This test var can mess with the stderr output checked in this test. + GIT_TEST_NAME_HASH_VERSION=1 \ + git submodule update --quiet --init --depth=1 submodule3 >out 2>err && test_must_be_empty out && test_must_be_empty err ) && diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 8d7b234beb8b09..77b6d0040e8a8f 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -426,14 +426,14 @@ test_expect_success 'option-like arguments passed to foreach commands are not lo git submodule foreach "echo be --quiet" > ../expected && git submodule foreach echo be --quiet > ../actual ) && - grep -sq -e "--quiet" expected && + test_grep -e "--quiet" expected && test_cmp expected actual ' test_expect_success 'option-like arguments passed to foreach recurse correctly' ' git -C clone2 submodule foreach --recursive "echo be --an-option" >expect && git -C clone2 submodule foreach --recursive echo be --an-option >actual && - grep -e "--an-option" expect && + test_grep -e "--an-option" expect && test_cmp expect actual ' diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh index d6040e0a337033..f860e7bbf49f46 100755 --- a/t/t7408-submodule-reference.sh +++ b/t/t7408-submodule-reference.sh @@ -4,6 +4,7 @@ # test_description='test clone --reference' + . ./test-lib.sh base_dir=$(pwd) diff --git a/t/t7409-submodule-detached-work-tree.sh b/t/t7409-submodule-detached-work-tree.sh index 574a6fc526ea0c..374ed481e9c64b 100755 --- a/t/t7409-submodule-detached-work-tree.sh +++ b/t/t7409-submodule-detached-work-tree.sh @@ -13,7 +13,6 @@ TEST_NO_CREATE_REPO=1 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh index f7783218576558..0490499573fd39 100755 --- a/t/t7412-submodule-absorbgitdirs.sh +++ b/t/t7412-submodule-absorbgitdirs.sh @@ -6,7 +6,6 @@ This test verifies that `git submodue absorbgitdirs` moves a submodules git directory into the superproject. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a real submodule' ' diff --git a/t/t7413-submodule-is-active.sh b/t/t7413-submodule-is-active.sh index 887d181b72ec05..9509dc18fde909 100755 --- a/t/t7413-submodule-is-active.sh +++ b/t/t7413-submodule-is-active.sh @@ -9,7 +9,6 @@ This is a unit test of the submodule.c is_submodule_active() function, which is also indirectly tested elsewhere. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -22,7 +21,7 @@ test_expect_success 'setup' ' git -C super submodule add ../sub sub2 && # Remove submodule.<name>.active entries in order to test in an - # environment where only URLs are present in the conifg + # environment where only URLs are present in the config git -C super config --unset submodule.sub1.active && git -C super config --unset submodule.sub2.active && diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh index 24f30e3bf9c644..e2d75c7f16c6ab 100755 --- a/t/t7414-submodule-mistakes.sh +++ b/t/t7414-submodule-mistakes.sh @@ -2,7 +2,6 @@ test_description='handling of common mistakes people may make with submodules' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create embedded repository' ' diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh index 2ab566e71787ab..0c605fd271a696 100755 --- a/t/t7416-submodule-dash-url.sh +++ b/t/t7416-submodule-dash-url.sh @@ -2,7 +2,6 @@ test_description='check handling of disallowed .gitmodule urls' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh index dbbb3853dc0853..5e3051da8bb362 100755 --- a/t/t7417-submodule-path-url.sh +++ b/t/t7417-submodule-path-url.sh @@ -4,7 +4,6 @@ test_description='check handling of .gitmodule path with dash' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7418-submodule-sparse-gitmodules.sh b/t/t7418-submodule-sparse-gitmodules.sh index e1d9bf2ee30d0c..dde11ecce806c4 100755 --- a/t/t7418-submodule-sparse-gitmodules.sh +++ b/t/t7418-submodule-sparse-gitmodules.sh @@ -15,7 +15,6 @@ also by committing .gitmodules and then just removing it from the filesystem. GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh index a5d1bc5c54ae09..08ed51d34ff543 100755 --- a/t/t7419-submodule-set-branch.sh +++ b/t/t7419-submodule-set-branch.sh @@ -9,7 +9,6 @@ This test verifies that the set-branch subcommand of git-submodule is working as expected. ' -TEST_PASSES_SANITIZE_LEAK=true TEST_NO_CREATE_REPO=1 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh index 479c8fdde1180b..ce64d8b1372173 100755 --- a/t/t7421-submodule-summary-add.sh +++ b/t/t7421-submodule-summary-add.sh @@ -10,7 +10,6 @@ while making sure to add submodules using `git submodule add` instead of `git add` as done in t7401. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7422-submodule-output.sh b/t/t7422-submodule-output.sh index c1686d6bb5f6f0..023a5cbdc44bac 100755 --- a/t/t7422-submodule-output.sh +++ b/t/t7422-submodule-output.sh @@ -2,7 +2,6 @@ test_description='submodule --cached, --quiet etc. output' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t3100.sh @@ -168,10 +167,45 @@ do done test_expect_success !MINGW 'git submodule status --recursive propagates SIGPIPE' ' - { git submodule status --recursive 2>err; echo $?>status; } | - grep -q X/S && - test_must_be_empty err && - test_match_signal 13 "$(cat status)" + # The test setup is somewhat involved because triggering a SIGPIPE is + # racy with buffered pipes. To avoid the raciness we thus need to make + # sure that the subprocess in question fills the buffers completely, + # which requires a couple thousand submodules in total. + test_when_finished "rm -rf submodule repo" && + git init submodule && + ( + cd submodule && + test_commit initial && + + COMMIT=$(git rev-parse HEAD) && + for i in $(test_seq 2000) + do + printf "[submodule \"sm-$i\"]\npath = recursive-submodule-path-$i\n" "$i" || + return 1 + done >gitmodules && + BLOB=$(git hash-object -w --stdin <gitmodules) && + + printf "100644 blob $BLOB\t.gitmodules\n" >tree && + for i in $(test_seq 2000) + do + printf "160000 commit $COMMIT\trecursive-submodule-path-%d\n" "$i" || + return 1 + done >>tree && + TREE=$(git mktree <tree) && + + COMMIT=$(git commit-tree "$TREE") && + git reset --hard "$COMMIT" + ) && + + git init repo && + ( + cd repo && + GIT_ALLOW_PROTOCOL=file git submodule add "$(pwd)"/../submodule && + { git submodule status --recursive 2>err; echo $?>status; } | + grep -q recursive-submodule-path-1 && + test_must_be_empty err && + test_match_signal 13 "$(cat status)" + ) ' test_done diff --git a/t/t7423-submodule-symlinks.sh b/t/t7423-submodule-symlinks.sh index f45d80620185b2..3d3c7af3ce520a 100755 --- a/t/t7423-submodule-symlinks.sh +++ b/t/t7423-submodule-symlinks.sh @@ -2,7 +2,6 @@ test_description='check that submodule operations do not follow symlinks' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare' ' diff --git a/t/t7424-submodule-mixed-ref-formats.sh b/t/t7424-submodule-mixed-ref-formats.sh index b43ef2ba675b8d..559713b60773a4 100755 --- a/t/t7424-submodule-mixed-ref-formats.sh +++ b/t/t7424-submodule-mixed-ref-formats.sh @@ -2,7 +2,6 @@ test_description='submodules handle mixed ref storage formats' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_ref_format () { diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh index 4a9c22c9e2b627..93677946411bac 100755 --- a/t/t7450-bad-git-dotfiles.sh +++ b/t/t7450-bad-git-dotfiles.sh @@ -13,7 +13,6 @@ Such as: - symlinked .gitmodules, etc ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh diff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh index 52f5e28154e2ff..cc12f99f11534b 100755 --- a/t/t7501-commit-basic-functionality.sh +++ b/t/t7501-commit-basic-functionality.sh @@ -9,7 +9,6 @@ test_description='git commit' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-diff.sh" diff --git a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh index aa004b70a8d1f1..ad1eb64ba0db16 100755 --- a/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh +++ b/t/t7503-pre-commit-and-pre-merge-commit-hooks.sh @@ -5,7 +5,6 @@ test_description='pre-commit and pre-merge-commit hooks' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'root commit' ' diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh index d1255228d5ffaa..c0f024eb1ef4e9 100755 --- a/t/t7504-commit-msg-hook.sh +++ b/t/t7504-commit-msg-hook.sh @@ -5,7 +5,6 @@ test_description='commit-msg hook' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'with no hook' ' diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh index b88383df9e48e1..2128142a61c60d 100755 --- a/t/t7505-prepare-commit-msg-hook.sh +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -5,7 +5,6 @@ test_description='prepare-commit-msg hook' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up commits for rebasing' ' diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index 46566d529e8725..185fe7e78efc32 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -2,7 +2,6 @@ test_description='git status for submodule' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_create_repo_with_commit () { diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh index 4c7db19ce7eff0..b53d71c0862396 100755 --- a/t/t7507-commit-verbose.sh +++ b/t/t7507-commit-verbose.sh @@ -2,7 +2,6 @@ test_description='verbose commit template' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh write_script "check-for-diff" <<\EOF && diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 773383fefb50a9..b2070d4e39f74d 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -5,7 +5,6 @@ test_description='git status' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -1700,7 +1699,7 @@ test_expect_success 'setup slow status advice' ' EOF git add .gitignore && git commit -m "Add .gitignore" && - git config advice.statusuoption true + git config set advice.statusuoption true ) ' diff --git a/t/t7509-commit-authorship.sh b/t/t7509-commit-authorship.sh index fd8c8f8f0bccf8..8e373b566b091d 100755 --- a/t/t7509-commit-authorship.sh +++ b/t/t7509-commit-authorship.sh @@ -5,7 +5,6 @@ test_description='commit tests of various authorhip options. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh author_header () { diff --git a/t/t7511-status-index.sh b/t/t7511-status-index.sh index 4ffa45a7bf3599..b5fdc048a54a15 100755 --- a/t/t7511-status-index.sh +++ b/t/t7511-status-index.sh @@ -2,7 +2,6 @@ test_description='git status with certain file name lengths' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh files="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z" diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index cdd5f2c6979388..802f8f704c62eb 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -10,7 +10,6 @@ test_description='git status advice' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh index 0f7d8938d984d9..818a8dafbd29e5 100755 --- a/t/t7513-interpret-trailers.sh +++ b/t/t7513-interpret-trailers.sh @@ -857,7 +857,7 @@ test_expect_success 'using "--where after" with "--no-where"' ' # the hardcoded default (in WHERE_END) assuming the absence of .gitconfig). # Here, the "start" setting of trailer.where is respected, so the new "Acked-by" # and "Bug" trailers are placed at the beginning, and not at the end which is -# the harcoded default. +# the hardcoded default. test_expect_success 'using "--where after" with "--no-where" defaults to configuration' ' test_config trailer.ack.key "Acked-by= " && test_config trailer.bug.key "Bug #" && @@ -881,7 +881,7 @@ test_expect_success 'using "--where after" with "--no-where" defaults to configu # immediately after it. For the next trailer (Bug #42), we default to using the # hardcoded WHERE_END because we don't have any "trailer.where" or # "trailer.bug.where" configured. -test_expect_success 'using "--no-where" defaults to harcoded default if nothing configured' ' +test_expect_success 'using "--no-where" defaults to hardcoded default if nothing configured' ' test_config trailer.ack.key "Acked-by= " && test_config trailer.bug.key "Bug #" && test_config trailer.separators ":=#" && diff --git a/t/t7514-commit-patch.sh b/t/t7514-commit-patch.sh index 03ba0c0e734e9b..075db69b429f5e 100755 --- a/t/t7514-commit-patch.sh +++ b/t/t7514-commit-patch.sh @@ -2,7 +2,6 @@ test_description='hunk edit with "commit -p -m"' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup (initial)' ' diff --git a/t/t7515-status-symlinks.sh b/t/t7515-status-symlinks.sh index e3d6bb67bf95a6..9f989be01b9f10 100755 --- a/t/t7515-status-symlinks.sh +++ b/t/t7515-status-symlinks.sh @@ -2,7 +2,6 @@ test_description='git status and symlinks' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh index bb95f09810b704..de7c4ca7901484 100755 --- a/t/t7516-commit-races.sh +++ b/t/t7516-commit-races.sh @@ -2,7 +2,6 @@ test_description='git commit races' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'race to create orphan commit' ' diff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh index efc6496e2b27f3..163ae8046850e7 100755 --- a/t/t7517-per-repo-email.sh +++ b/t/t7517-per-repo-email.sh @@ -9,7 +9,6 @@ test_description='per-repo forced setting of email address' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a likely user.useConfigOnly use case' ' diff --git a/t/t7518-ident-corner-cases.sh b/t/t7518-ident-corner-cases.sh index b37de0af49ff40..d3ea4d603ff871 100755 --- a/t/t7518-ident-corner-cases.sh +++ b/t/t7518-ident-corner-cases.sh @@ -2,7 +2,6 @@ test_description='corner cases in ident strings' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # confirm that we do not segfault _and_ that we do not say "(null)", as diff --git a/t/t7520-ignored-hook-warning.sh b/t/t7520-ignored-hook-warning.sh index 3b63c34a309de5..bcfe15d51d0706 100755 --- a/t/t7520-ignored-hook-warning.sh +++ b/t/t7520-ignored-hook-warning.sh @@ -2,7 +2,6 @@ test_description='ignored hook warning' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7524-commit-summary.sh b/t/t7524-commit-summary.sh index 47b2f1dc22a5cb..82b5e4aa412915 100755 --- a/t/t7524-commit-summary.sh +++ b/t/t7524-commit-summary.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='git commit summary' + . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7525-status-rename.sh b/t/t7525-status-rename.sh index a9210d3a3a9221..d409de1a33fd79 100755 --- a/t/t7525-status-rename.sh +++ b/t/t7525-status-rename.sh @@ -2,7 +2,6 @@ test_description='git status rename detection options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7526-commit-pathspec-file.sh b/t/t7526-commit-pathspec-file.sh index c97c550021e837..3aabbf35a1c172 100755 --- a/t/t7526-commit-pathspec-file.sh +++ b/t/t7526-commit-pathspec-file.sh @@ -2,7 +2,6 @@ test_description='commit --pathspec-from-file' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh index 730f3c7f81090e..409cd0cd121695 100755 --- a/t/t7527-builtin-fsmonitor.sh +++ b/t/t7527-builtin-fsmonitor.sh @@ -765,7 +765,7 @@ done # by the FSMonitor response to skip those recursive calls. That is, # even if FSMonitor says that the mtime of the submodule directory # hasn't changed and it could be implicitly marked valid, we must -# not take that shortcut. We need to force the recusion into the +# not take that shortcut. We need to force the recursion into the # submodule so that we get a summary of the status *within* the # submodule. @@ -907,6 +907,57 @@ test_expect_success "submodule absorbgitdirs implicitly starts daemon" ' test_subcommand git fsmonitor--daemon start <super-sub.trace ' +start_git_in_background () { + git "$@" & + git_pid=$! + git_pgid=$(ps -o pgid= -p $git_pid) + nr_tries_left=10 + while true + do + if test $nr_tries_left -eq 0 + then + kill -- -$git_pgid + exit 1 + fi + sleep 1 + nr_tries_left=$(($nr_tries_left - 1)) + done >/dev/null 2>&1 & + watchdog_pid=$! + wait $git_pid +} + +stop_git () { + while kill -0 -- -$git_pgid + do + kill -- -$git_pgid + sleep 1 + done +} + +stop_watchdog () { + while kill -0 $watchdog_pid + do + kill $watchdog_pid + sleep 1 + done +} + +test_expect_success !MINGW "submodule implicitly starts daemon by pull" ' + test_atexit "stop_watchdog" && + test_when_finished "stop_git; rm -rf cloned super sub" && + + create_super super && + create_sub sub && + + git -C super submodule add ../sub ./dir_1/dir_2/sub && + git -C super commit -m "add sub" && + git clone --recurse-submodules super cloned && + + git -C cloned/dir_1/dir_2/sub config core.fsmonitor true && + set -m && + start_git_in_background -C cloned pull --recurse-submodules +' + # On a case-insensitive file system, confirm that the daemon # notices when the .git directory is moved/renamed/deleted # regardless of how it is spelled in the FS event. diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 65fd3d8552b0fb..2a8df292196468 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -29,7 +29,6 @@ Testing basic merge operations/option parsing. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh @@ -174,7 +173,7 @@ test_expect_success 'merge -h with invalid index' ' cd broken && git init && >.git/index && - test_expect_code 129 git merge -h 2>usage + test_expect_code 129 git merge -h >usage ) && test_grep "[Uu]sage: git merge" broken/usage ' diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index a94387a75f2f48..199a1d5db31351 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -280,7 +280,7 @@ test_expect_success '--rebase overrides pull.ff unset' ' test_does_rebase pull --rebase ' -# Group 4: --no-rebase heeds pull.ff=!only or explict --ff or --no-ff +# Group 4: --no-rebase heeds pull.ff=!only or explicit --ff or --no-ff test_expect_success '--no-rebase works with --no-ff' ' test_does_merge_when_ff_possible pull --no-rebase --no-ff diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh index 3669d33bd5a15f..ff085b086cc38f 100755 --- a/t/t7602-merge-octopus-many.sh +++ b/t/t7602-merge-octopus-many.sh @@ -4,7 +4,6 @@ test_description='git merge Testing octopus merge with more than 25 refs.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7603-merge-reduce-heads.sh b/t/t7603-merge-reduce-heads.sh index 0e85b21ec82cc6..1f8c3b7ccbe6b1 100755 --- a/t/t7603-merge-reduce-heads.sh +++ b/t/t7603-merge-reduce-heads.sh @@ -4,7 +4,6 @@ test_description='git merge Testing octopus merge when reducing parents to independent branches.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # 0 - 1 @@ -53,12 +52,12 @@ test_expect_success 'merge c1 with c2, c3, c4, c5' ' test "$(git rev-parse c3)" = "$(git rev-parse HEAD^3)" && test "$(git rev-parse c5)" = "$(git rev-parse HEAD^4)" && git diff --exit-code && - test -f c0.c && - test -f c1.c && - test -f c2.c && - test -f c3.c && - test -f c4.c && - test -f c5.c && + test_path_is_file c0.c && + test_path_is_file c1.c && + test_path_is_file c2.c && + test_path_is_file c3.c && + test_path_is_file c4.c && + test_path_is_file c5.c && git show --format=%s -s >actual && ! grep c1 actual && grep c2 actual && @@ -76,12 +75,12 @@ test_expect_success 'pull c2, c3, c4, c5 into c1' ' test "$(git rev-parse c3)" = "$(git rev-parse HEAD^3)" && test "$(git rev-parse c5)" = "$(git rev-parse HEAD^4)" && git diff --exit-code && - test -f c0.c && - test -f c1.c && - test -f c2.c && - test -f c3.c && - test -f c4.c && - test -f c5.c && + test_path_is_file c0.c && + test_path_is_file c1.c && + test_path_is_file c2.c && + test_path_is_file c3.c && + test_path_is_file c4.c && + test_path_is_file c5.c && git show --format=%s -s >actual && ! grep c1 actual && grep c2 actual && diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index eca755510160be..cd4f9607dc13ce 100755 --- a/t/t7604-merge-custom-message.sh +++ b/t/t7604-merge-custom-message.sh @@ -4,7 +4,6 @@ test_description='git merge Testing merge when using a custom message for the merge commit.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_merge_msgs() { diff --git a/t/t7605-merge-resolve.sh b/t/t7605-merge-resolve.sh index 62d935d31c2e1d..5d56c3854647b2 100755 --- a/t/t7605-merge-resolve.sh +++ b/t/t7605-merge-resolve.sh @@ -4,7 +4,6 @@ test_description='git merge Testing the resolve strategy.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7606-merge-custom.sh b/t/t7606-merge-custom.sh index 135cb230856533..81fb7c474c14c1 100755 --- a/t/t7606-merge-custom.sh +++ b/t/t7606-merge-custom.sh @@ -14,7 +14,6 @@ Testing a custom strategy. * (tag: c0) c0 " -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up custom strategy' ' diff --git a/t/t7607-merge-state.sh b/t/t7607-merge-state.sh index 9001674f2ea220..89a62ac53b3d60 100755 --- a/t/t7607-merge-state.sh +++ b/t/t7607-merge-state.sh @@ -4,7 +4,6 @@ test_description="Test that merge state is as expected after failed merge" GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'Ensure we restore original state if no merge strategy handles it' ' diff --git a/t/t7608-merge-messages.sh b/t/t7608-merge-messages.sh index 2179938c437e47..0b908ab2e71280 100755 --- a/t/t7608-merge-messages.sh +++ b/t/t7608-merge-messages.sh @@ -4,7 +4,6 @@ test_description='test auto-generated merge messages' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_oneline() { diff --git a/t/t7609-mergetool--lib.sh b/t/t7609-mergetool--lib.sh index 8b1c3bd39f2249..af3ad284eeda00 100755 --- a/t/t7609-mergetool--lib.sh +++ b/t/t7609-mergetool--lib.sh @@ -4,11 +4,10 @@ test_description='git mergetool Testing basic merge tools options' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'mergetool --tool=vimdiff creates the expected layout' ' - . "$GIT_BUILD_DIR"/mergetools/vimdiff && + . "$GIT_SOURCE_DIR"/mergetools/vimdiff && run_unit_tests ' diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 22b3a85b3e960e..c077aba7cedde1 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -898,4 +898,12 @@ test_expect_success 'mergetool with guiDefault' ' git commit -m "branch1 resolved with mergetool" ' +test_expect_success 'mergetool with non-existent tool' ' + test_when_finished "git reset --hard" && + git checkout -b test$test_count branch1 && + test_must_fail git merge main && + yes "" | test_must_fail git mergetool --tool=absent >out 2>&1 && + test_grep "mergetool.absent.cmd not set for tool" out +' + test_done diff --git a/t/t7611-merge-abort.sh b/t/t7611-merge-abort.sh index 992a8f98749bae..1a251485e1b95c 100755 --- a/t/t7611-merge-abort.sh +++ b/t/t7611-merge-abort.sh @@ -25,7 +25,6 @@ Next, test git merge --abort with the following variables: GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -55,13 +54,13 @@ test_expect_success 'fails without MERGE_HEAD (unstarted merge)' ' ' test_expect_success 'fails without MERGE_HEAD (unstarted merge): .git/MERGE_HEAD sanity' ' - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" ' test_expect_success 'fails without MERGE_HEAD (completed merge)' ' git merge clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && # Merge successfully completed post_merge_head="$(git rev-parse HEAD)" && test_must_fail git merge --abort 2>output && @@ -69,7 +68,7 @@ test_expect_success 'fails without MERGE_HEAD (completed merge)' ' ' test_expect_success 'fails without MERGE_HEAD (completed merge): .git/MERGE_HEAD sanity' ' - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$post_merge_head" = "$(git rev-parse HEAD)" ' @@ -80,10 +79,10 @@ test_expect_success 'Forget previous merge' ' test_expect_success 'Abort after --no-commit' ' # Redo merge, but stop before creating merge commit git merge --no-commit clean_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort non-conflicting merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && test -z "$(git diff --staged)" @@ -92,10 +91,10 @@ test_expect_success 'Abort after --no-commit' ' test_expect_success 'Abort after conflicts' ' # Create conflicting merge test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort conflicting merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && test -z "$(git diff --staged)" @@ -106,7 +105,7 @@ test_expect_success 'Clean merge with dirty index fails' ' git add foo && git diff --staged > expect && test_must_fail git merge clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && git diff --staged > actual && @@ -115,7 +114,7 @@ test_expect_success 'Clean merge with dirty index fails' ' test_expect_success 'Conflicting merge with dirty index fails' ' test_must_fail git merge conflict_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && git diff --staged > actual && @@ -130,10 +129,10 @@ test_expect_success 'Reset index (but preserve worktree changes)' ' test_expect_success 'Abort clean merge with non-conflicting dirty worktree' ' git merge --no-commit clean_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -142,10 +141,10 @@ test_expect_success 'Abort clean merge with non-conflicting dirty worktree' ' test_expect_success 'Abort conflicting merge with non-conflicting dirty worktree' ' test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -160,7 +159,7 @@ test_expect_success 'Fail clean merge with conflicting dirty worktree' ' echo xyzzy >> bar && git diff > expect && test_must_fail git merge --no-commit clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -169,7 +168,7 @@ test_expect_success 'Fail clean merge with conflicting dirty worktree' ' test_expect_success 'Fail conflicting merge with conflicting dirty worktree' ' test_must_fail git merge conflict_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -184,7 +183,7 @@ test_expect_success 'Fail clean merge with matching dirty worktree' ' echo bart > bar && git diff > expect && test_must_fail git merge --no-commit clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -195,7 +194,7 @@ test_expect_success 'Fail conflicting merge with matching dirty worktree' ' echo barf > bar && git diff > expect && test_must_fail git merge conflict_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh index 84ddb568517cee..337fac0d8446f0 100755 --- a/t/t7612-merge-verify-signatures.sh +++ b/t/t7612-merge-verify-signatures.sh @@ -4,7 +4,6 @@ test_description='merge signature verification tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-gpg.sh" diff --git a/t/t7614-merge-signoff.sh b/t/t7614-merge-signoff.sh index cf96a35e8e7b20..fee258d4f0c2c0 100755 --- a/t/t7614-merge-signoff.sh +++ b/t/t7614-merge-signoff.sh @@ -8,7 +8,6 @@ This test runs git merge --signoff and makes sure that it works. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Setup test files diff --git a/t/t7615-diff-algo-with-mergy-operations.sh b/t/t7615-diff-algo-with-mergy-operations.sh index 9a83be518cb73b..3b1aad0167a402 100755 --- a/t/t7615-diff-algo-with-mergy-operations.sh +++ b/t/t7615-diff-algo-with-mergy-operations.sh @@ -4,7 +4,6 @@ test_description='git merge and other operations that rely on merge Testing the influence of the diff algorithm on the merge output.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index be1188e7365b19..611755cc139b96 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -308,7 +308,10 @@ test_expect_success 'no bitmaps created if .keep files present' ' keep=${pack%.pack}.keep && test_when_finished "rm -f \"\$keep\"" && >"$keep" && - git -C bare.git repack -ad 2>stderr && + + # Disable --name-hash-version test due to stderr comparison. + GIT_TEST_NAME_HASH_VERSION=1 \ + git -C bare.git repack -ad 2>stderr && test_must_be_empty stderr && find bare.git/objects/pack/ -type f -name "*.bitmap" >actual && test_must_be_empty actual @@ -319,7 +322,10 @@ test_expect_success 'auto-bitmaps do not complain if unavailable' ' blob=$(test-tool genrandom big $((1024*1024)) | git -C bare.git hash-object -w --stdin) && git -C bare.git update-ref refs/tags/big $blob && - git -C bare.git repack -ad 2>stderr && + + # Disable --name-hash-version test due to stderr comparison. + GIT_TEST_NAME_HASH_VERSION=1 \ + git -C bare.git repack -ad 2>stderr && test_must_be_empty stderr && find bare.git/objects/pack -type f -name "*.bitmap" >actual && test_must_be_empty actual @@ -776,6 +782,12 @@ test_expect_success 'repack -ad cleans up old .tmp-* packs' ' test_must_be_empty tmpfiles ' +test_expect_success '--name-hash-version option passes through to pack-objects' ' + GIT_TRACE2_EVENT="$(pwd)/hash-trace.txt" \ + git repack -a --name-hash-version=2 && + test_subcommand_flex git pack-objects --name-hash-version=2 <hash-trace.txt +' + test_expect_success 'setup for update-server-info' ' git init update-server-info && test_commit -C update-server-info message diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh index fe6c3e77a3c9ad..5559d4ccb429e0 100755 --- a/t/t7701-repack-unpack-unreachable.sh +++ b/t/t7701-repack-unpack-unreachable.sh @@ -5,7 +5,6 @@ test_description='git repack works correctly' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh fsha1= @@ -196,4 +195,20 @@ test_expect_success 'repack -k packs unreachable loose objects' ' git cat-file -p $sha1 ' +test_expect_success 'repack -k packs unreachable loose objects without existing packfiles' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + + oid=$(echo would-be-deleted-loose | git hash-object -w --stdin) && + objpath=.git/objects/$(echo $sha1 | sed "s,..,&/,") && + test_path_is_file $objpath && + + git repack -ad --keep-unreachable && + test_path_is_missing $objpath && + git cat-file -p $oid + ) +' + test_done diff --git a/t/t7702-repack-cyclic-alternate.sh b/t/t7702-repack-cyclic-alternate.sh index f3cdb98eec26b8..cd91766e78a77b 100755 --- a/t/t7702-repack-cyclic-alternate.sh +++ b/t/t7702-repack-cyclic-alternate.sh @@ -5,7 +5,6 @@ test_description='repack involving cyclic alternate' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -18,7 +17,7 @@ test_expect_success setup ' echo "$(pwd)"/.git/objects/../objects >.git/objects/info/alternates ' -test_expect_success 're-packing repository with itsself as alternate' ' +test_expect_success 're-packing repository with itself as alternate' ' git repack -adl && git fsck ' diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh index 8877aea98ba863..9fc1626fbfde89 100755 --- a/t/t7703-repack-geometric.sh +++ b/t/t7703-repack-geometric.sh @@ -2,7 +2,6 @@ test_description='git repack --geometric works correctly' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_TEST_MULTI_PACK_INDEX=0 diff --git a/t/t7704-repack-cruft.sh b/t/t7704-repack-cruft.sh index 5db9f4e10f75e9..959e6e2648897e 100755 --- a/t/t7704-repack-cruft.sh +++ b/t/t7704-repack-cruft.sh @@ -2,7 +2,6 @@ test_description='git repack works correctly' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh objdir=.git/objects diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index cc917b257e3bb8..9b74db55634b16 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -665,6 +665,10 @@ run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' ' test_cmp expect file ' +run_dir_diff_test 'difftool --dir-diff with no diff' ' + git difftool -d main main +' + write_script modify-file <<\EOF echo "new content" >file EOF diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index af2cf2f78ab890..64ac4f04ee97ad 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -87,6 +87,7 @@ test_expect_success setup ' # Still a no-op. function dummy() {} EOF + printf "\200\nASCII\n" >invalid-utf8 && if test_have_prereq FUNNYNAMES then echo unusual >"\"unusual\" pathname" && @@ -534,6 +535,14 @@ do test_cmp expected actual ' + test_expect_success "grep $L searches past invalid lines on UTF-8 locale" ' + LC_ALL=en_US.UTF-8 git grep A. invalid-utf8 >actual && + cat >expected <<-EOF && + invalid-utf8:ASCII + EOF + test_cmp expected actual + ' + test_expect_success FUNNYNAMES "grep $L should quote unusual pathnames" ' cat >expected <<-EOF && ${HC}"\"unusual\" pathname":unusual diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh index fe38d88a1a6ab1..3160be59fd2e26 100755 --- a/t/t7811-grep-open.sh +++ b/t/t7811-grep-open.sh @@ -3,7 +3,6 @@ test_description='git grep --open-files-in-pager ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pager.sh unset PAGER GIT_PAGER diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh index 31c66b63c2cb00..ac7be5471452a0 100755 --- a/t/t7812-grep-icase-non-ascii.sh +++ b/t/t7812-grep-icase-non-ascii.sh @@ -2,7 +2,6 @@ test_description='grep icase on non-English locales' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh doalarm () { diff --git a/t/t7813-grep-icase-iso.sh b/t/t7813-grep-icase-iso.sh index 1227885737b859..701e08a8e5941d 100755 --- a/t/t7813-grep-icase-iso.sh +++ b/t/t7813-grep-icase-iso.sh @@ -2,7 +2,6 @@ test_description='grep icase on non-English locales' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success GETTEXT_ISO_LOCALE 'setup' ' diff --git a/t/t7815-grep-binary.sh b/t/t7815-grep-binary.sh index ac871287c03a9f..90ebb64f46ebfa 100755 --- a/t/t7815-grep-binary.sh +++ b/t/t7815-grep-binary.sh @@ -2,7 +2,6 @@ test_description='git grep in binary files' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' " diff --git a/t/t7816-grep-binary-pattern.sh b/t/t7816-grep-binary-pattern.sh index 4353be5adb7b06..0088eaa0c918aa 100755 --- a/t/t7816-grep-binary-pattern.sh +++ b/t/t7816-grep-binary-pattern.sh @@ -2,7 +2,6 @@ test_description='git grep with a binary pattern files' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh nul_match_internal () { diff --git a/t/t7817-grep-sparse-checkout.sh b/t/t7817-grep-sparse-checkout.sh index 0ba7817fb76bc1..eb595645657fad 100755 --- a/t/t7817-grep-sparse-checkout.sh +++ b/t/t7817-grep-sparse-checkout.sh @@ -33,7 +33,6 @@ should leave the following structure in the working tree: But note that sub2 should have the SKIP_WORKTREE bit set. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 3cd7e1fcacb78a..1909aed95e08ad 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -328,7 +328,8 @@ test_expect_success 'incremental-repack task' ' # Delete refs that have not been repacked in these packs. git for-each-ref --format="delete %(refname)" \ - refs/prefetch refs/tags refs/remotes >refs && + refs/prefetch refs/tags refs/remotes \ + --exclude=refs/remotes/*/HEAD >refs && git update-ref --stdin <refs && # Replace the object directory with this pack layout. @@ -645,6 +646,22 @@ test_expect_success !MINGW 'register and unregister with regex metacharacters' ' maintenance.repo "$(pwd)/$META" ' +test_expect_success 'start without GIT_TEST_MAINT_SCHEDULER' ' + test_when_finished "rm -rf systemctl.log script repo" && + mkdir script && + write_script script/systemctl <<-\EOF && + echo "$*" >>../systemctl.log + EOF + git init repo && + ( + cd repo && + sane_unset GIT_TEST_MAINT_SCHEDULER && + PATH="$PWD/../script:$PATH" git maintenance start --scheduler=systemd + ) && + test_grep -- "--user list-timers" systemctl.log && + test_grep -- "enable --now git-maintenance@" systemctl.log +' + test_expect_success 'start --scheduler=<scheduler>' ' test_expect_code 129 git maintenance start --scheduler=foo 2>err && test_grep "unrecognized --scheduler argument" err && @@ -994,4 +1011,17 @@ test_expect_success 'repacking loose objects is quiet' ' ) ' +test_expect_success 'maintenance aborts with existing lock file' ' + test_when_finished "rm -rf repo script" && + mkdir script && + write_script script/systemctl <<-\EOF && + true + EOF + + git init repo && + : >repo/.git/objects/schedule.lock && + test_must_fail env PATH="$PWD/script:$PATH" git -C repo maintenance start --scheduler=systemd 2>err && + test_grep "Another scheduled git-maintenance(1) process seems to be running" err +' + test_done diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh index 35966340397591..e98993276a651a 100755 --- a/t/t8002-blame.sh +++ b/t/t8002-blame.sh @@ -5,7 +5,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh PROG='git blame -c' @@ -127,6 +126,32 @@ test_expect_success '--no-abbrev works like --abbrev with full length' ' check_abbrev $hexsz --no-abbrev ' +test_expect_success 'blame --abbrev gets truncated' ' + check_abbrev $hexsz --abbrev=9000 HEAD +' + +test_expect_success 'blame --abbrev gets truncated with boundary commit' ' + check_abbrev $hexsz --abbrev=9000 ^HEAD +' + +test_expect_success 'blame --abbrev -b truncates the blank boundary' ' + # Note that `--abbrev=` always gets incremented by 1, which is why we + # expect 11 leading spaces and not 10. + cat >expect <<-EOF && + $(printf "%11s" "") (<author@example.com> 2005-04-07 15:45:13 -0700 1) abbrev + EOF + git blame -b --abbrev=10 ^HEAD -- abbrev.t >actual && + test_cmp expect actual +' + +test_expect_success 'blame with excessive --abbrev and -b culls to hash length' ' + cat >expect <<-EOF && + $(printf "%${hexsz}s" "") (<author@example.com> 2005-04-07 15:45:13 -0700 1) abbrev + EOF + git blame -b --abbrev=9000 ^HEAD -- abbrev.t >actual && + test_cmp expect actual +' + test_expect_success '--exclude-promisor-objects does not BUG-crash' ' test_must_fail git blame --exclude-promisor-objects one ' diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 6288352f5777b3..731265541acf9f 100755 --- a/t/t8003-blame-corner-cases.sh +++ b/t/t8003-blame-corner-cases.sh @@ -4,7 +4,6 @@ test_description='git blame corner cases' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pick_fc='s/^[0-9a-f^]* *\([^ ]*\) *(\([^ ]*\) .*/\1-\2/' diff --git a/t/t8004-blame-with-conflicts.sh b/t/t8004-blame-with-conflicts.sh index 2c2a0b33f9bad5..35414a53363424 100755 --- a/t/t8004-blame-with-conflicts.sh +++ b/t/t8004-blame-with-conflicts.sh @@ -6,7 +6,6 @@ test_description='git blame on conflicted files' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup first case' ' diff --git a/t/t8005-blame-i18n.sh b/t/t8005-blame-i18n.sh index 75da219ed1be95..81847ffb9a88bd 100755 --- a/t/t8005-blame-i18n.sh +++ b/t/t8005-blame-i18n.sh @@ -1,8 +1,15 @@ #!/bin/sh test_description='git blame encoding conversion' + . ./test-lib.sh +if ! test_have_prereq ICONV +then + skip_all='skipping blame i18n tests; iconv not available' + test_done +fi + . "$TEST_DIRECTORY"/t8005/utf8.txt . "$TEST_DIRECTORY"/t8005/euc-japan.txt . "$TEST_DIRECTORY"/t8005/sjis.txt diff --git a/t/t8006-blame-textconv.sh b/t/t8006-blame-textconv.sh index 42f8be25a3fdf9..07a287ffd3e5c1 100755 --- a/t/t8006-blame-textconv.sh +++ b/t/t8006-blame-textconv.sh @@ -2,7 +2,6 @@ test_description='git blame textconv support' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh find_blame() { diff --git a/t/t8007-cat-file-textconv.sh b/t/t8007-cat-file-textconv.sh index c8266f17f14af3..c3735fb50de4cb 100755 --- a/t/t8007-cat-file-textconv.sh +++ b/t/t8007-cat-file-textconv.sh @@ -2,7 +2,6 @@ test_description='git cat-file textconv support' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >helper <<'EOF' diff --git a/t/t8008-blame-formats.sh b/t/t8008-blame-formats.sh index fb5d225a671447..c12a4196d66cab 100755 --- a/t/t8008-blame-formats.sh +++ b/t/t8008-blame-formats.sh @@ -2,7 +2,6 @@ test_description='blame output in various formats on a simple case' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t8009-blame-vs-topicbranches.sh b/t/t8009-blame-vs-topicbranches.sh index 30331713b950a5..c808b819621858 100755 --- a/t/t8009-blame-vs-topicbranches.sh +++ b/t/t8009-blame-vs-topicbranches.sh @@ -1,8 +1,7 @@ #!/bin/sh -test_description='blaming trough history with topic branches' +test_description='blaming through history with topic branches' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Creates the history shown below. '*'s mark the first parent in the merges. diff --git a/t/t8010-cat-file-filters.sh b/t/t8010-cat-file-filters.sh index eb64b766bdfa24..b3be2aa387f105 100755 --- a/t/t8010-cat-file-filters.sh +++ b/t/t8010-cat-file-filters.sh @@ -2,7 +2,6 @@ test_description='git cat-file filters support' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ' ' diff --git a/t/t8011-blame-split-file.sh b/t/t8011-blame-split-file.sh index da1801f4d23eda..c66494f5ba7335 100755 --- a/t/t8011-blame-split-file.sh +++ b/t/t8011-blame-split-file.sh @@ -11,7 +11,6 @@ not bother testing that the non-C case fails to find it. That is how blame behaves now, but it is not a property we want to make sure is retained. ' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # help avoid typing and reading long strings of similar lines diff --git a/t/t8012-blame-colors.sh b/t/t8012-blame-colors.sh index 9a79c109f2e985..c3a5f6d01ffe5c 100755 --- a/t/t8012-blame-colors.sh +++ b/t/t8012-blame-colors.sh @@ -5,7 +5,6 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh PROG='git blame -c' diff --git a/t/t8013-blame-ignore-revs.sh b/t/t8013-blame-ignore-revs.sh index d33788d8677293..370b76814927f3 100755 --- a/t/t8013-blame-ignore-revs.sh +++ b/t/t8013-blame-ignore-revs.sh @@ -2,7 +2,6 @@ test_description='ignore revisions when blaming' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Creates: diff --git a/t/t8014-blame-ignore-fuzzy.sh b/t/t8014-blame-ignore-fuzzy.sh index 933222cea15073..f5dcbd9e8243fb 100755 --- a/t/t8014-blame-ignore-fuzzy.sh +++ b/t/t8014-blame-ignore-fuzzy.sh @@ -2,7 +2,6 @@ test_description='git blame ignore fuzzy heuristic' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pick_author='s/^[0-9a-f^]* *(\([^ ]*\) .*/\1/' diff --git a/t/t8100-git-survey.sh b/t/t8100-git-survey.sh new file mode 100755 index 00000000000000..678fe582ad9506 --- /dev/null +++ b/t/t8100-git-survey.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +test_description='git survey' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +TEST_PASSES_SANITIZE_LEAK=0 +export TEST_PASSES_SANITIZE_LEAK + +. ./test-lib.sh + +test_expect_success 'create a semi-interesting repo' ' + test_commit_bulk 10 && + git tag -a -m one one HEAD~5 && + git tag -a -m two two HEAD~3 && + git tag -a -m three three two && + git tag -a -m four four three && + git update-ref -d refs/tags/three && + git update-ref -d refs/tags/two +' + +test_expect_success 'git survey --progress' ' + GIT_PROGRESS_DELAY=0 git survey --all-refs --progress >out 2>err && + grep "Preparing object walk" err +' + +test_expect_success 'git survey (default)' ' + git survey --all-refs >out 2>err && + test_line_count = 0 err && + + test_oid_cache <<-EOF && + commits_size_on_disk sha1: 1523 + commits_size_on_disk sha256: 1811 + + commits_size sha1: 2153 + commits_size sha256: 2609 + + trees_size_on_disk sha1: 495 + trees_size_on_disk sha256: 635 + + trees_size sha1: 1706 + trees_size sha256: 2366 + + tags_size sha1: 528 + tags_size sha256: 624 + + tags_size_on_disk sha1: 510 + tags_size_on_disk sha256: 569 + EOF + + tr , " " >expect <<-EOF && + GIT SURVEY for "$(pwd)" + ----------------------------------------------------- + + REFERENCES SUMMARY + ======================== + , Ref Type | Count + -----------------+------ + , Branches | 1 + Remote refs | 0 + Tags (all) | 2 + Tags (annotated) | 2 + + REACHABLE OBJECT SUMMARY + ======================== + Object Type | Count + ------------+------ + Tags | 4 + Commits | 10 + Trees | 10 + Blobs | 10 + + TOTAL OBJECT SIZES BY TYPE + =============================================== + Object Type | Count | Disk Size | Inflated Size + ------------+-------+-----------+-------------- + Commits | 10 | $(test_oid commits_size_on_disk) | $(test_oid commits_size) + Trees | 10 | $(test_oid trees_size_on_disk) | $(test_oid trees_size) + Blobs | 10 | 191 | 101 + Tags | 4 | $(test_oid tags_size_on_disk) | $(test_oid tags_size) + EOF + + lines=$(wc -l <expect) && + head -n $lines out >out-trimmed && + test_cmp expect out-trimmed && + + for type in "DIRECTORIES" "FILES" + do + for metric in "COUNT" "DISK SIZE" "INFLATED SIZE" + do + grep "TOP $type BY $metric" out || return 1 + done || return 1 + done +' + +test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index e2430f7bfabbc1..0c1af43f6fbb41 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -4,7 +4,6 @@ test_description='git send-email' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # May be altered later in the test diff --git a/t/t9002-column.sh b/t/t9002-column.sh index d5b98e615bca66..7353815c11b2bb 100755 --- a/t/t9002-column.sh +++ b/t/t9002-column.sh @@ -1,7 +1,6 @@ #!/bin/sh test_description='git column' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh index 14a704d0a8c311..8da318d2b543da 100755 --- a/t/t9003-help-autocorrect.sh +++ b/t/t9003-help-autocorrect.sh @@ -2,7 +2,6 @@ test_description='help.autocorrect finding a match' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -29,15 +28,18 @@ test_expect_success 'setup' ' test_cmp expect actual ' -test_expect_success 'autocorrect showing candidates' ' - git config help.autocorrect 0 && +for show in false no off 0 show +do + test_expect_success 'autocorrect showing candidates' ' + git config help.autocorrect $show && - test_must_fail git lfg 2>actual && - grep "^ lgf" actual && + test_must_fail git lfg 2>actual && + grep "^ lgf" actual && - test_must_fail git distimdist 2>actual && - grep "^ distimdistim" actual -' + test_must_fail git distimdist 2>actual && + grep "^ distimdistim" actual + ' +done for immediate in -1 immediate do @@ -65,7 +67,7 @@ test_expect_success 'autocorrect can be declined altogether' ' test_expect_success 'autocorrect works in work tree created from bare repo' ' git clone --bare . bare.git && git -C bare.git worktree add ../worktree && - git -C worktree -c help.autocorrect=immediate stauts + git -C worktree -c help.autocorrect=immediate status ' test_done diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index 52046e60d5150d..b2ee626b9ae7e0 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -21,32 +21,32 @@ a_empty_cr= a_empty_crlf= cd import - cat >> kw.c <<\EOF + cat >>kw.c <<\EOF /* Somebody prematurely put a keyword into this file */ /* $Id$ */ EOF - printf "Hello\r\nWorld\r\n" > crlf + printf "Hello\r\nWorld\r\n" >crlf a_crlf=$(git hash-object -w crlf) - printf "Hello\rWorld\r" > cr + printf "Hello\rWorld\r" >cr a_cr=$(git hash-object -w cr) - printf "Hello\nWorld\n" > lf + printf "Hello\nWorld\n" >lf a_lf=$(git hash-object -w lf) - printf "Hello\r\nWorld" > ne_crlf + printf "Hello\r\nWorld" >ne_crlf a_ne_crlf=$(git hash-object -w ne_crlf) - printf "Hello\nWorld" > ne_lf + printf "Hello\nWorld" >ne_lf a_ne_lf=$(git hash-object -w ne_lf) - printf "Hello\rWorld" > ne_cr + printf "Hello\rWorld" >ne_cr a_ne_cr=$(git hash-object -w ne_cr) touch empty a_empty=$(git hash-object -w empty) - printf "\n" > empty_lf + printf "\n" >empty_lf a_empty_lf=$(git hash-object -w empty_lf) - printf "\r" > empty_cr + printf "\r" >empty_cr a_empty_cr=$(git hash-object -w empty_cr) - printf "\r\n" > empty_crlf + printf "\r\n" >empty_crlf a_empty_crlf=$(git hash-object -w empty_crlf) svn_cmd import --no-auto-props -m 'import for git svn' . "$svnrepo" >/dev/null @@ -57,10 +57,10 @@ test_expect_success 'checkout working copy from svn' 'svn co "$svnrepo" test_wc' test_expect_success 'setup some commits to svn' ' ( cd test_wc && - echo Greetings >> kw.c && + echo Greetings >>kw.c && poke kw.c && svn_cmd commit -m "Not yet an Id" && - echo Hello world >> kw.c && + echo Hello world >>kw.c && poke kw.c && svn_cmd commit -m "Modified file, but still not yet an Id" && svn_cmd propset svn:keywords Id kw.c && @@ -75,7 +75,7 @@ test_expect_success 'fetch revisions from svn' 'git svn fetch' name='test svn:keywords ignoring' test_expect_success "$name" \ 'git checkout -b mybranch remotes/git-svn && - echo Hi again >> kw.c && + echo Hi again >>kw.c && git commit -a -m "test keywords ignoring" && git svn set-tree remotes/git-svn..mybranch && git pull . remotes/git-svn' @@ -106,8 +106,8 @@ done cd test_wc - printf '$Id$\rHello\rWorld\r' > cr - printf '$Id$\rHello\rWorld' > ne_cr + printf '$Id$\rHello\rWorld\r' >cr + printf '$Id$\rHello\rWorld' >ne_cr a_cr=$(printf '$Id$\r\nHello\r\nWorld\r\n' | git hash-object --stdin) a_ne_cr=$(printf '$Id$\r\nHello\r\nWorld' | git hash-object --stdin) test_expect_success 'Set CRLF on cr files' \ @@ -126,7 +126,7 @@ b_ne_cr="$(git hash-object ne_cr)" test_expect_success 'CRLF + $Id$' "test '$a_cr' = '$b_cr'" test_expect_success 'CRLF + $Id$ (no newline)' "test '$a_ne_cr' = '$b_ne_cr'" -cat > show-ignore.expect <<\EOF +cat >show-ignore.expect <<\EOF # / /no-such-file* @@ -153,7 +153,7 @@ no-such-file* ' . && svn_cmd commit -m 'propset svn:ignore' ) && - git svn show-ignore > show-ignore.got && + git svn show-ignore >show-ignore.got && cmp show-ignore.expect show-ignore.got " diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 3d4842164c8915..a44eabf0d80fa8 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -4,7 +4,6 @@ # test_description='Test export of commits to CVS' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq PERL; then diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index 027235d61aa35e..a81662713eb876 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -150,7 +150,8 @@ test_expect_success 'scalar clone' ' "$(pwd)" && git for-each-ref --format="%(refname)" refs/remotes/origin/ >actual && - echo "refs/remotes/origin/parallel" >expect && + echo "refs/remotes/origin/HEAD" >>expect && + echo "refs/remotes/origin/parallel" >>expect && test_cmp expect actual && test_path_is_missing 1/2 && @@ -219,7 +220,7 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' ' done ' - test_expect_success 'scalar reconfigure --all with detached HEADs' ' +test_expect_success 'scalar reconfigure --all with detached HEADs' ' repos="two three four" && for num in $repos do diff --git a/t/t9211-scalar-clone.sh b/t/t9211-scalar-clone.sh index 7869f45ee646dd..01f71910f53323 100755 --- a/t/t9211-scalar-clone.sh +++ b/t/t9211-scalar-clone.sh @@ -31,7 +31,7 @@ test_expect_success 'set up repository to clone' ' ) ' -cleanup_clone () { +cleanup_clone() { rm -rf "$1" } @@ -127,7 +127,7 @@ test_expect_success '--single-branch clones HEAD only' ' ( cd $enlistment/src && git for-each-ref refs/remotes/origin >out && - test_line_count = 1 out && + test_line_count = 2 out && grep "refs/remotes/origin/base" out ) && @@ -141,7 +141,7 @@ test_expect_success '--no-single-branch clones all branches' ' ( cd $enlistment/src && git for-each-ref refs/remotes/origin >out && - test_line_count = 2 out && + test_line_count = 3 out && grep "refs/remotes/origin/base" out && grep "refs/remotes/origin/parallel" out ) && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 3b3c371740a392..b258dbf1df79c1 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -7,7 +7,6 @@ test_description='test git fast-import utility' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash @@ -522,6 +521,113 @@ test_expect_success 'B: fail on invalid committer (5)' ' test_must_fail git fast-import <input ' +test_expect_success 'B: fail on invalid file path of ..' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 100644 :1 ../invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: fail on invalid file path of .' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Good path + COMMIT + M 100644 :1 ok-path + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Bad path + COMMIT + R ok-path ./invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success WINDOWS 'B: fail on invalid file path of C:' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 100644 :1 C:/invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: fail on invalid file path of .git' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 100644 :1 .git/invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: fail on invalid file path of .gitmodules' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 120000 :1 .gitmodules + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + ### ### series C ### @@ -946,7 +1052,7 @@ test_expect_success 'L: verify internal tree sorting' ' :100644 100644 M ba EXPECT_END - git fast-import <input && + git -c core.protectNTFS=false fast-import <input && GIT_PRINT_SHA1_ELLIPSIS="yes" git diff-tree --abbrev --raw L^ L >output && cut -d" " -f1,2,5 output >actual && test_cmp expect actual @@ -3097,7 +3203,7 @@ test_path_eol_success () { test_expect_success "S: paths at EOL with $test must work" ' test_when_finished "git branch -D S-path-eol" && - git fast-import --export-marks=marks.out <<-EOF >out 2>err && + git -c core.protectNTFS=false fast-import --export-marks=marks.out <<-EOF >out 2>err && blob mark :401 data <<BLOB @@ -3206,7 +3312,7 @@ test_path_space_success () { test_expect_success "S: paths before space with $test must work" ' test_when_finished "git branch -D S-path-space" && - git fast-import --export-marks=marks.out <<-EOF 2>err && + git -c core.protectNTFS=false fast-import --export-marks=marks.out <<-EOF 2>err && blob mark :401 data <<BLOB @@ -3676,7 +3782,7 @@ test_expect_success !MINGW 'W: get-mark & empty orphan commit with erroneous thi ### series X (other new features) ### -test_expect_success 'X: handling encoding' ' +test_expect_success ICONV 'X: handling encoding' ' test_tick && cat >input <<-INPUT_END && commit refs/heads/encoding @@ -3692,6 +3798,34 @@ test_expect_success 'X: handling encoding' ' git log -1 --format=%B encoding | grep $(printf "\317\200") ' +test_expect_success 'X: replace ref that becomes useless is removed' ' + git init -qb main testrepo && + cd testrepo && + ( + test_commit test && + + test_commit msg somename content && + + git mv somename othername && + NEW_TREE=$(git write-tree) && + MSG="$(git log -1 --format=%B HEAD)" && + NEW_COMMIT=$(git commit-tree -p HEAD^1 -m "$MSG" $NEW_TREE) && + git replace main $NEW_COMMIT && + + echo more >>othername && + git add othername && + git commit -qm more && + + git fast-export --all >tmp && + sed -e s/othername/somename/ tmp >tmp2 && + git fast-import --force <tmp2 2>msgs && + + grep "Dropping.*since it would point to itself" msgs && + git show-ref >refs && + ! grep refs/replace refs + ) +' + ### ### series Y (submodules and hash algorithms) ### diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh index 58413221e6a73d..1ae4d7c0d37db2 100755 --- a/t/t9301-fast-import-notes.sh +++ b/t/t9301-fast-import-notes.sh @@ -7,7 +7,6 @@ test_description='test git fast-import of notes objects' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t9302-fast-import-unpack-limit.sh b/t/t9302-fast-import-unpack-limit.sh index d8b1f9442e8f6e..ec8c8652c6ce07 100755 --- a/t/t9302-fast-import-unpack-limit.sh +++ b/t/t9302-fast-import-unpack-limit.sh @@ -1,7 +1,6 @@ #!/bin/sh test_description='test git fast-import unpack limit' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create loose objects on import' ' diff --git a/t/t9303-fast-import-compression.sh b/t/t9303-fast-import-compression.sh index 4f5bf40587cb03..f15c8c0213ea21 100755 --- a/t/t9303-fast-import-compression.sh +++ b/t/t9303-fast-import-compression.sh @@ -2,7 +2,6 @@ test_description='compression setting of fast-import utility' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh import_large () { diff --git a/t/t9304-fast-import-marks.sh b/t/t9304-fast-import-marks.sh index 1f776a80f3b4b9..6c50adca009c6d 100755 --- a/t/t9304-fast-import-marks.sh +++ b/t/t9304-fast-import-marks.sh @@ -2,7 +2,6 @@ test_description='test exotic situations with marks' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup dump of basic history' ' diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 1eb035ee4ce547..40427883ec6dbf 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -124,7 +124,7 @@ test_expect_success 'fast-export --show-original-ids | git fast-import' ' test $MUSS = $(git rev-parse --verify refs/tags/muss) ' -test_expect_success 'reencoding iso-8859-7' ' +test_expect_success ICONV 'reencoding iso-8859-7' ' test_when_finished "git reset --hard HEAD~1" && test_config i18n.commitencoding iso-8859-7 && @@ -420,7 +420,7 @@ M 100644 :1 there EOF -test_expect_success 'dropping tag of filtered out object' ' +test_expect_success ICONV 'dropping tag of filtered out object' ' ( cd limit-by-paths && git fast-export --tag-of-filtered-object=drop mytag -- there > output && @@ -437,7 +437,7 @@ msg EOF -test_expect_success 'rewriting tag of filtered out object' ' +test_expect_success ICONV 'rewriting tag of filtered out object' ' ( cd limit-by-paths && git fast-export --tag-of-filtered-object=rewrite mytag -- there > output && @@ -631,7 +631,7 @@ test_expect_success 'fast-export quotes pathnames' ' git rev-list HEAD >expect && git init result && cd result && - git fast-import <../export.out && + git -c core.protectNTFS=false fast-import <../export.out && git rev-list HEAD >actual && test_cmp ../expect actual ) @@ -666,7 +666,7 @@ M 100644 :13 file EOF -test_expect_success 'avoid uninteresting refs' ' +test_expect_success ICONV 'avoid uninteresting refs' ' > tmp-marks && git fast-export --import-marks=tmp-marks \ --export-marks=tmp-marks main > /dev/null && @@ -685,7 +685,7 @@ from :14 EOF -test_expect_success 'refs are updated even if no commits need to be exported' ' +test_expect_success ICONV 'refs are updated even if no commits need to be exported' ' > tmp-marks && git fast-export --import-marks=tmp-marks \ --export-marks=tmp-marks main > /dev/null && diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh index c0d9d7be754d57..156a6474847cf6 100755 --- a/t/t9351-fast-export-anonymize.sh +++ b/t/t9351-fast-export-anonymize.sh @@ -4,7 +4,6 @@ test_description='basic tests for fast-export --anonymize' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup simple repo' ' diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index a67e6abd49db3d..a34805acdc25cc 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -12,7 +12,6 @@ repository using cvs CLI client via git-cvsserver server' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh marked_as () { diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index ccfa4153840acf..7679780fb87b4f 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -13,7 +13,6 @@ or warnings to log.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gitweb.sh # ---------------------------------------------------------------------- diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh index c900231079cf75..32814e75df5b0d 100755 --- a/t/t9501-gitweb-standalone-http-status.sh +++ b/t/t9501-gitweb-standalone-http-status.sh @@ -13,7 +13,6 @@ code and message.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gitweb.sh # diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh index b41ea193314381..81d562555799be 100755 --- a/t/t9502-gitweb-standalone-parse-output.sh +++ b/t/t9502-gitweb-standalone-parse-output.sh @@ -13,7 +13,6 @@ in the HTTP header or the actual script output.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-gitweb.sh # ---------------------------------------------------------------------- diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh index 41fcf3606b39b7..568084921896cf 100755 --- a/t/t9600-cvsimport.sh +++ b/t/t9600-cvsimport.sh @@ -4,7 +4,6 @@ test_description='git cvsimport basic tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh if ! test_have_prereq NOT_ROOT; then diff --git a/t/t9601-cvsimport-vendor-branch.sh b/t/t9601-cvsimport-vendor-branch.sh index e00766949573cf..116cddba3a5da8 100755 --- a/t/t9601-cvsimport-vendor-branch.sh +++ b/t/t9601-cvsimport-vendor-branch.sh @@ -35,7 +35,6 @@ test_description='git cvsimport handling of vendor branches' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh setup_cvs_test_repository t9601 diff --git a/t/t9602-cvsimport-branches-tags.sh b/t/t9602-cvsimport-branches-tags.sh index 3768e3bd8cc8e3..e5266c9a872f15 100755 --- a/t/t9602-cvsimport-branches-tags.sh +++ b/t/t9602-cvsimport-branches-tags.sh @@ -7,7 +7,6 @@ test_description='git cvsimport handling of branches and tags' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh setup_cvs_test_repository t9602 diff --git a/t/t9603-cvsimport-patchsets.sh b/t/t9603-cvsimport-patchsets.sh index 2a387fdbaaefe0..1ee966c256afba 100755 --- a/t/t9603-cvsimport-patchsets.sh +++ b/t/t9603-cvsimport-patchsets.sh @@ -13,7 +13,6 @@ test_description='git cvsimport testing for correct patchset estimation' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh setup_cvs_test_repository t9603 diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh index 9cf0685d56fe51..57a3bef2ecedfb 100755 --- a/t/t9604-cvsimport-timestamps.sh +++ b/t/t9604-cvsimport-timestamps.sh @@ -2,7 +2,6 @@ test_description='git cvsimport timestamps' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh test_lazy_prereq POSIX_TIMEZONE ' diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh index 44316971224bc4..9c9e3b5eb11a0f 100755 --- a/t/t9700-perl-git.sh +++ b/t/t9700-perl-git.sh @@ -5,7 +5,6 @@ test_description='perl interface (Git.pm)' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-perl.sh diff --git a/t/t9700/test.pl b/t/t9700/test.pl index 2e1d50d4d1e8c8..58a9b328d558f3 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.008001; +require v5.26; use warnings; use strict; diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh index 3e6dfce24833a0..0816763e46639c 100755 --- a/t/t9800-git-p4-basic.sh +++ b/t/t9800-git-p4-basic.sh @@ -5,7 +5,6 @@ test_description='git p4 tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh index cdbfacc727a7c6..c598011635ac2f 100755 --- a/t/t9801-git-p4-branch.sh +++ b/t/t9801-git-p4-branch.sh @@ -5,7 +5,6 @@ test_description='git p4 tests for p4 branches' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh index 1bc48305b01789..df01a5d3389861 100755 --- a/t/t9802-git-p4-filetype.sh +++ b/t/t9802-git-p4-filetype.sh @@ -2,7 +2,6 @@ test_description='git p4 filetype tests' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9803-git-p4-shell-metachars.sh b/t/t9803-git-p4-shell-metachars.sh index ab7fe16266872c..2913277013da56 100755 --- a/t/t9803-git-p4-shell-metachars.sh +++ b/t/t9803-git-p4-shell-metachars.sh @@ -2,7 +2,6 @@ test_description='git p4 transparency to shell metachars in filenames' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9804-git-p4-label.sh b/t/t9804-git-p4-label.sh index c8963fd3980e0e..32364571063d4c 100755 --- a/t/t9804-git-p4-label.sh +++ b/t/t9804-git-p4-label.sh @@ -2,7 +2,6 @@ test_description='git p4 label tests' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9805-git-p4-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh index 72dce3d2b46f4d..90ef647db7e610 100755 --- a/t/t9805-git-p4-skip-submit-edit.sh +++ b/t/t9805-git-p4-skip-submit-edit.sh @@ -2,7 +2,6 @@ test_description='git p4 skipSubmitEdit config variables' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh index e4ce44ebf3783b..c26d29743307b5 100755 --- a/t/t9806-git-p4-options.sh +++ b/t/t9806-git-p4-options.sh @@ -5,7 +5,6 @@ test_description='git p4 options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9808-git-p4-chdir.sh b/t/t9808-git-p4-chdir.sh index 342f7f3d4a09d2..58a9b3b71e6d88 100755 --- a/t/t9808-git-p4-chdir.sh +++ b/t/t9808-git-p4-chdir.sh @@ -2,7 +2,6 @@ test_description='git p4 relative chdir' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh index f33fdea889edc3..9c9710d8c7b871 100755 --- a/t/t9809-git-p4-client-view.sh +++ b/t/t9809-git-p4-client-view.sh @@ -2,7 +2,6 @@ test_description='git p4 client view' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh index 15e32c9f353a73..5fe83315ecd57a 100755 --- a/t/t9810-git-p4-rcs.sh +++ b/t/t9810-git-p4-rcs.sh @@ -2,7 +2,6 @@ test_description='git p4 rcs keywords' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh CP1252="\223\224" diff --git a/t/t9811-git-p4-label-import.sh b/t/t9811-git-p4-label-import.sh index 52a4b0af811294..5ac5383fb71715 100755 --- a/t/t9811-git-p4-label-import.sh +++ b/t/t9811-git-p4-label-import.sh @@ -5,7 +5,6 @@ test_description='git p4 label tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh index 46aa5fd56c7706..254a7c244698a0 100755 --- a/t/t9812-git-p4-wildcards.sh +++ b/t/t9812-git-p4-wildcards.sh @@ -2,7 +2,6 @@ test_description='git p4 wildcards' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9813-git-p4-preserve-users.sh b/t/t9813-git-p4-preserve-users.sh index 0efea28da2cb9d..fd018c87a80636 100755 --- a/t/t9813-git-p4-preserve-users.sh +++ b/t/t9813-git-p4-preserve-users.sh @@ -2,7 +2,6 @@ test_description='git p4 preserve users' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh index 00df6ebd3bdc03..2a9838f37fe293 100755 --- a/t/t9814-git-p4-rename.sh +++ b/t/t9814-git-p4-rename.sh @@ -2,7 +2,6 @@ test_description='git p4 rename' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh index 92ef9d8c242559..c766fd159f14b6 100755 --- a/t/t9815-git-p4-submit-fail.sh +++ b/t/t9815-git-p4-submit-fail.sh @@ -2,7 +2,6 @@ test_description='git p4 submit failure handling' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh index e687fbc25f60f5..5e904ac80d8522 100755 --- a/t/t9816-git-p4-locked.sh +++ b/t/t9816-git-p4-locked.sh @@ -2,7 +2,6 @@ test_description='git p4 locked file behavior' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9817-git-p4-exclude.sh b/t/t9817-git-p4-exclude.sh index 3deb334fed1c6a..ec3d937c6a73bb 100755 --- a/t/t9817-git-p4-exclude.sh +++ b/t/t9817-git-p4-exclude.sh @@ -2,7 +2,6 @@ test_description='git p4 tests for excluded paths during clone and sync' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh index 091bb72bdb62bd..de591d875c2bbc 100755 --- a/t/t9818-git-p4-block.sh +++ b/t/t9818-git-p4-block.sh @@ -2,7 +2,6 @@ test_description='git p4 fetching changes in multiple blocks' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9819-git-p4-case-folding.sh b/t/t9819-git-p4-case-folding.sh index 985be203571620..b4d93f0c17c357 100755 --- a/t/t9819-git-p4-case-folding.sh +++ b/t/t9819-git-p4-case-folding.sh @@ -2,7 +2,6 @@ test_description='interaction with P4 case-folding' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh if test_have_prereq CASE_INSENSITIVE_FS diff --git a/t/t9820-git-p4-editor-handling.sh b/t/t9820-git-p4-editor-handling.sh index 48e4dfb95c03c3..fa1bba1dd93614 100755 --- a/t/t9820-git-p4-editor-handling.sh +++ b/t/t9820-git-p4-editor-handling.sh @@ -2,7 +2,6 @@ test_description='git p4 handling of EDITOR' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9821-git-p4-path-variations.sh b/t/t9821-git-p4-path-variations.sh index 49691c53dadddb..ef80f1690bcb9a 100755 --- a/t/t9821-git-p4-path-variations.sh +++ b/t/t9821-git-p4-path-variations.sh @@ -2,7 +2,6 @@ test_description='Clone repositories with path case variations' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d with case folding enabled' ' diff --git a/t/t9822-git-p4-path-encoding.sh b/t/t9822-git-p4-path-encoding.sh index e62ed49f51e022..572d395498e30a 100755 --- a/t/t9822-git-p4-path-encoding.sh +++ b/t/t9822-git-p4-path-encoding.sh @@ -2,7 +2,6 @@ test_description='Clone repositories with non ASCII paths' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh UTF8_ESCAPED="a-\303\244_o-\303\266_u-\303\274.txt" diff --git a/t/t9823-git-p4-mock-lfs.sh b/t/t9823-git-p4-mock-lfs.sh index 98a40d8af3793b..88b76dc4d6c26f 100755 --- a/t/t9823-git-p4-mock-lfs.sh +++ b/t/t9823-git-p4-mock-lfs.sh @@ -2,7 +2,6 @@ test_description='Clone repositories and store files in Mock LFS' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_file_is_not_in_mock_lfs () { diff --git a/t/t9825-git-p4-handle-utf16-without-bom.sh b/t/t9825-git-p4-handle-utf16-without-bom.sh index d0b86537dd975a..6a60b323493913 100755 --- a/t/t9825-git-p4-handle-utf16-without-bom.sh +++ b/t/t9825-git-p4-handle-utf16-without-bom.sh @@ -2,7 +2,6 @@ test_description='git p4 handling of UTF-16 files without BOM' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh UTF16="\227\000\227\000" diff --git a/t/t9826-git-p4-keep-empty-commits.sh b/t/t9826-git-p4-keep-empty-commits.sh index 54083f842e9259..fd64afe064e5a9 100755 --- a/t/t9826-git-p4-keep-empty-commits.sh +++ b/t/t9826-git-p4-keep-empty-commits.sh @@ -2,7 +2,6 @@ test_description='Clone repositories and keep empty commits' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9827-git-p4-change-filetype.sh b/t/t9827-git-p4-change-filetype.sh index 3476ea2fd3b577..d3670bd7a24dbf 100755 --- a/t/t9827-git-p4-change-filetype.sh +++ b/t/t9827-git-p4-change-filetype.sh @@ -2,7 +2,6 @@ test_description='git p4 support for file type change' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9828-git-p4-map-user.sh b/t/t9828-git-p4-map-user.sh index 7c8f9e3930406d..ca6c2942bdf200 100755 --- a/t/t9828-git-p4-map-user.sh +++ b/t/t9828-git-p4-map-user.sh @@ -2,7 +2,6 @@ test_description='Clone repositories and map users' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9829-git-p4-jobs.sh b/t/t9829-git-p4-jobs.sh index 3fc0948d9cff20..88cfb1fcd3f0a1 100755 --- a/t/t9829-git-p4-jobs.sh +++ b/t/t9829-git-p4-jobs.sh @@ -2,7 +2,6 @@ test_description='git p4 retrieve job info' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9830-git-p4-symlink-dir.sh b/t/t9830-git-p4-symlink-dir.sh index 02561a7f0e62f7..3fb6960c18fc0c 100755 --- a/t/t9830-git-p4-symlink-dir.sh +++ b/t/t9830-git-p4-symlink-dir.sh @@ -2,7 +2,6 @@ test_description='git p4 symlinked directories' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9831-git-p4-triggers.sh b/t/t9831-git-p4-triggers.sh index f287f41e3741e1..ff6c0352e68824 100755 --- a/t/t9831-git-p4-triggers.sh +++ b/t/t9831-git-p4-triggers.sh @@ -2,7 +2,6 @@ test_description='git p4 with server triggers' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh index a2667754086a5c..6b3cb0414aa08c 100755 --- a/t/t9832-unshelve.sh +++ b/t/t9832-unshelve.sh @@ -6,7 +6,6 @@ last_shelved_change () { test_description='git p4 unshelve' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9833-errors.sh b/t/t9833-errors.sh index da1d30c142c4fa..e22369ccdf5f15 100755 --- a/t/t9833-errors.sh +++ b/t/t9833-errors.sh @@ -2,7 +2,6 @@ test_description='git p4 errors' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9834-git-p4-file-dir-bug.sh b/t/t9834-git-p4-file-dir-bug.sh index 565870fc740cb2..dac67e89d7d720 100755 --- a/t/t9834-git-p4-file-dir-bug.sh +++ b/t/t9834-git-p4-file-dir-bug.sh @@ -6,7 +6,6 @@ This test creates files and directories with the same name in perforce and checks that git-p4 recovers from the error at the same time as the perforce repository.' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh test_expect_success 'start p4d' ' diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh index ad20ffdededdc9..6116f806f63115 100755 --- a/t/t9835-git-p4-metadata-encoding-python2.sh +++ b/t/t9835-git-p4-metadata-encoding-python2.sh @@ -6,32 +6,31 @@ This test checks that the import process handles inconsistent text encoding in p4 metadata (author names, commit messages, etc) without failing, and produces maximally sane output in git.' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh -python_target_version='2' - ############################### ## SECTION REPEATED IN t9836 ## ############################### -# Please note: this test calls "git-p4.py" rather than "git-p4", because the -# latter references a specific path so we can't easily force it to run under -# the python version we need to. - -python_major_version=$(python -V 2>&1 | cut -c 8) -python_target_binary=$(which python$python_target_version) -if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary" +# These tests are specific to Python 2. Write a custom script that executes +# git-p4 directly with the Python 2 interpreter to ensure that we use that +# version even if Git was compiled with Python 3. +python_target_binary=$(which python2) +if test -n "$python_target_binary" then mkdir temp_python - PATH="$(pwd)/temp_python:$PATH" && export PATH - ln -s $python_target_binary temp_python/python + PATH="$(pwd)/temp_python:$PATH" + export PATH + + write_script temp_python/git-p4-python2 <<-EOF + exec "$python_target_binary" "$(git --exec-path)/git-p4" "\$@" + EOF fi -python_major_version=$(python -V 2>&1 | cut -c 8) -if ! test "$python_major_version" = "$python_target_version" +git p4-python2 >err +if ! grep 'valid commands' err then - skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available" + skip_all="skipping python2 git p4 tests; python2 not available" test_done fi @@ -82,14 +81,14 @@ test_expect_success 'init depot' ' test_expect_success 'clone non-utf8 repo with strict encoding' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err && + test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python2 clone --dest="$git" //depot@all 2>err && grep "Decoding perforce metadata failed!" err ' test_expect_success 'check utf-8 contents with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -101,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' ' test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -115,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st test_expect_success 'check utf-8 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -127,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' ' test_expect_success 'check latin-1 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -139,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' ' test_expect_success 'check cp-1252 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -151,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' ' test_expect_success 'check cp850 contents parsed with correct fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -163,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' ' test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -175,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$cli" && P4USER=cp1252_author && @@ -187,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb ( cd "$git" && - git p4.py sync --branch=master && + git p4-python2 sync --branch=master && git log p4/master >actual && grep "sœme more cp-1252 tæxt" actual && @@ -202,7 +201,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb test_expect_success 'passthrough (latin-1 contents corrupted in git) is the default with python2' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh index 71ae763399c084..5e5217a66b4fdb 100755 --- a/t/t9836-git-p4-metadata-encoding-python3.sh +++ b/t/t9836-git-p4-metadata-encoding-python3.sh @@ -6,32 +6,31 @@ This test checks that the import process handles inconsistent text encoding in p4 metadata (author names, commit messages, etc) without failing, and produces maximally sane output in git.' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh -python_target_version='3' - ############################### ## SECTION REPEATED IN t9835 ## ############################### -# Please note: this test calls "git-p4.py" rather than "git-p4", because the -# latter references a specific path so we can't easily force it to run under -# the python version we need to. - -python_major_version=$(python -V 2>&1 | cut -c 8) -python_target_binary=$(which python$python_target_version) -if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary" +# These tests are specific to Python 3. Write a custom script that executes +# git-p4 directly with the Python 3 interpreter to ensure that we use that +# version even if Git was compiled with Python 2. +python_target_binary=$(which python3) +if test -n "$python_target_binary" then mkdir temp_python - PATH="$(pwd)/temp_python:$PATH" && export PATH - ln -s $python_target_binary temp_python/python + PATH="$(pwd)/temp_python:$PATH" + export PATH + + write_script temp_python/git-p4-python3 <<-EOF + exec "$python_target_binary" "$(git --exec-path)/git-p4" "\$@" + EOF fi -python_major_version=$(python -V 2>&1 | cut -c 8) -if ! test "$python_major_version" = "$python_target_version" +git p4-python3 >err +if ! grep 'valid commands' err then - skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available" + skip_all="skipping python3 git p4 tests; python3 not available" test_done fi @@ -82,14 +81,14 @@ test_expect_success 'init depot' ' test_expect_success 'clone non-utf8 repo with strict encoding' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err && + test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python3 clone --dest="$git" //depot@all 2>err && grep "Decoding perforce metadata failed!" err ' test_expect_success 'check utf-8 contents with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -101,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' ' test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -115,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st test_expect_success 'check utf-8 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -127,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' ' test_expect_success 'check latin-1 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -139,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' ' test_expect_success 'check cp-1252 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -151,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' ' test_expect_success 'check cp850 contents parsed with correct fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -163,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' ' test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -175,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$cli" && P4USER=cp1252_author && @@ -187,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb ( cd "$git" && - git p4.py sync --branch=master && + git p4-python3 sync --branch=master && git log p4/master >actual && grep "sœme more cp-1252 tæxt" actual && @@ -203,7 +202,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb test_expect_success 'fallback (both utf-8 and cp-1252 contents handled) is the default with python3' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git p4.py clone --dest="$git" //depot@all && + git p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && diff --git a/t/t9850-shell.sh b/t/t9850-shell.sh index cfc71c3bd43187..36566ace21b07c 100755 --- a/t/t9850-shell.sh +++ b/t/t9850-shell.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='git shell tests' + . ./test-lib.sh test_expect_success 'shell allows upload-pack' ' diff --git a/t/t9901-git-web--browse.sh b/t/t9901-git-web--browse.sh index 19f56e5680f678..de7152f82713bf 100755 --- a/t/t9901-git-web--browse.sh +++ b/t/t9901-git-web--browse.sh @@ -5,7 +5,6 @@ test_description='git web--browse basic tests This test checks that git web--browse can handle various valid URLs.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_web_browse () { diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index cc6aa9f0cd36e3..51bd7508376ce3 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -16,7 +16,6 @@ test_untraceable=UnfortunatelyYes GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-bash.sh complete () @@ -658,6 +657,7 @@ test_expect_success '__git_refs - simple' ' HEAD main matching-branch + other/HEAD other/branch-in-other other/main-in-other matching-tag @@ -673,6 +673,7 @@ test_expect_success '__git_refs - full refs' ' cat >expected <<-EOF && refs/heads/main refs/heads/matching-branch + refs/remotes/other/HEAD refs/remotes/other/branch-in-other refs/remotes/other/main-in-other refs/tags/matching-tag @@ -729,6 +730,7 @@ test_expect_success '__git_refs - remote on local file system - full refs' ' test_expect_success '__git_refs - configured remote' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -756,6 +758,7 @@ test_expect_success '__git_refs - configured remote - full refs' ' test_expect_success '__git_refs - configured remote - repo given on the command line' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -787,6 +790,7 @@ test_expect_success '__git_refs - configured remote - full refs - repo given on test_expect_success '__git_refs - configured remote - remote name matches a directory' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -875,12 +879,14 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer HEAD main matching-branch + other/HEAD other/ambiguous other/branch-in-other other/main-in-other remote/ambiguous remote/branch-in-remote matching-tag + HEAD branch-in-other branch-in-remote main-in-other @@ -904,6 +910,7 @@ test_expect_success '__git_refs - after --opt=' ' HEAD main matching-branch + other/HEAD other/branch-in-other other/main-in-other matching-tag @@ -919,6 +926,7 @@ test_expect_success '__git_refs - after --opt= - full refs' ' cat >expected <<-EOF && refs/heads/main refs/heads/matching-branch + refs/remotes/other/HEAD refs/remotes/other/branch-in-other refs/remotes/other/main-in-other refs/tags/matching-tag @@ -935,6 +943,7 @@ test_expect_success '__git refs - excluding refs' ' ^HEAD ^main ^matching-branch + ^other/HEAD ^other/branch-in-other ^other/main-in-other ^matching-tag @@ -950,6 +959,7 @@ test_expect_success '__git refs - excluding full refs' ' cat >expected <<-EOF && ^refs/heads/main ^refs/heads/matching-branch + ^refs/remotes/other/HEAD ^refs/remotes/other/branch-in-other ^refs/remotes/other/main-in-other ^refs/tags/matching-tag @@ -975,6 +985,7 @@ test_expect_success '__git_refs - do not filter refs unless told so' ' main matching-branch matching/branch + other/HEAD other/branch-in-other other/main-in-other other/matching/branch-in-other @@ -1095,6 +1106,7 @@ test_expect_success '__git_complete_refs - simple' ' HEAD Z main Z matching-branch Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z matching-tag Z @@ -1123,6 +1135,7 @@ test_expect_success '__git_complete_refs - matching' ' test_expect_success '__git_complete_refs - remote' ' sed -e "s/Z$//" >expected <<-EOF && HEAD Z + HEAD Z branch-in-other Z main-in-other Z EOF @@ -1139,9 +1152,11 @@ test_expect_success '__git_complete_refs - track' ' HEAD Z main Z matching-branch Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z matching-tag Z + HEAD Z branch-in-other Z main-in-other Z EOF @@ -1184,6 +1199,7 @@ test_expect_success '__git_complete_refs - suffix' ' HEAD. main. matching-branch. + other/HEAD. other/branch-in-other. other/main-in-other. matching-tag. @@ -1199,6 +1215,7 @@ test_expect_success '__git_complete_refs - suffix' ' test_expect_success '__git_complete_fetch_refspecs - simple' ' sed -e "s/Z$//" >expected <<-EOF && HEAD:HEAD Z + HEAD:HEAD Z branch-in-other:branch-in-other Z main-in-other:main-in-other Z EOF @@ -1225,6 +1242,7 @@ test_expect_success '__git_complete_fetch_refspecs - matching' ' test_expect_success '__git_complete_fetch_refspecs - prefix' ' sed -e "s/Z$//" >expected <<-EOF && +HEAD:HEAD Z + +HEAD:HEAD Z +branch-in-other:branch-in-other Z +main-in-other:main-in-other Z EOF @@ -1289,6 +1307,7 @@ test_expect_success '__git_complete_worktree_paths with -C' ' test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' ' test_completion "git switch " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1435,11 +1454,13 @@ test_expect_success 'git-bisect - existing view subcommand is recognized and ena test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' ' test_completion "git checkout " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1461,6 +1482,7 @@ test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, compl test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' ' GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1470,6 +1492,7 @@ test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_G test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' ' test_completion "git switch --no-guess --guess " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1490,6 +1513,7 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1498,11 +1522,13 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' ' GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1514,6 +1540,7 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1522,11 +1549,13 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' ' test_completion "git checkout --no-guess --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1538,6 +1567,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1550,6 +1580,7 @@ test_expect_success 'git checkout - with checkout.guess = false, only completes main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1559,11 +1590,13 @@ test_expect_success 'git checkout - with checkout.guess = true, completes refs a test_config checkout.guess true && test_completion "git checkout " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1573,11 +1606,13 @@ test_expect_success 'git checkout - a later --guess overrides previous checkout. test_config checkout.guess false && test_completion "git checkout --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1590,6 +1625,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous checko main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1601,6 +1637,7 @@ test_expect_success 'git switch - with --detach, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1612,6 +1649,7 @@ test_expect_success 'git checkout - with --detach, complete only references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1783,6 +1821,7 @@ test_expect_success 'git switch - with -d, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1794,6 +1833,7 @@ test_expect_success 'git checkout - with -d, complete only references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1801,10 +1841,12 @@ test_expect_success 'git checkout - with -d, complete only references' ' test_expect_success 'git switch - with --track, complete only remote branches' ' test_completion "git switch --track " <<-\EOF && + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF test_completion "git switch -t " <<-\EOF + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1812,10 +1854,12 @@ test_expect_success 'git switch - with --track, complete only remote branches' ' test_expect_success 'git checkout - with --track, complete only remote branches' ' test_completion "git checkout --track " <<-\EOF && + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF test_completion "git checkout -t " <<-\EOF + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1834,6 +1878,7 @@ test_expect_success 'git checkout - with --no-track, complete only local referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1845,6 +1890,7 @@ test_expect_success 'git switch - with -c, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1856,6 +1902,7 @@ test_expect_success 'git switch - with -C, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1867,6 +1914,7 @@ test_expect_success 'git switch - with -c and --track, complete all references' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1878,6 +1926,7 @@ test_expect_success 'git switch - with -C and --track, complete all references' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1889,6 +1938,7 @@ test_expect_success 'git switch - with -c and --no-track, complete all reference main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1900,6 +1950,7 @@ test_expect_success 'git switch - with -C and --no-track, complete all reference main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1911,6 +1962,7 @@ test_expect_success 'git checkout - with -b, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1922,6 +1974,7 @@ test_expect_success 'git checkout - with -B, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1933,6 +1986,7 @@ test_expect_success 'git checkout - with -b and --track, complete all references main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1944,6 +1998,7 @@ test_expect_success 'git checkout - with -B and --track, complete all references main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1955,6 +2010,7 @@ test_expect_success 'git checkout - with -b and --no-track, complete all referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1966,6 +2022,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1973,6 +2030,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen test_expect_success 'git switch - for -c, complete local branches and unique remote branches' ' test_completion "git switch -c " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1982,6 +2040,7 @@ test_expect_success 'git switch - for -c, complete local branches and unique rem test_expect_success 'git switch - for -C, complete local branches and unique remote branches' ' test_completion "git switch -C " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2019,6 +2078,7 @@ test_expect_success 'git switch - for -C with --no-track, complete local branche test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' ' test_completion "git checkout -b " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2028,6 +2088,7 @@ test_expect_success 'git checkout - for -b, complete local branches and unique r test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' ' test_completion "git checkout -B " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2065,6 +2126,7 @@ test_expect_success 'git checkout - for -B with --no-track, complete local branc test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' ' test_completion "git switch --orphan " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2080,6 +2142,7 @@ test_expect_success 'git switch - --orphan with branch already provided complete test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' ' test_completion "git checkout --orphan " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2093,6 +2156,7 @@ test_expect_success 'git checkout - --orphan with branch already provided comple main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 95e9955bca1bed..d667dda654e2de 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -8,7 +8,6 @@ test_description='test git-specific bash prompt functions' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -TEST_PASSES_SANITIZE_LEAK=true . ./lib-bash.sh . "$GIT_BUILD_DIR/contrib/completion/git-prompt.sh" diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index fde9bf54fc35fc..79377bc0fc2110 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -926,7 +926,8 @@ test_expect_success () { test_body_or_stdin test_body "$2" test -n "$test_skip_test_preamble" || say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $test_body" - if test_run_ "$test_body" + if test_run_ "$test_body" && + ! check_test_results_san_file_has_entries_ then test_ok_ "$1" else @@ -1267,6 +1268,16 @@ test_cmp () { eval "$GIT_TEST_CMP" '"$@"' } +# test_cmp_sorted runs test_cmp on sorted versions of the two +# input files. Uses "$1.sorted" and "$2.sorted" as temp files. + +test_cmp_sorted () { + sort <"$1" >"$1.sorted" && + sort <"$2" >"$2.sorted" && + test_cmp "$1.sorted" "$2.sorted" && + rm "$1.sorted" "$2.sorted" +} + # Check that the given config key has the expected value. # # test_cmp_config [-C <dir>] <expected-value> @@ -1885,6 +1896,32 @@ test_subcommand () { fi } +# Check that the given subcommand was run with the given set of +# arguments in order (but with possible extra arguments). +# +# test_subcommand_flex [!] <command> <args>... < <trace> +# +# If the first parameter passed is !, this instead checks that +# the given command was not called. +# +test_subcommand_flex () { + local negate= + if test "$1" = "!" + then + negate=t + shift + fi + + local expr="$(printf '"%s".*' "$@")" + + if test -n "$negate" + then + ! grep "\[$expr\]" + else + grep "\[$expr\]" + fi +} + # Check that the given command was invoked as part of the # trace2-format trace on stdin. # @@ -2006,3 +2043,11 @@ test_trailing_hash () { test-tool hexdump | sed "s/ //g" } + +# Trim and replace each character with ascii code below 32 or above +# 127 (included) using a dot '.' character. +# Octal intervals \001-\040 and \177-\377 +# correspond to decimal intervals 1-32 and 127-255 +test_redact_non_printables () { + tr -d "\n\r" | tr "[\001-\040][\177-\377]" "." +} diff --git a/t/test-lib.sh b/t/test-lib.sh index e718efe4c601f4..9001ed3a6470a2 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -35,13 +35,7 @@ else # needing to exist. TEST_DIRECTORY=$(cd "$TEST_DIRECTORY" && pwd) || exit 1 fi -if test -z "$TEST_OUTPUT_DIRECTORY" -then - # Similarly, override this to store the test-results subdir - # elsewhere - TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY -fi -GIT_BUILD_DIR="${TEST_DIRECTORY%/t}" +GIT_BUILD_DIR="${GIT_BUILD_DIR:-${TEST_DIRECTORY%/t}}" if test "$TEST_DIRECTORY" = "$GIT_BUILD_DIR" then echo "PANIC: Running in a $TEST_DIRECTORY that doesn't end in '/t'?" >&2 @@ -86,12 +80,22 @@ prepend_var ASAN_OPTIONS : detect_leaks=0 export ASAN_OPTIONS prepend_var LSAN_OPTIONS : $GIT_SAN_OPTIONS +prepend_var LSAN_OPTIONS : exitcode=0 prepend_var LSAN_OPTIONS : fast_unwind_on_malloc=0 export LSAN_OPTIONS prepend_var UBSAN_OPTIONS : $GIT_SAN_OPTIONS export UBSAN_OPTIONS +# The TEST_OUTPUT_DIRECTORY will be overwritten via GIT-BUILD-OPTIONS. So in +# case the caller has manually set up this variable via the environment we must +# make sure to not overwrite that value, and thus we save it into +# TEST_OUTPUT_DIRECTORY_OVERRIDE here. +if test -n "$TEST_OUTPUT_DIRECTORY" && test -z "$TEST_OUTPUT_DIRECTORY_OVERRIDE" +then + TEST_OUTPUT_DIRECTORY_OVERRIDE=$TEST_OUTPUT_DIRECTORY +fi + if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS then echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).' @@ -100,6 +104,13 @@ fi . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS export PERL_PATH SHELL_PATH +if test -z "$TEST_OUTPUT_DIRECTORY" +then + # Similarly, override this to store the test-results subdir + # elsewhere + TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY +fi + # In t0000, we need to override test directories of nested testcases. In case # the developer has TEST_OUTPUT_DIRECTORY part of his build options, then we'd # reset this value to instead contain what the developer has specified. We thus @@ -321,8 +332,7 @@ TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX" TEST_RESULTS_SAN_FILE_PFX=trace TEST_RESULTS_SAN_DIR_SFX=leak TEST_RESULTS_SAN_FILE= -TEST_RESULTS_SAN_DIR="$TEST_RESULTS_DIR/$TEST_NAME.$TEST_RESULTS_SAN_DIR_SFX" -TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP= +TEST_RESULTS_SAN_DIR="$TEST_RESULTS_BASE.$TEST_RESULTS_SAN_DIR_SFX" TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX" test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY" case "$TRASH_DIRECTORY" in @@ -330,17 +340,6 @@ case "$TRASH_DIRECTORY" in *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;; esac -# Utility functions using $TEST_RESULTS_* variables -nr_san_dir_leaks_ () { - # stderr piped to /dev/null because the directory may have - # been "rmdir"'d already. - find "$TEST_RESULTS_SAN_DIR" \ - -type f \ - -name "$TEST_RESULTS_SAN_FILE_PFX.*" 2>/dev/null | - xargs grep -lv "Unable to get registers from thread" | - wc -l -} - # If --stress was passed, run this test repeatedly in several parallel loops. if test "$GIT_TEST_STRESS_STARTED" = "done" then @@ -513,6 +512,7 @@ unset VISUAL EMAIL LANGUAGE $("$PERL_PATH" -e ' PERF_ CURL_VERBOSE TRACE_CURL + BUILD_DIR )); my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env); print join("\n", @vars); @@ -578,53 +578,6 @@ case $GIT_TEST_FSYNC in ;; esac -# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing -# the test with valgrind and have not compiled with conflict SANITIZE -# options. -if test -n "$valgrind" || - test -n "$SANITIZE_ADDRESS" || - test -n "$SANITIZE_LEAK" || - test -n "$TEST_NO_MALLOC_CHECK" -then - setup_malloc_check () { - : nothing - } - teardown_malloc_check () { - : nothing - } -else - _USE_GLIBC_TUNABLES= - if _GLIBC_VERSION=$(getconf GNU_LIBC_VERSION 2>/dev/null) && - _GLIBC_VERSION=${_GLIBC_VERSION#"glibc "} && - expr 2.34 \<= "$_GLIBC_VERSION" >/dev/null - then - _USE_GLIBC_TUNABLES=YesPlease - fi - setup_malloc_check () { - local g - local t - MALLOC_CHECK_=3 MALLOC_PERTURB_=165 - export MALLOC_CHECK_ MALLOC_PERTURB_ - if test -n "$_USE_GLIBC_TUNABLES" - then - g= - LD_PRELOAD="libc_malloc_debug.so.0" - for t in \ - glibc.malloc.check=1 \ - glibc.malloc.perturb=165 - do - g="${g#:}:$t" - done - GLIBC_TUNABLES=$g - export LD_PRELOAD GLIBC_TUNABLES - fi - } - teardown_malloc_check () { - unset MALLOC_CHECK_ MALLOC_PERTURB_ - unset LD_PRELOAD GLIBC_TUNABLES - } -fi - # Protect ourselves from common misconfiguration to export # CDPATH into the environment unset CDPATH @@ -848,6 +801,7 @@ test_failure_ () { GIT_EXIT_OK=t exit 0 fi + check_test_results_san_file_ "$test_failure" _error_exit fi finalize_test_case_output failure "$failure_label" "$@" @@ -1215,61 +1169,26 @@ test_atexit_handler () { teardown_malloc_check } -sanitize_leak_log_message_ () { - local new="$1" && - local old="$2" && - local file="$3" && - - printf "With SANITIZE=leak at exit we have %d leak logs, but started with %d +check_test_results_san_file_has_entries_ () { + test -z "$TEST_RESULTS_SAN_FILE" && return 1 -This means that we have a blindspot where git is leaking but we're -losing the exit code somewhere, or not propagating it appropriately -upwards! - -See the logs at \"%s.*\"; -those logs are reproduced below." \ - "$new" "$old" "$file" + # Lines marked with DEDUP_TOKEN show unique leaks. We only care that we + # found at least one. + # + # But also suppress any false positives caused by bugs or races in the + # sanitizer itself. + grep -s ^DEDUP_TOKEN "$TEST_RESULTS_SAN_FILE".* | + grep -qv sanitizer::GetThreadStackTopAndBottom } check_test_results_san_file_ () { - if test -z "$TEST_RESULTS_SAN_FILE" + if ! check_test_results_san_file_has_entries_ then return fi && - local old="$TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP" && - local new="$(nr_san_dir_leaks_)" && - - if test $new -le $old - then - return - fi && - local out="$(sanitize_leak_log_message_ "$new" "$old" "$TEST_RESULTS_SAN_FILE")" && - say_color error "$out" && - if test "$old" != 0 - then - echo && - say_color error "The logs include output from past runs to avoid" && - say_color error "that remove 'test-results' between runs." - fi && say_color error "$(cat "$TEST_RESULTS_SAN_FILE".*)" && - if test -n "$passes_sanitize_leak" && test "$test_failure" = 0 - then - say "As TEST_PASSES_SANITIZE_LEAK=true and our logs show we're leaking, exit non-zero!" && - invert_exit_code=t - elif test -n "$passes_sanitize_leak" - then - say "As TEST_PASSES_SANITIZE_LEAK=true and our logs show we're leaking, and we're failing for other reasons too..." && - invert_exit_code= - elif test -n "$sanitize_leak_check" && test "$test_failure" = 0 - then - say "As TEST_PASSES_SANITIZE_LEAK=true isn't set the above leak is 'ok' with GIT_TEST_PASSING_SANITIZE_LEAK=check" && - invert_exit_code= - elif test -n "$sanitize_leak_check" - then - say "As TEST_PASSES_SANITIZE_LEAK=true isn't set the above leak is 'ok' with GIT_TEST_PASSING_SANITIZE_LEAK=check" && - invert_exit_code=t - elif test "$test_failure" = 0 + if test "$test_failure" = 0 then say "Our logs revealed a memory leak, exit non-zero!" && invert_exit_code=t @@ -1300,11 +1219,6 @@ 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)" @@ -1503,12 +1417,62 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH" fi fi -GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt +GIT_TEMPLATE_DIR="$GIT_TEST_TEMPLATE_DIR" GIT_CONFIG_NOSYSTEM=1 GIT_ATTR_NOSYSTEM=1 GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.." export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM GIT_CEILING_DIRECTORIES +# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing +# the test with valgrind and have not compiled with conflict SANITIZE +# options. +if test -n "$valgrind" || + test -n "$SANITIZE_ADDRESS" || + test -n "$SANITIZE_LEAK" || + test -n "$TEST_NO_MALLOC_CHECK" +then + setup_malloc_check () { + : nothing + } + teardown_malloc_check () { + : nothing + } +else + _USE_GLIBC_TUNABLES= + _USE_GLIBC_PRELOAD=libc_malloc_debug.so.0 + if _GLIBC_VERSION=$(getconf GNU_LIBC_VERSION 2>/dev/null) && + _GLIBC_VERSION=${_GLIBC_VERSION#"glibc "} && + expr 2.34 \<= "$_GLIBC_VERSION" >/dev/null && + stderr=$(LD_PRELOAD=$_USE_GLIBC_PRELOAD git version 2>&1 >/dev/null) && + test -z "$stderr" + then + _USE_GLIBC_TUNABLES=YesPlease + fi + setup_malloc_check () { + local g + local t + MALLOC_CHECK_=3 MALLOC_PERTURB_=165 + export MALLOC_CHECK_ MALLOC_PERTURB_ + if test -n "$_USE_GLIBC_TUNABLES" + then + g= + LD_PRELOAD=$_USE_GLIBC_PRELOAD + for t in \ + glibc.malloc.check=1 \ + glibc.malloc.perturb=165 + do + g="${g#:}:$t" + done + GLIBC_TUNABLES=$g + export LD_PRELOAD GLIBC_TUNABLES + fi + } + teardown_malloc_check () { + unset MALLOC_CHECK_ MALLOC_PERTURB_ + unset LD_PRELOAD GLIBC_TUNABLES + } +fi + if test -z "$GIT_TEST_CMP" then if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT" @@ -1519,9 +1483,9 @@ then fi fi -GITPERLLIB="$GIT_BUILD_DIR"/perl/build/lib +GITPERLLIB="$GIT_TEST_GITPERLLIB" export GITPERLLIB -test -d "$GIT_BUILD_DIR"/templates/blt || { +test -d "$GIT_TEMPLATE_DIR" || { BAIL_OUT "You haven't built things yet, have you?" } @@ -1541,74 +1505,22 @@ then test_done fi -BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK () { - BAIL_OUT "$1 has no effect except when compiled with SANITIZE=leak" -} - if test -n "$SANITIZE_LEAK" then - # Normalize with test_bool_env - passes_sanitize_leak= - - # We need to see TEST_PASSES_SANITIZE_LEAK in "test-tool - # env-helper" (via test_bool_env) - export TEST_PASSES_SANITIZE_LEAK - if test_bool_env TEST_PASSES_SANITIZE_LEAK false - then - passes_sanitize_leak=t - fi - - if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" || - test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" - then - if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" && - test -n "$passes_sanitize_leak" - then - skip_all="skipping leak-free $this_test under GIT_TEST_PASSING_SANITIZE_LEAK=check-failing" - test_done - fi - - sanitize_leak_check=t - if test -n "$invert_exit_code" - then - BAIL_OUT "cannot use --invert-exit-code under GIT_TEST_PASSING_SANITIZE_LEAK=check" - fi - - if test -z "$passes_sanitize_leak" - then - say "in GIT_TEST_PASSING_SANITIZE_LEAK=check mode, setting --invert-exit-code for TEST_PASSES_SANITIZE_LEAK != true" - invert_exit_code=t - fi - elif test -z "$passes_sanitize_leak" && - test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false - then - skip_all="skipping $this_test under GIT_TEST_PASSING_SANITIZE_LEAK=true" - test_done - fi - + rm -rf "$TEST_RESULTS_SAN_DIR" if ! mkdir -p "$TEST_RESULTS_SAN_DIR" then BAIL_OUT "cannot create $TEST_RESULTS_SAN_DIR" fi && TEST_RESULTS_SAN_FILE="$TEST_RESULTS_SAN_DIR/$TEST_RESULTS_SAN_FILE_PFX" - # In case "test-results" is left over from a previous - # run: Only report if new leaks show up. - TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP=$(nr_san_dir_leaks_) - # Don't litter *.leak dirs if there was nothing to report test_atexit "rmdir \"$TEST_RESULTS_SAN_DIR\" 2>/dev/null || :" prepend_var LSAN_OPTIONS : dedup_token_length=9999 prepend_var LSAN_OPTIONS : log_exe_name=1 - prepend_var LSAN_OPTIONS : log_path=\"$TEST_RESULTS_SAN_FILE\" + prepend_var LSAN_OPTIONS : log_path="'$TEST_RESULTS_SAN_FILE'" export LSAN_OPTIONS - -elif test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" || - test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" || - test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false -then - BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_PASSING_SANITIZE_LEAK=true" fi if test "${GIT_TEST_CHAIN_LINT:-1}" != 0 && @@ -1772,6 +1684,8 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_CURL" && test_set_prereq LIBCURL +test -z "$NO_GITWEB" && test_set_prereq GITWEB +test -z "$NO_ICONV" && test_set_prereq ICONV test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PTHREADS" && test_set_prereq PTHREADS test -z "$NO_PYTHON" && test_set_prereq PYTHON @@ -1948,6 +1862,10 @@ test_lazy_prereq CURL ' curl --version ' +test_lazy_prereq WITHOUT_BREAKING_CHANGES ' + test -z "$WITH_BREAKING_CHANGES" +' + # SHA1 is a test if the hash algorithm in use is SHA-1. This is both for tests # which will not work with other hash algorithms and tests that work but don't # test anything meaningful (e.g. special values which cause short collisions). diff --git a/t/test-terminal.perl b/t/test-terminal.perl index b8fd6a4f1338b0..862bb8f3952914 100755 --- a/t/test-terminal.perl +++ b/t/test-terminal.perl @@ -1,5 +1,5 @@ #!/usr/bin/perl -use 5.008001; +require v5.26; use strict; use warnings; use IO::Pty; diff --git a/t/unit-tests/clar-generate.awk b/t/unit-tests/clar-generate.awk deleted file mode 100644 index ab71ce6c9fc2c3..00000000000000 --- a/t/unit-tests/clar-generate.awk +++ /dev/null @@ -1,50 +0,0 @@ -function add_suite(suite, initialize, cleanup, count) { - if (!suite) return - suite_count++ - callback_count += count - suites = suites " {\n" - suites = suites " \"" suite "\",\n" - suites = suites " " initialize ",\n" - suites = suites " " cleanup ",\n" - suites = suites " _clar_cb_" suite ", " count ", 1\n" - suites = suites " },\n" -} - -BEGIN { - suites = "static struct clar_suite _clar_suites[] = {\n" -} - -{ - print - name = $3; sub(/\(.*$/, "", name) - suite = name; sub(/^test_/, "", suite); sub(/__.*$/, "", suite) - short_name = name; sub(/^.*__/, "", short_name) - cb = "{ \"" short_name "\", &" name " }" - if (suite != prev_suite) { - add_suite(prev_suite, initialize, cleanup, count) - if (callbacks) callbacks = callbacks "};\n" - callbacks = callbacks "static const struct clar_func _clar_cb_" suite "[] = {\n" - initialize = "{ NULL, NULL }" - cleanup = "{ NULL, NULL }" - count = 0 - prev_suite = suite - } - if (short_name == "initialize") { - initialize = cb - } else if (short_name == "cleanup") { - cleanup = cb - } else { - callbacks = callbacks " " cb ",\n" - count++ - } -} - -END { - add_suite(suite, initialize, cleanup, count) - suites = suites "};" - if (callbacks) callbacks = callbacks "};" - print callbacks - print suites - print "static const size_t _clar_suite_count = " suite_count ";" - print "static const size_t _clar_callback_count = " callback_count ";" -} diff --git a/t/unit-tests/clar/.editorconfig b/t/unit-tests/clar/.editorconfig new file mode 100644 index 00000000000000..aa343a42885ac7 --- /dev/null +++ b/t/unit-tests/clar/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +charset = utf-8 +insert_final_newline = true + +[*.{c,h}] +indent_style = tab +tab_width = 8 + +[CMakeLists.txt] +indent_style = tab +tab_width = 8 diff --git a/t/unit-tests/clar/.github/workflows/ci.yml b/t/unit-tests/clar/.github/workflows/ci.yml index b1ac2de460af9e..0065843d17aa8b 100644 --- a/t/unit-tests/clar/.github/workflows/ci.yml +++ b/t/unit-tests/clar/.github/workflows/ci.yml @@ -10,14 +10,26 @@ jobs: build: strategy: matrix: - os: [ ubuntu-latest, macos-latest ] + platform: + - os: ubuntu-latest + generator: Unix Makefiles + - os: macos-latest + generator: Unix Makefiles + - os: windows-latest + generator: Visual Studio 17 2022 + - os: windows-latest + generator: MSYS Makefiles + - os: windows-latest + generator: MinGW Makefiles - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.platform.os }} steps: - name: Check out uses: actions/checkout@v2 - name: Build run: | - cd test - make + mkdir build + cd build + cmake .. -G "${{matrix.platform.generator}}" + cmake --build . diff --git a/t/unit-tests/clar/.gitignore b/t/unit-tests/clar/.gitignore new file mode 100644 index 00000000000000..84c048a73cc2e5 --- /dev/null +++ b/t/unit-tests/clar/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/t/unit-tests/clar/CMakeLists.txt b/t/unit-tests/clar/CMakeLists.txt new file mode 100644 index 00000000000000..12d4af114fe3b3 --- /dev/null +++ b/t/unit-tests/clar/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16..3.29) + +project(clar LANGUAGES C) + +option(BUILD_TESTS "Build test executable" ON) + +add_library(clar INTERFACE) +target_sources(clar INTERFACE + clar.c + clar.h + clar/fixtures.h + clar/fs.h + clar/print.h + clar/sandbox.h + clar/summary.h +) +set_target_properties(clar PROPERTIES + C_STANDARD 90 + C_STANDARD_REQUIRED ON + C_EXTENSIONS OFF +) + +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + include(CTest) + if(BUILD_TESTING) + add_subdirectory(test) + endif() +endif() diff --git a/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c index cef0f023c24bb3..d54e4553674908 100644 --- a/t/unit-tests/clar/clar.c +++ b/t/unit-tests/clar/clar.c @@ -4,7 +4,12 @@ * This file is part of clar, distributed under the ISC license. * For full terms see the included COPYING file. */ -#include <assert.h> + +#define _BSD_SOURCE +#define _DARWIN_C_SOURCE +#define _DEFAULT_SOURCE + +#include <errno.h> #include <setjmp.h> #include <stdlib.h> #include <stdio.h> @@ -13,11 +18,22 @@ #include <stdarg.h> #include <wchar.h> #include <time.h> +#include <inttypes.h> /* required for sandboxing */ #include <sys/types.h> #include <sys/stat.h> +#if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_WCHAR__) + /* + * uClibc can optionally be built without wchar support, in which case + * the installed <wchar.h> is a stub that only defines the `whar_t` + * type but none of the functions typically declared by it. + */ +#else +# define CLAR_HAVE_WCHAR +#endif + #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> @@ -28,6 +44,9 @@ # ifndef stat # define stat(path, st) _stat(path, st) + typedef struct _stat STAT_T; +# else + typedef struct stat STAT_T; # endif # ifndef mkdir # define mkdir(path, mode) _mkdir(path) @@ -60,30 +79,11 @@ # else # define p_snprintf snprintf # endif - -# ifndef PRIuZ -# define PRIuZ "Iu" -# endif -# ifndef PRIxZ -# define PRIxZ "Ix" -# endif - -# if defined(_MSC_VER) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) - typedef struct stat STAT_T; -# else - typedef struct _stat STAT_T; -# endif #else # include <sys/wait.h> /* waitpid(2) */ # include <unistd.h> # define _MAIN_CC # define p_snprintf snprintf -# ifndef PRIuZ -# define PRIuZ "zu" -# endif -# ifndef PRIxZ -# define PRIxZ "zx" -# endif typedef struct stat STAT_T; #endif @@ -102,7 +102,7 @@ fixture_path(const char *base, const char *fixture_name); struct clar_error { const char *file; const char *function; - size_t line_number; + uintmax_t line_number; const char *error_msg; char *description; @@ -195,11 +195,12 @@ static void clar_print_shutdown(int test_count, int suite_count, int error_count static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error); static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed); static void clar_print_onsuite(const char *suite_name, int suite_index); +static void clar_print_onabortv(const char *msg, va_list argp); static void clar_print_onabort(const char *msg, ...); /* From clar_sandbox.c */ static void clar_unsandbox(void); -static int clar_sandbox(void); +static void clar_sandbox(void); /* From summary.h */ static struct clar_summary *clar_summary_init(const char *filename); @@ -218,6 +219,15 @@ static int clar_summary_shutdown(struct clar_summary *fp); _clar.trace_payload); \ } while (0) +static void clar_abort(const char *msg, ...) +{ + va_list argp; + va_start(argp, msg); + clar_print_onabortv(msg, argp); + va_end(argp); + exit(-1); +} + void cl_trace_register(cl_trace_cb *cb, void *payload) { _clar.pfn_trace_cb = cb; @@ -271,9 +281,7 @@ static double clar_time_diff(clar_time *start, clar_time *end) static void clar_time_now(clar_time *out) { - struct timezone tz; - - gettimeofday(out, &tz); + gettimeofday(out, NULL); } static double clar_time_diff(clar_time *start, clar_time *end) @@ -386,7 +394,8 @@ clar_run_suite(const struct clar_suite *suite, const char *filter) _clar.active_test = test[i].name; - report = calloc(1, sizeof(struct clar_report)); + if ((report = calloc(1, sizeof(*report))) == NULL) + clar_abort("Failed to allocate report.\n"); report->suite = _clar.active_suite; report->test = _clar.active_test; report->test_number = _clar.tests_ran; @@ -479,9 +488,10 @@ clar_parse_args(int argc, char **argv) switch (action) { case 's': { - struct clar_explicit *explicit = - calloc(1, sizeof(struct clar_explicit)); - assert(explicit); + struct clar_explicit *explicit; + + if ((explicit = calloc(1, sizeof(*explicit))) == NULL) + clar_abort("Failed to allocate explicit test.\n"); explicit->suite_idx = j; explicit->filter = argument; @@ -505,10 +515,8 @@ clar_parse_args(int argc, char **argv) } } - if (!found) { - clar_print_onabort("No suite matching '%s' found.\n", argument); - exit(-1); - } + if (!found) + clar_abort("No suite matching '%s' found.\n", argument); break; } @@ -540,11 +548,17 @@ clar_parse_args(int argc, char **argv) case 'r': _clar.write_summary = 1; free(_clar.summary_filename); - _clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL; + if (*(argument + 2)) { + if ((_clar.summary_filename = strdup(argument + 2)) == NULL) + clar_abort("Failed to allocate summary filename.\n"); + } else { + _clar.summary_filename = NULL; + } break; default: - assert(!"Unexpected commandline argument!"); + clar_abort("Unexpected commandline argument '%s'.\n", + argument[1]); } } } @@ -566,22 +580,18 @@ clar_test_init(int argc, char **argv) if (!_clar.summary_filename && (summary_env = getenv("CLAR_SUMMARY")) != NULL) { _clar.write_summary = 1; - _clar.summary_filename = strdup(summary_env); + if ((_clar.summary_filename = strdup(summary_env)) == NULL) + clar_abort("Failed to allocate summary filename.\n"); } if (_clar.write_summary && !_clar.summary_filename) - _clar.summary_filename = strdup("summary.xml"); + if ((_clar.summary_filename = strdup("summary.xml")) == NULL) + clar_abort("Failed to allocate summary filename.\n"); - if (_clar.write_summary && - !(_clar.summary = clar_summary_init(_clar.summary_filename))) { - clar_print_onabort("Failed to open the summary file\n"); - exit(-1); - } + if (_clar.write_summary) + _clar.summary = clar_summary_init(_clar.summary_filename); - if (clar_sandbox() < 0) { - clar_print_onabort("Failed to sandbox the test runner.\n"); - exit(-1); - } + clar_sandbox(); } int @@ -615,10 +625,9 @@ clar_test_shutdown(void) clar_unsandbox(); - if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) { - clar_print_onabort("Failed to write the summary file\n"); - exit(-1); - } + if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) + clar_abort("Failed to write the summary file '%s: %s.\n", + _clar.summary_filename, strerror(errno)); for (explicit = _clar.explicit; explicit; explicit = explicit_next) { explicit_next = explicit->next; @@ -649,7 +658,7 @@ static void abort_test(void) { if (!_clar.trampoline_enabled) { clar_print_onabort( - "Fatal error: a cleanup method raised an exception."); + "Fatal error: a cleanup method raised an exception.\n"); clar_report_errors(_clar.last_report); exit(-1); } @@ -673,7 +682,10 @@ void clar__fail( const char *description, int should_abort) { - struct clar_error *error = calloc(1, sizeof(struct clar_error)); + struct clar_error *error; + + if ((error = calloc(1, sizeof(*error))) == NULL) + clar_abort("Failed to allocate error.\n"); if (_clar.last_report->errors == NULL) _clar.last_report->errors = error; @@ -688,8 +700,9 @@ void clar__fail( error->line_number = line; error->error_msg = error_msg; - if (description != NULL) - error->description = strdup(description); + if (description != NULL && + (error->description = strdup(description)) == NULL) + clar_abort("Failed to allocate description.\n"); _clar.total_errors++; _clar.last_report->status = CL_TEST_FAILURE; @@ -763,6 +776,7 @@ void clar__assert_equal( } } } +#ifdef CLAR_HAVE_WCHAR else if (!strcmp("%ls", fmt)) { const wchar_t *wcs1 = va_arg(args, const wchar_t *); const wchar_t *wcs2 = va_arg(args, const wchar_t *); @@ -798,8 +812,9 @@ void clar__assert_equal( } } } - else if (!strcmp("%"PRIuZ, fmt) || !strcmp("%"PRIxZ, fmt)) { - size_t sz1 = va_arg(args, size_t), sz2 = va_arg(args, size_t); +#endif /* CLAR_HAVE_WCHAR */ + else if (!strcmp("%"PRIuMAX, fmt) || !strcmp("%"PRIxMAX, fmt)) { + uintmax_t sz1 = va_arg(args, uintmax_t), sz2 = va_arg(args, uintmax_t); is_equal = (sz1 == sz2); if (!is_equal) { int offset = p_snprintf(buf, sizeof(buf), fmt, sz1); diff --git a/t/unit-tests/clar/clar/print.h b/t/unit-tests/clar/clar/print.h index c17e2f693bdc52..69d0ee967e7475 100644 --- a/t/unit-tests/clar/clar/print.h +++ b/t/unit-tests/clar/clar/print.h @@ -21,7 +21,7 @@ static void clar_print_clap_error(int num, const struct clar_report *report, con { printf(" %d) Failure:\n", num); - printf("%s::%s [%s:%"PRIuZ"]\n", + printf("%s::%s [%s:%"PRIuMAX"]\n", report->suite, report->test, error->file, @@ -136,7 +136,7 @@ static void clar_print_tap_ontest(const char *suite_name, const char *test_name, printf(" at:\n"); printf(" file: '"); print_escaped(error->file); printf("'\n"); - printf(" line: %" PRIuZ "\n", error->line_number); + printf(" line: %" PRIuMAX "\n", error->line_number); printf(" function: '%s'\n", error->function); printf(" ---\n"); @@ -202,10 +202,15 @@ static void clar_print_onsuite(const char *suite_name, int suite_index) PRINT(onsuite, suite_name, suite_index); } +static void clar_print_onabortv(const char *msg, va_list argp) +{ + PRINT(onabort, msg, argp); +} + static void clar_print_onabort(const char *msg, ...) { va_list argp; va_start(argp, msg); - PRINT(onabort, msg, argp); + clar_print_onabortv(msg, argp); va_end(argp); } diff --git a/t/unit-tests/clar/clar/sandbox.h b/t/unit-tests/clar/clar/sandbox.h index e25057b7c490e0..bc960f50e0f2ec 100644 --- a/t/unit-tests/clar/clar/sandbox.h +++ b/t/unit-tests/clar/clar/sandbox.h @@ -122,14 +122,14 @@ static int build_sandbox_path(void) if (mkdir(_clar_path, 0700) != 0) return -1; -#elif defined(__TANDEM) - if (mktemp(_clar_path) == NULL) +#elif defined(_WIN32) + if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0) return -1; if (mkdir(_clar_path, 0700) != 0) return -1; -#elif defined(_WIN32) - if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0) +#elif defined(__sun) || defined(__TANDEM) + if (mktemp(_clar_path) == NULL) return -1; if (mkdir(_clar_path, 0700) != 0) @@ -142,15 +142,14 @@ static int build_sandbox_path(void) return 0; } -static int clar_sandbox(void) +static void clar_sandbox(void) { if (_clar_path[0] == '\0' && build_sandbox_path() < 0) - return -1; + clar_abort("Failed to build sandbox path.\n"); if (chdir(_clar_path) != 0) - return -1; - - return 0; + clar_abort("Failed to change into sandbox directory '%s': %s.\n", + _clar_path, strerror(errno)); } const char *clar_sandbox_path(void) diff --git a/t/unit-tests/clar/clar/summary.h b/t/unit-tests/clar/clar/summary.h index 4dd352e28b8363..0d0b646fe7514b 100644 --- a/t/unit-tests/clar/clar/summary.h +++ b/t/unit-tests/clar/clar/summary.h @@ -66,16 +66,12 @@ struct clar_summary *clar_summary_init(const char *filename) struct clar_summary *summary; FILE *fp; - if ((fp = fopen(filename, "w")) == NULL) { - perror("fopen"); - return NULL; - } + if ((fp = fopen(filename, "w")) == NULL) + clar_abort("Failed to open the summary file '%s': %s.\n", + filename, strerror(errno)); - if ((summary = malloc(sizeof(struct clar_summary))) == NULL) { - perror("malloc"); - fclose(fp); - return NULL; - } + if ((summary = malloc(sizeof(struct clar_summary))) == NULL) + clar_abort("Failed to allocate summary.\n"); summary->filename = filename; summary->fp = fp; diff --git a/t/unit-tests/clar/test/.gitignore b/t/unit-tests/clar/test/.gitignore deleted file mode 100644 index a477d0c40ca262..00000000000000 --- a/t/unit-tests/clar/test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -clar.suite -.clarcache -clar_test -*.o diff --git a/t/unit-tests/clar/test/CMakeLists.txt b/t/unit-tests/clar/test/CMakeLists.txt new file mode 100644 index 00000000000000..7f2c1dc17a9ac0 --- /dev/null +++ b/t/unit-tests/clar/test/CMakeLists.txt @@ -0,0 +1,39 @@ +find_package(Python COMPONENTS Interpreter REQUIRED) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/clar.suite" + COMMAND "${Python_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/generate.py" --output "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS main.c sample.c clar_test.h + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" +) + +add_executable(clar_test) +set_target_properties(clar_test PROPERTIES + C_STANDARD 90 + C_STANDARD_REQUIRED ON + C_EXTENSIONS OFF +) + +# MSVC generates all kinds of warnings. We may want to fix these in the future +# and then unconditionally treat warnings as errors. +if(NOT MSVC) + set_target_properties(clar_test PROPERTIES + COMPILE_WARNING_AS_ERROR ON + ) +endif() + +target_sources(clar_test PRIVATE + main.c + sample.c + "${CMAKE_CURRENT_BINARY_DIR}/clar.suite" +) +target_compile_definitions(clar_test PRIVATE + CLAR_FIXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/" +) +target_compile_options(clar_test PRIVATE + $<IF:$<CXX_COMPILER_ID:MSVC>,/W4,-Wall> +) +target_include_directories(clar_test PRIVATE + "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" +) +target_link_libraries(clar_test clar) diff --git a/t/unit-tests/clar/test/Makefile b/t/unit-tests/clar/test/Makefile deleted file mode 100644 index 93c6b2ad32c2ce..00000000000000 --- a/t/unit-tests/clar/test/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (c) Vicent Marti. All rights reserved. -# -# This file is part of clar, distributed under the ISC license. -# For full terms see the included COPYING file. -# - -# -# Set up the path to the clar sources and to the fixtures directory -# -# The fixture path needs to be an absolute path so it can be used -# even after we have chdir'ed into the test directory while testing. -# -CURRENT_MAKEFILE := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) -TEST_DIRECTORY := $(abspath $(dir $(CURRENT_MAKEFILE))) -CLAR_PATH := $(dir $(TEST_DIRECTORY)) -CLAR_FIXTURE_PATH := $(TEST_DIRECTORY)/resources/ - -CFLAGS=-g -I.. -I. -Wall -DCLAR_FIXTURE_PATH=\"$(CLAR_FIXTURE_PATH)\" - -.PHONY: clean - -# list the objects that go into our test -objects = main.o sample.o - -# build the test executable itself -clar_test: $(objects) clar_test.h clar.suite $(CLAR_PATH)clar.c - $(CC) $(CFLAGS) -o $@ "$(CLAR_PATH)clar.c" $(objects) - -# test object files depend on clar macros -$(objects) : $(CLAR_PATH)clar.h - -# build the clar.suite file of test metadata -clar.suite: - python "$(CLAR_PATH)generate.py" . - -# remove all generated files -clean: - $(RM) -rf *.o clar.suite .clarcache clar_test clar_test.dSYM diff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh new file mode 100755 index 00000000000000..abf6a2ea2a615e --- /dev/null +++ b/t/unit-tests/generate-clar-decls.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +if test $# -lt 2 +then + echo "USAGE: $0 <OUTPUT> <SUITE>..." 2>&1 + exit 1 +fi + +OUTPUT="$1" +shift + +for suite in "$@" +do + suite_name=$(basename "$suite") + suite_name=${suite_name%.c} + suite_name=${suite_name#u-} + suite_name=$(echo "$suite_name" | tr '-' '_') + sed -ne "s/^\(void test_${suite_name}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\)$/extern \1;/p" "$suite" || + exit 1 +done >"$OUTPUT" diff --git a/t/unit-tests/generate-clar-suites.sh b/t/unit-tests/generate-clar-suites.sh new file mode 100755 index 00000000000000..d5c712221e46a2 --- /dev/null +++ b/t/unit-tests/generate-clar-suites.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +if test $# -lt 2 +then + echo "USAGE: $0 <CLAR_DECLS_H> <OUTPUT>" 2>&1 + exit 1 +fi + +CLAR_DECLS_H="$1" +OUTPUT="$2" + +awk ' + function add_suite(suite, initialize, cleanup, count) { + if (!suite) return + suite_count++ + callback_count += count + suites = suites " {\n" + suites = suites " \"" suite "\",\n" + suites = suites " " initialize ",\n" + suites = suites " " cleanup ",\n" + suites = suites " _clar_cb_" suite ", " count ", 1\n" + suites = suites " },\n" + } + + BEGIN { + suites = "static struct clar_suite _clar_suites[] = {\n" + } + + { + print + name = $3; sub(/\(.*$/, "", name) + suite = name; sub(/^test_/, "", suite); sub(/__.*$/, "", suite) + short_name = name; sub(/^.*__/, "", short_name) + cb = "{ \"" short_name "\", &" name " }" + if (suite != prev_suite) { + add_suite(prev_suite, initialize, cleanup, count) + if (callbacks) callbacks = callbacks "};\n" + callbacks = callbacks "static const struct clar_func _clar_cb_" suite "[] = {\n" + initialize = "{ NULL, NULL }" + cleanup = "{ NULL, NULL }" + count = 0 + prev_suite = suite + } + if (short_name == "initialize") { + initialize = cb + } else if (short_name == "cleanup") { + cleanup = cb + } else { + callbacks = callbacks " " cb ",\n" + count++ + } + } + + END { + add_suite(suite, initialize, cleanup, count) + suites = suites "};" + if (callbacks) callbacks = callbacks "};" + print callbacks + print suites + print "static const size_t _clar_suite_count = " suite_count ";" + print "static const size_t _clar_callback_count = " callback_count ";" + } +' "$CLAR_DECLS_H" >"$OUTPUT" diff --git a/t/unit-tests/lib-oid.c b/t/unit-tests/lib-oid.c index 8f0ccac5328247..e0b3180f23c018 100644 --- a/t/unit-tests/lib-oid.c +++ b/t/unit-tests/lib-oid.c @@ -1,9 +1,9 @@ -#include "test-lib.h" +#include "unit-test.h" #include "lib-oid.h" #include "strbuf.h" #include "hex.h" -int init_hash_algo(void) +int cl_setup_hash_algo(void) { static int algo = -1; @@ -11,42 +11,32 @@ int init_hash_algo(void) const char *algo_name = getenv("GIT_TEST_DEFAULT_HASH"); algo = algo_name ? hash_algo_by_name(algo_name) : GIT_HASH_SHA1; - if (!check(algo != GIT_HASH_UNKNOWN)) - test_msg("BUG: invalid GIT_TEST_DEFAULT_HASH value ('%s')", - algo_name); + cl_assert(algo != GIT_HASH_UNKNOWN); } return algo; } -static int get_oid_arbitrary_hex_algop(const char *hex, struct object_id *oid, +static void cl_parse_oid(const char *hex, struct object_id *oid, const struct git_hash_algo *algop) { - int ret; size_t sz = strlen(hex); struct strbuf buf = STRBUF_INIT; - if (!check(sz <= algop->hexsz)) { - test_msg("BUG: hex string (%s) bigger than maximum allowed (%lu)", - hex, (unsigned long)algop->hexsz); - return -1; - } + cl_assert(sz <= algop->hexsz); strbuf_add(&buf, hex, sz); strbuf_addchars(&buf, '0', algop->hexsz - sz); - ret = get_oid_hex_algop(buf.buf, oid, algop); - if (!check_int(ret, ==, 0)) - test_msg("BUG: invalid hex input (%s) provided", hex); + cl_assert_equal_i(get_oid_hex_algop(buf.buf, oid, algop), 0); strbuf_release(&buf); - return ret; } -int get_oid_arbitrary_hex(const char *hex, struct object_id *oid) + +void cl_parse_any_oid(const char *hex, struct object_id *oid) { - int hash_algo = init_hash_algo(); + int hash_algo = cl_setup_hash_algo(); - if (!check_int(hash_algo, !=, GIT_HASH_UNKNOWN)) - return -1; - return get_oid_arbitrary_hex_algop(hex, oid, &hash_algos[hash_algo]); + cl_assert(hash_algo != GIT_HASH_UNKNOWN); + cl_parse_oid(hex, oid, &hash_algos[hash_algo]); } diff --git a/t/unit-tests/lib-oid.h b/t/unit-tests/lib-oid.h index 4e77c04bd224e6..4031775104906d 100644 --- a/t/unit-tests/lib-oid.h +++ b/t/unit-tests/lib-oid.h @@ -5,6 +5,7 @@ /* * Convert arbitrary hex string to object_id. + * * For example, passing "abc12" will generate * "abc1200000000000000000000000000000000000" hex of length 40 for SHA-1 and * create object_id with that. @@ -12,14 +13,16 @@ * algo is not allowed. The hash algo is decided based on GIT_TEST_DEFAULT_HASH * environment variable. */ -int get_oid_arbitrary_hex(const char *s, struct object_id *oid); + +void cl_parse_any_oid (const char *s, struct object_id *oid); /* * Returns one of GIT_HASH_{SHA1, SHA256, UNKNOWN} based on the value of * GIT_TEST_DEFAULT_HASH environment variable. The fallback value in the * absence of GIT_TEST_DEFAULT_HASH is GIT_HASH_SHA1. It also uses - * check(algo != GIT_HASH_UNKNOWN) before returning to verify if the + * cl_assert(algo != GIT_HASH_UNKNOWN) before returning to verify if the * GIT_TEST_DEFAULT_HASH's value is valid or not. */ -int init_hash_algo(void); + +int cl_setup_hash_algo(void); #endif /* LIB_OID_H */ diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c index ab1fa44a2824d5..8a6961226657f3 100644 --- a/t/unit-tests/lib-reftable.c +++ b/t/unit-tests/lib-reftable.c @@ -1,9 +1,12 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "lib-reftable.h" #include "test-lib.h" #include "reftable/constants.h" #include "reftable/writer.h" +#include "strbuf.h" -void t_reftable_set_hash(uint8_t *p, int i, uint32_t id) +void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id) { memset(p, (uint8_t)i, hash_size(id)); } @@ -19,15 +22,17 @@ static int strbuf_writer_flush(void *arg UNUSED) return 0; } -struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf, +struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf, struct reftable_write_options *opts) { - return reftable_new_writer(&strbuf_writer_write, - &strbuf_writer_flush, - buf, opts); + struct reftable_writer *writer; + int ret = reftable_writer_new(&writer, &strbuf_writer_write, &strbuf_writer_flush, + buf, opts); + check(!ret); + return writer; } -void t_reftable_write_to_buf(struct strbuf *buf, +void t_reftable_write_to_buf(struct reftable_buf *buf, struct reftable_ref_record *refs, size_t nrefs, struct reftable_log_record *logs, @@ -80,7 +85,7 @@ void t_reftable_write_to_buf(struct strbuf *buf, size_t off = i * (opts.block_size ? opts.block_size : DEFAULT_BLOCK_SIZE); if (!off) - off = header_size(opts.hash_id == GIT_SHA256_FORMAT_ID ? 2 : 1); + off = header_size(opts.hash_id == REFTABLE_HASH_SHA256 ? 2 : 1); check_char(buf->buf[off], ==, 'r'); } diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h index d115419084753d..e4c360fa7eede9 100644 --- a/t/unit-tests/lib-reftable.h +++ b/t/unit-tests/lib-reftable.h @@ -2,15 +2,16 @@ #define LIB_REFTABLE_H #include "git-compat-util.h" -#include "strbuf.h" #include "reftable/reftable-writer.h" -void t_reftable_set_hash(uint8_t *p, int i, uint32_t id); +struct reftable_buf; -struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf, +void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id); + +struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf, struct reftable_write_options *opts); -void t_reftable_write_to_buf(struct strbuf *buf, +void t_reftable_write_to_buf(struct reftable_buf *buf, struct reftable_ref_record *refs, size_t nrecords, struct reftable_log_record *logs, diff --git a/t/unit-tests/t-example-decorate.c b/t/unit-tests/t-example-decorate.c deleted file mode 100644 index 8bf0709c41f681..00000000000000 --- a/t/unit-tests/t-example-decorate.c +++ /dev/null @@ -1,74 +0,0 @@ -#define USE_THE_REPOSITORY_VARIABLE - -#include "test-lib.h" -#include "object.h" -#include "decorate.h" -#include "repository.h" - -struct test_vars { - struct object *one, *two, *three; - struct decoration n; - int decoration_a, decoration_b; -}; - -static void t_add(struct test_vars *vars) -{ - void *ret = add_decoration(&vars->n, vars->one, &vars->decoration_a); - - check(ret == NULL); - ret = add_decoration(&vars->n, vars->two, NULL); - check(ret == NULL); -} - -static void t_readd(struct test_vars *vars) -{ - void *ret = add_decoration(&vars->n, vars->one, NULL); - - check(ret == &vars->decoration_a); - ret = add_decoration(&vars->n, vars->two, &vars->decoration_b); - check(ret == NULL); -} - -static void t_lookup(struct test_vars *vars) -{ - void *ret = lookup_decoration(&vars->n, vars->one); - - check(ret == NULL); - ret = lookup_decoration(&vars->n, vars->two); - check(ret == &vars->decoration_b); - ret = lookup_decoration(&vars->n, vars->three); - check(ret == NULL); -} - -static void t_loop(struct test_vars *vars) -{ - int i, objects_noticed = 0; - - for (i = 0; i < vars->n.size; i++) { - if (vars->n.entries[i].base) - objects_noticed++; - } - check_int(objects_noticed, ==, 2); -} - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - struct object_id one_oid = { { 1 } }, two_oid = { { 2 } }, three_oid = { { 3 } }; - struct test_vars vars = { 0 }; - - vars.one = lookup_unknown_object(the_repository, &one_oid); - vars.two = lookup_unknown_object(the_repository, &two_oid); - vars.three = lookup_unknown_object(the_repository, &three_oid); - - TEST(t_add(&vars), - "Add 2 objects, one with a non-NULL decoration and one with a NULL decoration."); - TEST(t_readd(&vars), - "When re-adding an already existing object, the old decoration is returned."); - TEST(t_lookup(&vars), - "Lookup returns the added declarations, or NULL if the object was never added."); - TEST(t_loop(&vars), "The user can also loop through all entries."); - - clear_decoration(&vars.n, NULL); - - return test_done(); -} diff --git a/t/unit-tests/t-mem-pool.c b/t/unit-tests/t-mem-pool.c deleted file mode 100644 index fe500c704b3c8a..00000000000000 --- a/t/unit-tests/t-mem-pool.c +++ /dev/null @@ -1,31 +0,0 @@ -#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 UNUSED, const char **argv UNUSED) -{ - 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-oid-array.c b/t/unit-tests/t-oid-array.c deleted file mode 100644 index 45b59a2a51bc52..00000000000000 --- a/t/unit-tests/t-oid-array.c +++ /dev/null @@ -1,126 +0,0 @@ -#define USE_THE_REPOSITORY_VARIABLE - -#include "test-lib.h" -#include "lib-oid.h" -#include "oid-array.h" -#include "hex.h" - -static int fill_array(struct oid_array *array, const char *hexes[], size_t n) -{ - for (size_t i = 0; i < n; i++) { - struct object_id oid; - - if (!check_int(get_oid_arbitrary_hex(hexes[i], &oid), ==, 0)) - return -1; - oid_array_append(array, &oid); - } - if (!check_uint(array->nr, ==, n)) - return -1; - return 0; -} - -static int add_to_oid_array(const struct object_id *oid, void *data) -{ - struct oid_array *array = data; - - oid_array_append(array, oid); - return 0; -} - -static void t_enumeration(const char **input_args, size_t input_sz, - const char **expect_args, size_t expect_sz) -{ - struct oid_array input = OID_ARRAY_INIT, expect = OID_ARRAY_INIT, - actual = OID_ARRAY_INIT; - size_t i; - - if (fill_array(&input, input_args, input_sz)) - return; - if (fill_array(&expect, expect_args, expect_sz)) - return; - - oid_array_for_each_unique(&input, add_to_oid_array, &actual); - if (!check_uint(actual.nr, ==, expect.nr)) - return; - - for (i = 0; i < actual.nr; i++) { - if (!check(oideq(&actual.oid[i], &expect.oid[i]))) - test_msg("expected: %s\n got: %s\n index: %" PRIuMAX, - oid_to_hex(&expect.oid[i]), oid_to_hex(&actual.oid[i]), - (uintmax_t)i); - } - - oid_array_clear(&actual); - oid_array_clear(&input); - oid_array_clear(&expect); -} - -#define TEST_ENUMERATION(input, expect, desc) \ - TEST(t_enumeration(input, ARRAY_SIZE(input), expect, ARRAY_SIZE(expect)), \ - desc " works") - -static void t_lookup(const char **input_hexes, size_t n, const char *query_hex, - int lower_bound, int upper_bound) -{ - struct oid_array array = OID_ARRAY_INIT; - struct object_id oid_query; - int ret; - - if (!check_int(get_oid_arbitrary_hex(query_hex, &oid_query), ==, 0)) - return; - if (fill_array(&array, input_hexes, n)) - return; - ret = oid_array_lookup(&array, &oid_query); - - if (!check_int(ret, <=, upper_bound) || - !check_int(ret, >=, lower_bound)) - test_msg("oid query for lookup: %s", oid_to_hex(&oid_query)); - - oid_array_clear(&array); -} - -#define TEST_LOOKUP(input_hexes, query, lower_bound, upper_bound, desc) \ - TEST(t_lookup(input_hexes, ARRAY_SIZE(input_hexes), query, \ - lower_bound, upper_bound), \ - desc " works") - -static void setup(void) -{ - /* The hash algo is used by oid_array_lookup() internally */ - int algo = init_hash_algo(); - if (check_int(algo, !=, GIT_HASH_UNKNOWN)) - repo_set_hash_algo(the_repository, algo); -} - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - const char *arr_input[] = { "88", "44", "aa", "55" }; - const char *arr_input_dup[] = { "88", "44", "aa", "55", - "88", "44", "aa", "55", - "88", "44", "aa", "55" }; - const char *res_sorted[] = { "44", "55", "88", "aa" }; - const char *nearly_55; - - if (!TEST(setup(), "setup")) - test_skip_all("hash algo initialization failed"); - - TEST_ENUMERATION(arr_input, res_sorted, "ordered enumeration"); - TEST_ENUMERATION(arr_input_dup, res_sorted, - "ordered enumeration with duplicate suppression"); - - TEST_LOOKUP(arr_input, "55", 1, 1, "lookup"); - TEST_LOOKUP(arr_input, "33", INT_MIN, -1, "lookup non-existent entry"); - TEST_LOOKUP(arr_input_dup, "55", 3, 5, "lookup with duplicates"); - TEST_LOOKUP(arr_input_dup, "66", INT_MIN, -1, - "lookup non-existent entry with duplicates"); - - nearly_55 = init_hash_algo() == GIT_HASH_SHA1 ? - "5500000000000000000000000000000000000001" : - "5500000000000000000000000000000000000000000000000000000000000001"; - TEST_LOOKUP(((const char *[]){ "55", nearly_55 }), "55", 0, 0, - "lookup with almost duplicate values"); - TEST_LOOKUP(((const char *[]){ "55", "55" }), "55", 0, 1, - "lookup with single duplicate value"); - - return test_done(); -} diff --git a/t/unit-tests/t-oidmap.c b/t/unit-tests/t-oidmap.c deleted file mode 100644 index b22e52d08bdf77..00000000000000 --- a/t/unit-tests/t-oidmap.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "test-lib.h" -#include "lib-oid.h" -#include "oidmap.h" -#include "hash.h" -#include "hex.h" - -/* - * Elements we will put in oidmap structs are made of a key: the entry.oid - * field, which is of type struct object_id, and a value: the name field (could - * be a refname for example). - */ -struct test_entry { - struct oidmap_entry entry; - char name[FLEX_ARRAY]; -}; - -static const char *const key_val[][2] = { { "11", "one" }, - { "22", "two" }, - { "33", "three" } }; - -static void setup(void (*f)(struct oidmap *map)) -{ - struct oidmap map = OIDMAP_INIT; - int ret = 0; - - for (size_t i = 0; i < ARRAY_SIZE(key_val); i++){ - struct test_entry *entry; - - FLEX_ALLOC_STR(entry, name, key_val[i][1]); - if ((ret = get_oid_arbitrary_hex(key_val[i][0], &entry->entry.oid))) { - free(entry); - break; - } - entry = oidmap_put(&map, entry); - if (!check(entry == NULL)) - free(entry); - } - - if (!ret) - f(&map); - oidmap_free(&map, 1); -} - -static void t_replace(struct oidmap *map) -{ - struct test_entry *entry, *prev; - - FLEX_ALLOC_STR(entry, name, "un"); - if (get_oid_arbitrary_hex("11", &entry->entry.oid)) - return; - prev = oidmap_put(map, entry); - if (!check(prev != NULL)) - return; - check_str(prev->name, "one"); - free(prev); - - FLEX_ALLOC_STR(entry, name, "deux"); - if (get_oid_arbitrary_hex("22", &entry->entry.oid)) - return; - prev = oidmap_put(map, entry); - if (!check(prev != NULL)) - return; - check_str(prev->name, "two"); - free(prev); -} - -static void t_get(struct oidmap *map) -{ - struct test_entry *entry; - struct object_id oid; - - if (get_oid_arbitrary_hex("22", &oid)) - return; - entry = oidmap_get(map, &oid); - if (!check(entry != NULL)) - return; - check_str(entry->name, "two"); - - if (get_oid_arbitrary_hex("44", &oid)) - return; - check(oidmap_get(map, &oid) == NULL); - - if (get_oid_arbitrary_hex("11", &oid)) - return; - entry = oidmap_get(map, &oid); - if (!check(entry != NULL)) - return; - check_str(entry->name, "one"); -} - -static void t_remove(struct oidmap *map) -{ - struct test_entry *entry; - struct object_id oid; - - if (get_oid_arbitrary_hex("11", &oid)) - return; - entry = oidmap_remove(map, &oid); - if (!check(entry != NULL)) - return; - check_str(entry->name, "one"); - check(oidmap_get(map, &oid) == NULL); - free(entry); - - if (get_oid_arbitrary_hex("22", &oid)) - return; - entry = oidmap_remove(map, &oid); - if (!check(entry != NULL)) - return; - check_str(entry->name, "two"); - check(oidmap_get(map, &oid) == NULL); - free(entry); - - if (get_oid_arbitrary_hex("44", &oid)) - return; - check(oidmap_remove(map, &oid) == NULL); -} - -static int key_val_contains(struct test_entry *entry, char seen[]) -{ - for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) { - struct object_id oid; - - if (get_oid_arbitrary_hex(key_val[i][0], &oid)) - return -1; - - if (oideq(&entry->entry.oid, &oid)) { - if (seen[i]) - return 2; - seen[i] = 1; - return 0; - } - } - return 1; -} - -static void t_iterate(struct oidmap *map) -{ - struct oidmap_iter iter; - struct test_entry *entry; - char seen[ARRAY_SIZE(key_val)] = { 0 }; - int count = 0; - - oidmap_iter_init(map, &iter); - while ((entry = oidmap_iter_next(&iter))) { - int ret; - if (!check_int((ret = key_val_contains(entry, seen)), ==, 0)) { - switch (ret) { - case -1: - break; /* error message handled by get_oid_arbitrary_hex() */ - case 1: - test_msg("obtained entry was not given in the input\n" - " name: %s\n oid: %s\n", - entry->name, oid_to_hex(&entry->entry.oid)); - break; - case 2: - test_msg("duplicate entry detected\n" - " name: %s\n oid: %s\n", - entry->name, oid_to_hex(&entry->entry.oid)); - break; - default: - test_msg("BUG: invalid return value (%d) from key_val_contains()", - ret); - break; - } - } else { - count++; - } - } - check_int(count, ==, ARRAY_SIZE(key_val)); - check_int(hashmap_get_size(&map->map), ==, ARRAY_SIZE(key_val)); -} - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - TEST(setup(t_replace), "replace works"); - TEST(setup(t_get), "get works"); - TEST(setup(t_remove), "remove works"); - TEST(setup(t_iterate), "iterate works"); - return test_done(); -} diff --git a/t/unit-tests/t-oidtree.c b/t/unit-tests/t-oidtree.c deleted file mode 100644 index a38754b066b3ea..00000000000000 --- a/t/unit-tests/t-oidtree.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "test-lib.h" -#include "lib-oid.h" -#include "oidtree.h" -#include "hash.h" -#include "hex.h" -#include "strvec.h" - -#define FILL_TREE(tree, ...) \ - do { \ - const char *hexes[] = { __VA_ARGS__ }; \ - if (fill_tree_loc(tree, hexes, ARRAY_SIZE(hexes))) \ - return; \ - } while (0) - -static int fill_tree_loc(struct oidtree *ot, const char *hexes[], size_t n) -{ - for (size_t i = 0; i < n; i++) { - struct object_id oid; - if (!check_int(get_oid_arbitrary_hex(hexes[i], &oid), ==, 0)) - return -1; - oidtree_insert(ot, &oid); - } - return 0; -} - -static void check_contains(struct oidtree *ot, const char *hex, int expected) -{ - struct object_id oid; - - if (!check_int(get_oid_arbitrary_hex(hex, &oid), ==, 0)) - return; - if (!check_int(oidtree_contains(ot, &oid), ==, expected)) - test_msg("oid: %s", oid_to_hex(&oid)); -} - -struct expected_hex_iter { - size_t i; - struct strvec expected_hexes; - const char *query; -}; - -static enum cb_next check_each_cb(const struct object_id *oid, void *data) -{ - struct expected_hex_iter *hex_iter = data; - struct object_id expected; - - if (!check_int(hex_iter->i, <, hex_iter->expected_hexes.nr)) { - test_msg("error: extraneous callback for query: ('%s'), object_id: ('%s')", - hex_iter->query, oid_to_hex(oid)); - return CB_BREAK; - } - - if (!check_int(get_oid_arbitrary_hex(hex_iter->expected_hexes.v[hex_iter->i], - &expected), ==, 0)) - ; /* the data is bogus and cannot be used */ - else if (!check(oideq(oid, &expected))) - test_msg("expected: %s\n got: %s\n query: %s", - oid_to_hex(&expected), oid_to_hex(oid), hex_iter->query); - - hex_iter->i += 1; - return CB_CONTINUE; -} - -LAST_ARG_MUST_BE_NULL -static void check_each(struct oidtree *ot, const char *query, ...) -{ - struct object_id oid; - struct expected_hex_iter hex_iter = { .expected_hexes = STRVEC_INIT, - .query = query }; - const char *arg; - va_list hex_args; - - va_start(hex_args, query); - while ((arg = va_arg(hex_args, const char *))) - strvec_push(&hex_iter.expected_hexes, arg); - va_end(hex_args); - - if (!check_int(get_oid_arbitrary_hex(query, &oid), ==, 0)) - return; - oidtree_each(ot, &oid, strlen(query), check_each_cb, &hex_iter); - - if (!check_int(hex_iter.i, ==, hex_iter.expected_hexes.nr)) - test_msg("error: could not find some 'object_id's for query ('%s')", query); - strvec_clear(&hex_iter.expected_hexes); -} - -static void setup(void (*f)(struct oidtree *ot)) -{ - struct oidtree ot; - - oidtree_init(&ot); - f(&ot); - oidtree_clear(&ot); -} - -static void t_contains(struct oidtree *ot) -{ - FILL_TREE(ot, "444", "1", "2", "3", "4", "5", "a", "b", "c", "d", "e"); - check_contains(ot, "44", 0); - check_contains(ot, "441", 0); - check_contains(ot, "440", 0); - check_contains(ot, "444", 1); - check_contains(ot, "4440", 1); - check_contains(ot, "4444", 0); -} - -static void t_each(struct oidtree *ot) -{ - FILL_TREE(ot, "f", "9", "8", "123", "321", "320", "a", "b", "c", "d", "e"); - check_each(ot, "12300", "123", NULL); - check_each(ot, "3211", NULL); /* should not reach callback */ - check_each(ot, "3210", "321", NULL); - check_each(ot, "32100", "321", NULL); - check_each(ot, "32", "320", "321", NULL); -} - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - TEST(setup(t_contains), "oidtree insert and contains works"); - TEST(setup(t_each), "oidtree each works"); - return test_done(); -} diff --git a/t/unit-tests/t-prio-queue.c b/t/unit-tests/t-prio-queue.c deleted file mode 100644 index fe6ae37935b8a8..00000000000000 --- a/t/unit-tests/t-prio-queue.c +++ /dev/null @@ -1,91 +0,0 @@ -#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, size_t input_size, - int *result, size_t result_size) -{ - struct prio_queue pq = { intcmp }; - int j = 0; - - for (int i = 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_uint(j, <, result_size)) - break; - if (!check_int(result[j], ==, show(get))) - test_msg(" j: %d", j); - j++; - break; - case DUMP: - while ((peek = prio_queue_peek(&pq))) { - get = prio_queue_get(&pq); - if (!check(peek == get)) - return; - if (!check_uint(j, <, result_size)) - break; - if (!check_int(result[j], ==, show(get))) - test_msg(" j: %d", j); - j++; - } - break; - case STACK: - pq.compare = NULL; - break; - case REVERSE: - prio_queue_reverse(&pq); - break; - default: - prio_queue_put(&pq, &input[i]); - break; - } - } - check_uint(j, ==, result_size); - clear_prio_queue(&pq); -} - -#define TEST_INPUT(input, result) \ - test_prio_queue(input, ARRAY_SIZE(input), result, ARRAY_SIZE(result)) - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - TEST(TEST_INPUT(((int []){ 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP }), - ((int []){ 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10 })), - "prio-queue works for basic input"); - TEST(TEST_INPUT(((int []){ 6, 2, 4, GET, 5, 3, GET, GET, 1, DUMP }), - ((int []){ 2, 3, 4, 1, 5, 6 })), - "prio-queue works for mixed put & get commands"); - TEST(TEST_INPUT(((int []){ 1, 2, GET, GET, GET, 1, 2, GET, GET, GET }), - ((int []){ 1, 2, MISSING, 1, 2, MISSING })), - "prio-queue works when queue is empty"); - TEST(TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }), - ((int []){ 3, 2, 6, 4, 5, 1, 8 })), - "prio-queue works when used as a LIFO stack"); - TEST(TEST_INPUT(((int []){ STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP }), - ((int []){ 1, 2, 3, 4, 5, 6 })), - "prio-queue works when LIFO stack is reversed"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c index e5556ebf527331..9ba7eb05ada89b 100644 --- a/t/unit-tests/t-reftable-basics.c +++ b/t/unit-tests/t-reftable-basics.c @@ -20,6 +20,11 @@ static int integer_needle_lesseq(size_t i, void *_args) return args->needle <= args->haystack[i]; } +static void *realloc_stub(void *p UNUSED, size_t size UNUSED) +{ + return NULL; +} + int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { if_test ("binary search with binsearch works") { @@ -54,7 +59,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) } } - if_test ("names_length retuns size of a NULL-terminated string array") { + if_test ("names_length returns size of a NULL-terminated string array") { const char *a[] = { "a", "b", NULL }; check_int(names_length(a), ==, 2); } @@ -72,13 +77,14 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) if_test ("parse_names works for basic input") { char in1[] = "line\n"; char in2[] = "a\nb\nc"; - char **out = NULL; - parse_names(in1, strlen(in1), &out); + char **out = parse_names(in1, strlen(in1)); + check(out != NULL); check_str(out[0], "line"); check(!out[1]); free_names(out); - parse_names(in2, strlen(in2), &out); + out = parse_names(in2, strlen(in2)); + check(out != NULL); check_str(out[0], "a"); check_str(out[1], "b"); check_str(out[2], "c"); @@ -88,8 +94,8 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) if_test ("parse_names drops empty string") { char in[] = "a\n\nb\n"; - char **out = NULL; - parse_names(in, strlen(in), &out); + char **out = parse_names(in, strlen(in)); + check(out != NULL); check_str(out[0], "a"); /* simply '\n' should be dropped as empty string */ check_str(out[1], "b"); @@ -98,8 +104,8 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) } if_test ("common_prefix_size works") { - struct strbuf a = STRBUF_INIT; - struct strbuf b = STRBUF_INIT; + struct reftable_buf a = REFTABLE_BUF_INIT; + struct reftable_buf b = REFTABLE_BUF_INIT; struct { const char *a, *b; int want; @@ -112,14 +118,14 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) }; for (size_t i = 0; i < ARRAY_SIZE(cases); i++) { - strbuf_addstr(&a, cases[i].a); - strbuf_addstr(&b, cases[i].b); - check_int(common_prefix_size(&a, &b), ==, cases[i].want); - strbuf_reset(&a); - strbuf_reset(&b); + check(!reftable_buf_addstr(&a, cases[i].a)); + check(!reftable_buf_addstr(&b, cases[i].b)); + check_uint(common_prefix_size(&a, &b), ==, cases[i].want); + reftable_buf_reset(&a); + reftable_buf_reset(&b); } - strbuf_release(&a); - strbuf_release(&b); + reftable_buf_release(&a); + reftable_buf_release(&b); } if_test ("put_be24 and get_be24 work") { @@ -140,5 +146,56 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) check_int(in, ==, out); } + if_test ("REFTABLE_ALLOC_GROW works") { + int *arr = NULL, *old_arr; + size_t alloc = 0, old_alloc; + + check(!REFTABLE_ALLOC_GROW(arr, 1, alloc)); + check(arr != NULL); + check_uint(alloc, >=, 1); + arr[0] = 42; + + old_alloc = alloc; + old_arr = arr; + reftable_set_alloc(NULL, realloc_stub, NULL); + check(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); + check(arr == old_arr); + check_uint(alloc, ==, old_alloc); + + old_alloc = alloc; + reftable_set_alloc(NULL, NULL, NULL); + check(!REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); + check(arr != NULL); + check_uint(alloc, >, old_alloc); + arr[alloc - 1] = 42; + + reftable_free(arr); + } + + if_test ("REFTABLE_ALLOC_GROW_OR_NULL works") { + int *arr = NULL; + size_t alloc = 0, old_alloc; + + REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc); + check(arr != NULL); + check_uint(alloc, >=, 1); + arr[0] = 42; + + old_alloc = alloc; + REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); + check(arr != NULL); + check_uint(alloc, >, old_alloc); + arr[alloc - 1] = 42; + + old_alloc = alloc; + reftable_set_alloc(NULL, realloc_stub, NULL); + REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); + check(arr == NULL); + check_uint(alloc, ==, 0); + reftable_set_alloc(NULL, NULL, NULL); + + reftable_free(arr); + } + return test_done(); } diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index f1a49485e23a78..22040aeefa528c 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -11,6 +11,7 @@ license that can be found in the LICENSE file or at #include "reftable/blocksource.h" #include "reftable/constants.h" #include "reftable/reftable-error.h" +#include "strbuf.h" static void t_ref_block_read_write(void) { @@ -20,7 +21,7 @@ static void t_ref_block_read_write(void) const size_t block_size = 1024; struct reftable_block block = { 0 }; struct block_writer bw = { - .last_key = STRBUF_INIT, + .last_key = REFTABLE_BUF_INIT, }; struct reftable_record rec = { .type = BLOCK_TYPE_REF, @@ -29,13 +30,15 @@ static void t_ref_block_read_write(void) int ret; struct block_reader br = { 0 }; struct block_iter it = BLOCK_ITER_INIT; - struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block.data, block_size); + check(block.data != NULL); block.len = block_size; - block_source_from_strbuf(&block.source ,&buf); - block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + block_source_from_buf(&block.source ,&buf); + ret = block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size, + header_off, hash_size(REFTABLE_HASH_SHA1)); + check(!ret); rec.u.ref.refname = (char *) ""; rec.u.ref.value_type = REFTABLE_REF_DELETION; @@ -45,7 +48,7 @@ static void t_ref_block_read_write(void) for (i = 0; i < N; i++) { rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); rec.u.ref.value_type = REFTABLE_REF_VAL1; - memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); + memset(rec.u.ref.value.val1, i, REFTABLE_HASH_SIZE_SHA1); recs[i] = rec; ret = block_writer_add(&bw, &rec); @@ -59,7 +62,7 @@ static void t_ref_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -70,7 +73,7 @@ static void t_ref_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -83,7 +86,7 @@ static void t_ref_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -91,15 +94,15 @@ static void t_ref_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); block_iter_close(&it); reftable_record_release(&rec); reftable_block_done(&br.block); - strbuf_release(&want); - strbuf_release(&buf); + reftable_buf_release(&want); + reftable_buf_release(&buf); for (i = 0; i < N; i++) reftable_record_release(&recs[i]); } @@ -112,7 +115,7 @@ static void t_log_block_read_write(void) const size_t block_size = 2048; struct reftable_block block = { 0 }; struct block_writer bw = { - .last_key = STRBUF_INIT, + .last_key = REFTABLE_BUF_INIT, }; struct reftable_record rec = { .type = BLOCK_TYPE_LOG, @@ -121,13 +124,15 @@ static void t_log_block_read_write(void) int ret; struct block_reader br = { 0 }; struct block_iter it = BLOCK_ITER_INIT; - struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block.data, block_size); + check(block.data != NULL); block.len = block_size; - block_source_from_strbuf(&block.source ,&buf); - block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + block_source_from_buf(&block.source ,&buf); + ret = block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size, + header_off, hash_size(REFTABLE_HASH_SHA1)); + check(!ret); for (i = 0; i < N; i++) { rec.u.log.refname = xstrfmt("branch%02"PRIuMAX , (uintmax_t)i); @@ -146,7 +151,7 @@ static void t_log_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -157,13 +162,13 @@ static void t_log_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { block_iter_reset(&it); - strbuf_reset(&want); - strbuf_addstr(&want, recs[i].u.log.refname); + reftable_buf_reset(&want); + check(!reftable_buf_addstr(&want, recs[i].u.log.refname)); ret = block_iter_seek_key(&it, &br, &want); check_int(ret, ==, 0); @@ -171,7 +176,7 @@ static void t_log_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -179,15 +184,15 @@ static void t_log_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); block_iter_close(&it); reftable_record_release(&rec); reftable_block_done(&br.block); - strbuf_release(&want); - strbuf_release(&buf); + reftable_buf_release(&want); + reftable_buf_release(&buf); for (i = 0; i < N; i++) reftable_record_release(&recs[i]); } @@ -200,7 +205,7 @@ static void t_obj_block_read_write(void) const size_t block_size = 1024; struct reftable_block block = { 0 }; struct block_writer bw = { - .last_key = STRBUF_INIT, + .last_key = REFTABLE_BUF_INIT, }; struct reftable_record rec = { .type = BLOCK_TYPE_OBJ, @@ -209,13 +214,15 @@ static void t_obj_block_read_write(void) int ret; struct block_reader br = { 0 }; struct block_iter it = BLOCK_ITER_INIT; - struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block.data, block_size); + check(block.data != NULL); block.len = block_size; - block_source_from_strbuf(&block.source, &buf); - block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + block_source_from_buf(&block.source, &buf); + ret = block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size, + header_off, hash_size(REFTABLE_HASH_SHA1)); + check(!ret); for (i = 0; i < N; i++) { uint8_t bytes[] = { i, i + 1, i + 2, i + 3, i + 5 }, *allocated; @@ -236,7 +243,7 @@ static void t_obj_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -247,7 +254,7 @@ static void t_obj_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -260,15 +267,15 @@ static void t_obj_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); block_iter_close(&it); reftable_record_release(&rec); reftable_block_done(&br.block); - strbuf_release(&want); - strbuf_release(&buf); + reftable_buf_release(&want); + reftable_buf_release(&buf); for (i = 0; i < N; i++) reftable_record_release(&recs[i]); } @@ -281,29 +288,34 @@ static void t_index_block_read_write(void) const size_t block_size = 1024; struct reftable_block block = { 0 }; struct block_writer bw = { - .last_key = STRBUF_INIT, + .last_key = REFTABLE_BUF_INIT, }; struct reftable_record rec = { .type = BLOCK_TYPE_INDEX, - .u.idx.last_key = STRBUF_INIT, + .u.idx.last_key = REFTABLE_BUF_INIT, }; size_t i = 0; int ret; struct block_reader br = { 0 }; struct block_iter it = BLOCK_ITER_INIT; - struct strbuf want = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_buf want = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block.data, block_size); + check(block.data != NULL); block.len = block_size; - block_source_from_strbuf(&block.source, &buf); - block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + block_source_from_buf(&block.source, &buf); + ret = block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size, + header_off, hash_size(REFTABLE_HASH_SHA1)); + check(!ret); for (i = 0; i < N; i++) { - strbuf_init(&recs[i].u.idx.last_key, 9); + char buf[128]; + snprintf(buf, sizeof(buf), "branch%02"PRIuMAX, (uintmax_t)i); + + reftable_buf_init(&recs[i].u.idx.last_key); recs[i].type = BLOCK_TYPE_INDEX; - strbuf_addf(&recs[i].u.idx.last_key, "branch%02"PRIuMAX, (uintmax_t)i); + check(!reftable_buf_addstr(&recs[i].u.idx.last_key, buf)); recs[i].u.idx.offset = i; ret = block_writer_add(&bw, &recs[i]); @@ -315,7 +327,7 @@ static void t_index_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -326,7 +338,7 @@ static void t_index_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -339,7 +351,7 @@ static void t_index_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -347,15 +359,15 @@ static void t_index_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); block_iter_close(&it); reftable_record_release(&rec); reftable_block_done(&br.block); - strbuf_release(&want); - strbuf_release(&buf); + reftable_buf_release(&want); + reftable_buf_release(&buf); for (i = 0; i < N; i++) reftable_record_release(&recs[i]); } diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c index 19e54bdfb8b5ea..60836f80d60281 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/t-reftable-merged.c @@ -20,7 +20,7 @@ static struct reftable_merged_table * merged_table_from_records(struct reftable_ref_record **refs, struct reftable_block_source **source, struct reftable_reader ***readers, const size_t *sizes, - struct strbuf *buf, const size_t n) + struct reftable_buf *buf, const size_t n) { struct reftable_merged_table *mt = NULL; struct reftable_write_options opts = { @@ -29,18 +29,20 @@ merged_table_from_records(struct reftable_ref_record **refs, int err; REFTABLE_CALLOC_ARRAY(*readers, n); + check(*readers != NULL); REFTABLE_CALLOC_ARRAY(*source, n); + check(*source != NULL); for (size_t i = 0; i < n; i++) { t_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts); - block_source_from_strbuf(&(*source)[i], &buf[i]); + block_source_from_buf(&(*source)[i], &buf[i]); err = reftable_reader_new(&(*readers)[i], &(*source)[i], "name"); check(!err); } - err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&mt, *readers, n, REFTABLE_HASH_SHA1); check(!err); return mt; } @@ -73,7 +75,7 @@ static void t_merged_single_record(void) struct reftable_ref_record *refs[] = { r1, r2, r3 }; size_t sizes[] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) }; - struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; + struct reftable_buf bufs[3] = { REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, REFTABLE_BUF_INIT }; struct reftable_block_source *bs = NULL; struct reftable_reader **readers = NULL; struct reftable_merged_table *mt = @@ -82,19 +84,20 @@ static void t_merged_single_record(void) struct reftable_iterator it = { 0 }; int err; - merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + err = merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + check(!err); err = reftable_iterator_seek_ref(&it, "a"); check(!err); err = reftable_iterator_next_ref(&it, &ref); check(!err); - check(reftable_ref_record_equal(&r2[0], &ref, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&r2[0], &ref, REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); readers_destroy(readers, 3); reftable_merged_table_free(mt); for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) - strbuf_release(&bufs[i]); + reftable_buf_release(&bufs[i]); reftable_free(bs); } @@ -149,7 +152,7 @@ static void t_merged_refs(void) struct reftable_ref_record *refs[] = { r1, r2, r3 }; size_t sizes[3] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) }; - struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; + struct reftable_buf bufs[3] = { REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, REFTABLE_BUF_INIT }; struct reftable_block_source *bs = NULL; struct reftable_reader **readers = NULL; struct reftable_merged_table *mt = @@ -161,10 +164,11 @@ static void t_merged_refs(void) size_t cap = 0; size_t i; - merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + err = merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + check(!err); err = reftable_iterator_seek_ref(&it, "a"); check(!err); - check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID); + check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1); check_int(reftable_merged_table_min_update_index(mt), ==, 1); check_int(reftable_merged_table_max_update_index(mt), ==, 3); @@ -174,7 +178,7 @@ static void t_merged_refs(void) if (err > 0) break; - REFTABLE_ALLOC_GROW(out, len + 1, cap); + check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); out[len++] = ref; } reftable_iterator_destroy(&it); @@ -182,13 +186,13 @@ static void t_merged_refs(void) check_int(ARRAY_SIZE(want), ==, len); for (i = 0; i < len; i++) check(reftable_ref_record_equal(want[i], &out[i], - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); for (i = 0; i < len; i++) reftable_ref_record_release(&out[i]); reftable_free(out); for (i = 0; i < 3; i++) - strbuf_release(&bufs[i]); + reftable_buf_release(&bufs[i]); readers_destroy(readers, 3); reftable_merged_table_free(mt); reftable_free(bs); @@ -230,8 +234,8 @@ static void t_merged_seek_multiple_times(void) size_t sizes[] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), }; - struct strbuf bufs[] = { - STRBUF_INIT, STRBUF_INIT, + struct reftable_buf bufs[] = { + REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, }; struct reftable_block_source *sources = NULL; struct reftable_reader **readers = NULL; @@ -248,12 +252,12 @@ static void t_merged_seek_multiple_times(void) err = reftable_iterator_next_ref(&it, &rec); check(!err); - err = reftable_ref_record_equal(&rec, &r1[1], GIT_SHA1_RAWSZ); + err = reftable_ref_record_equal(&rec, &r1[1], REFTABLE_HASH_SIZE_SHA1); check(err == 1); err = reftable_iterator_next_ref(&it, &rec); check(!err); - err = reftable_ref_record_equal(&rec, &r2[1], GIT_SHA1_RAWSZ); + err = reftable_ref_record_equal(&rec, &r2[1], REFTABLE_HASH_SIZE_SHA1); check(err == 1); err = reftable_iterator_next_ref(&it, &rec); @@ -261,7 +265,79 @@ static void t_merged_seek_multiple_times(void) } for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) - strbuf_release(&bufs[i]); + reftable_buf_release(&bufs[i]); + readers_destroy(readers, ARRAY_SIZE(refs)); + reftable_ref_record_release(&rec); + reftable_iterator_destroy(&it); + reftable_merged_table_free(mt); + reftable_free(sources); +} + +static void t_merged_seek_multiple_times_without_draining(void) +{ + struct reftable_ref_record r1[] = { + { + .refname = (char *) "a", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 1 }, + }, + { + .refname = (char *) "c", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 2 }, + } + }; + struct reftable_ref_record r2[] = { + { + .refname = (char *) "b", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 3 }, + }, + { + .refname = (char *) "d", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 4 }, + }, + }; + struct reftable_ref_record *refs[] = { + r1, r2, + }; + size_t sizes[] = { + ARRAY_SIZE(r1), ARRAY_SIZE(r2), + }; + struct reftable_buf bufs[] = { + REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, + }; + struct reftable_block_source *sources = NULL; + struct reftable_reader **readers = NULL; + struct reftable_ref_record rec = { 0 }; + struct reftable_iterator it = { 0 }; + struct reftable_merged_table *mt; + int err; + + mt = merged_table_from_records(refs, &sources, &readers, sizes, bufs, 2); + merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + + err = reftable_iterator_seek_ref(&it, "b"); + check(!err); + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r2[0], REFTABLE_HASH_SIZE_SHA1); + check(err == 1); + + err = reftable_iterator_seek_ref(&it, "a"); + check(!err); + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r1[0], REFTABLE_HASH_SIZE_SHA1); + check(err == 1); + + for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) + reftable_buf_release(&bufs[i]); readers_destroy(readers, ARRAY_SIZE(refs)); reftable_ref_record_release(&rec); reftable_iterator_destroy(&it); @@ -273,7 +349,7 @@ static struct reftable_merged_table * merged_table_from_log_records(struct reftable_log_record **logs, struct reftable_block_source **source, struct reftable_reader ***readers, const size_t *sizes, - struct strbuf *buf, const size_t n) + struct reftable_buf *buf, const size_t n) { struct reftable_merged_table *mt = NULL; struct reftable_write_options opts = { @@ -283,18 +359,20 @@ merged_table_from_log_records(struct reftable_log_record **logs, int err; REFTABLE_CALLOC_ARRAY(*readers, n); + check(*readers != NULL); REFTABLE_CALLOC_ARRAY(*source, n); + check(*source != NULL); for (size_t i = 0; i < n; i++) { t_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts); - block_source_from_strbuf(&(*source)[i], &buf[i]); + block_source_from_buf(&(*source)[i], &buf[i]); err = reftable_reader_new(&(*readers)[i], &(*source)[i], "name"); check(!err); } - err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&mt, *readers, n, REFTABLE_HASH_SHA1); check(!err); return mt; } @@ -355,7 +433,7 @@ static void t_merged_logs(void) struct reftable_log_record *logs[] = { r1, r2, r3 }; size_t sizes[3] = { ARRAY_SIZE(r1), ARRAY_SIZE(r2), ARRAY_SIZE(r3) }; - struct strbuf bufs[3] = { STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; + struct reftable_buf bufs[3] = { REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, REFTABLE_BUF_INIT }; struct reftable_block_source *bs = NULL; struct reftable_reader **readers = NULL; struct reftable_merged_table *mt = merged_table_from_log_records( @@ -367,10 +445,11 @@ static void t_merged_logs(void) size_t cap = 0; size_t i; - merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); + err = merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); + check(!err); err = reftable_iterator_seek_log(&it, "a"); check(!err); - check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID); + check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1); check_int(reftable_merged_table_min_update_index(mt), ==, 1); check_int(reftable_merged_table_max_update_index(mt), ==, 3); @@ -380,7 +459,7 @@ static void t_merged_logs(void) if (err > 0) break; - REFTABLE_ALLOC_GROW(out, len + 1, cap); + check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); out[len++] = log; } reftable_iterator_destroy(&it); @@ -388,15 +467,16 @@ static void t_merged_logs(void) check_int(ARRAY_SIZE(want), ==, len); for (i = 0; i < len; i++) check(reftable_log_record_equal(want[i], &out[i], - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); - merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); + err = merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); + check(!err); err = reftable_iterator_seek_log_at(&it, "a", 2); check(!err); reftable_log_record_release(&out[0]); err = reftable_iterator_next_log(&it, &out[0]); check(!err); - check(reftable_log_record_equal(&out[0], &r3[0], GIT_SHA1_RAWSZ)); + check(reftable_log_record_equal(&out[0], &r3[0], REFTABLE_HASH_SIZE_SHA1)); reftable_iterator_destroy(&it); for (i = 0; i < len; i++) @@ -404,7 +484,7 @@ static void t_merged_logs(void) reftable_free(out); for (i = 0; i < 3; i++) - strbuf_release(&bufs[i]); + reftable_buf_release(&bufs[i]); readers_destroy(readers, 3); reftable_merged_table_free(mt); reftable_free(bs); @@ -413,7 +493,7 @@ static void t_merged_logs(void) static void t_default_write_opts(void) { struct reftable_write_options opts = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record rec = { .refname = (char *) "master", @@ -434,22 +514,22 @@ static void t_default_write_opts(void) check(!err); reftable_writer_free(w); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&rd, &source, "filename"); check(!err); hash_id = reftable_reader_hash_id(rd); - check_int(hash_id, ==, GIT_SHA1_FORMAT_ID); + check_int(hash_id, ==, REFTABLE_HASH_SHA1); - err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA256_FORMAT_ID); + err = reftable_merged_table_new(&merged, &rd, 1, REFTABLE_HASH_SHA256); check_int(err, ==, REFTABLE_FORMAT_ERROR); - err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&merged, &rd, 1, REFTABLE_HASH_SHA1); check(!err); reftable_reader_decref(rd); reftable_merged_table_free(merged); - strbuf_release(&buf); + reftable_buf_release(&buf); } @@ -459,7 +539,8 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_merged_logs(), "merged table with multiple log updates for same ref"); TEST(t_merged_refs(), "merged table with multiple updates to same ref"); TEST(t_merged_seek_multiple_times(), "merged table can seek multiple times"); - TEST(t_merged_single_record(), "ref ocurring in only one record can be fetched"); + TEST(t_merged_seek_multiple_times_without_draining(), "merged table can seek multiple times without draining"); + TEST(t_merged_single_record(), "ref occurring in only one record can be fetched"); return test_done(); } diff --git a/t/unit-tests/t-reftable-pq.c b/t/unit-tests/t-reftable-pq.c index ada4c19f18afe7..f3f8a0cdf38579 100644 --- a/t/unit-tests/t-reftable-pq.c +++ b/t/unit-tests/t-reftable-pq.c @@ -9,6 +9,7 @@ license that can be found in the LICENSE file or at #include "test-lib.h" #include "reftable/constants.h" #include "reftable/pq.h" +#include "strbuf.h" static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq) { @@ -132,7 +133,7 @@ static void t_merged_iter_pqueue_top(void) merged_iter_pqueue_check(&pq); check(pq_entry_equal(&top, &e)); - check(reftable_record_equal(top.rec, &recs[i], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1)); for (size_t j = 0; i < pq.len; j++) { check(pq_less(&top, &pq.heap[j])); check_int(top.index, >, j); diff --git a/t/unit-tests/t-reftable-reader.c b/t/unit-tests/t-reftable-reader.c index eea86966c0d898..546df6005e4cfc 100644 --- a/t/unit-tests/t-reftable-reader.c +++ b/t/unit-tests/t-reftable-reader.c @@ -16,11 +16,11 @@ static int t_reader_seek_once(void) struct reftable_ref_record ref = { 0 }; struct reftable_iterator it = { 0 }; struct reftable_reader *reader; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; int ret; t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); ret = reftable_reader_new(&reader, &source, "name"); check(!ret); @@ -31,7 +31,7 @@ static int t_reader_seek_once(void) ret = reftable_iterator_next_ref(&it, &ref); check(!ret); - ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ); + ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1); check_int(ret, ==, 1); ret = reftable_iterator_next_ref(&it, &ref); @@ -40,7 +40,7 @@ static int t_reader_seek_once(void) reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); reftable_reader_decref(reader); - strbuf_release(&buf); + reftable_buf_release(&buf); return 0; } @@ -57,11 +57,11 @@ static int t_reader_reseek(void) struct reftable_ref_record ref = { 0 }; struct reftable_iterator it = { 0 }; struct reftable_reader *reader; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; int ret; t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); ret = reftable_reader_new(&reader, &source, "name"); check(!ret); @@ -74,7 +74,7 @@ static int t_reader_reseek(void) ret = reftable_iterator_next_ref(&it, &ref); check(!ret); - ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ); + ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1); check_int(ret, ==, 1); ret = reftable_iterator_next_ref(&it, &ref); @@ -84,7 +84,7 @@ static int t_reader_reseek(void) reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); reftable_reader_decref(reader); - strbuf_release(&buf); + reftable_buf_release(&buf); return 0; } diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c index e1b235a5f13471..c9626831dac5fb 100644 --- a/t/unit-tests/t-reftable-readwrite.c +++ b/t/unit-tests/t-reftable-readwrite.c @@ -6,6 +6,8 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-lib.h" #include "lib-reftable.h" #include "reftable/basics.h" @@ -13,18 +15,19 @@ license that can be found in the LICENSE file or at #include "reftable/reader.h" #include "reftable/reftable-error.h" #include "reftable/reftable-writer.h" +#include "strbuf.h" static const int update_index = 5; static void t_buffer(void) { - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; struct reftable_block out = { 0 }; int n; uint8_t in[] = "hello"; - strbuf_add(&buf, in, sizeof(in)); - block_source_from_strbuf(&source, &buf); + check(!reftable_buf_add(&buf, in, sizeof(in))); + block_source_from_buf(&source, &buf); check_int(block_source_size(&source), ==, 6); n = block_source_read_block(&source, &out, 0, sizeof(in)); check_int(n, ==, sizeof(in)); @@ -37,11 +40,11 @@ static void t_buffer(void) reftable_block_done(&out); block_source_close(&source); - strbuf_release(&buf); + reftable_buf_release(&buf); } -static void write_table(char ***names, struct strbuf *buf, int N, - int block_size, uint32_t hash_id) +static void write_table(char ***names, struct reftable_buf *buf, int N, + int block_size, enum reftable_hash hash_id) { struct reftable_write_options opts = { .block_size = block_size, @@ -52,14 +55,17 @@ static void write_table(char ***names, struct strbuf *buf, int N, int i; REFTABLE_CALLOC_ARRAY(*names, N + 1); + check(*names != NULL); REFTABLE_CALLOC_ARRAY(refs, N); + check(refs != NULL); REFTABLE_CALLOC_ARRAY(logs, N); + check(logs != NULL); for (i = 0; i < N; i++) { refs[i].refname = (*names)[i] = xstrfmt("refs/heads/branch%02d", i); refs[i].update_index = update_index; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { @@ -67,19 +73,19 @@ static void write_table(char ***names, struct strbuf *buf, int N, logs[i].update_index = update_index; logs[i].value_type = REFTABLE_LOG_UPDATE; t_reftable_set_hash(logs[i].value.update.new_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); logs[i].value.update.message = (char *) "message"; } t_reftable_write_to_buf(buf, refs, N, logs, N, &opts); - free(refs); - free(logs); + reftable_free(refs); + reftable_free(logs); } static void t_log_buffer_size(void) { - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_write_options opts = { .block_size = 4096, }; @@ -87,7 +93,7 @@ static void t_log_buffer_size(void) int i; struct reftable_log_record log = { .refname = (char *) "refs/heads/master", - .update_index = 0xa, + .update_index = update_index, .value_type = REFTABLE_LOG_UPDATE, .value = { .update = { .name = (char *) "Han-Wen Nienhuys", @@ -101,9 +107,9 @@ static void t_log_buffer_size(void) /* This tests buffer extension for log compression. Must use a random hash, to ensure that the compressed part is larger than the original. */ - for (i = 0; i < GIT_SHA1_RAWSZ; i++) { - log.value.update.old_hash[i] = (uint8_t)(git_rand() % 256); - log.value.update.new_hash[i] = (uint8_t)(git_rand() % 256); + for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) { + log.value.update.old_hash[i] = (uint8_t)(git_rand(0) % 256); + log.value.update.new_hash[i] = (uint8_t)(git_rand(0) % 256); } reftable_writer_set_limits(w, update_index, update_index); err = reftable_writer_add_log(w, &log); @@ -111,12 +117,12 @@ static void t_log_buffer_size(void) err = reftable_writer_close(w); check(!err); reftable_writer_free(w); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_log_overflow(void) { - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; char msg[256] = { 0 }; struct reftable_write_options opts = { .block_size = ARRAY_SIZE(msg), @@ -124,7 +130,7 @@ static void t_log_overflow(void) int err; struct reftable_log_record log = { .refname = (char *) "refs/heads/master", - .update_index = 0xa, + .update_index = update_index, .value_type = REFTABLE_LOG_UPDATE, .value = { .update = { @@ -145,28 +151,72 @@ static void t_log_overflow(void) err = reftable_writer_add_log(w, &log); check_int(err, ==, REFTABLE_ENTRY_TOO_BIG_ERROR); reftable_writer_free(w); - strbuf_release(&buf); + reftable_buf_release(&buf); } -static void t_log_write_read(void) +static void t_log_write_limits(void) { - int N = 2; - char **names = reftable_calloc(N + 1, sizeof(*names)); + struct reftable_write_options opts = { 0 }; + struct reftable_buf buf = REFTABLE_BUF_INIT; + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_log_record log = { + .refname = (char *)"refs/head/master", + .update_index = 0, + .value_type = REFTABLE_LOG_UPDATE, + .value = { + .update = { + .old_hash = { 1 }, + .new_hash = { 2 }, + .name = (char *)"Han-Wen Nienhuys", + .email = (char *)"hanwen@google.com", + .tz_offset = 100, + .time = 0x5e430672, + }, + }, + }; int err; + + reftable_writer_set_limits(w, 1, 1); + + /* write with update_index (0) below set limits (1, 1) */ + err = reftable_writer_add_log(w, &log); + check_int(err, ==, 0); + + /* write with update_index (1) in the set limits (1, 1) */ + log.update_index = 1; + err = reftable_writer_add_log(w, &log); + check_int(err, ==, 0); + + /* write with update_index (3) above set limits (1, 1) */ + log.update_index = 3; + err = reftable_writer_add_log(w, &log); + check_int(err, ==, REFTABLE_API_ERROR); + + reftable_writer_free(w); + reftable_buf_release(&buf); +} + +static void t_log_write_read(void) +{ struct reftable_write_options opts = { .block_size = 256, }; struct reftable_ref_record ref = { 0 }; - int i = 0; struct reftable_log_record log = { 0 }; - int n; struct reftable_iterator it = { 0 }; struct reftable_reader *reader; struct reftable_block_source source = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); const struct reftable_stats *stats = NULL; + int N = 2, err, i, n; + char **names; + + names = reftable_calloc(N + 1, sizeof(*names)); + check(names != NULL); + reftable_writer_set_limits(w, 0, N); + for (i = 0; i < N; i++) { char name[256]; struct reftable_ref_record ref = { 0 }; @@ -178,6 +228,7 @@ static void t_log_write_read(void) err = reftable_writer_add_ref(w, &ref); check(!err); } + for (i = 0; i < N; i++) { struct reftable_log_record log = { 0 }; @@ -185,9 +236,9 @@ static void t_log_write_read(void) log.update_index = i; log.value_type = REFTABLE_LOG_UPDATE; t_reftable_set_hash(log.value.update.old_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); t_reftable_set_hash(log.value.update.new_hash, i + 1, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); err = reftable_writer_add_log(w, &log); check(!err); @@ -201,12 +252,13 @@ static void t_log_write_read(void) reftable_writer_free(w); w = NULL; - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.log"); check(!err); - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, names[N - 1]); check(!err); @@ -221,8 +273,8 @@ static void t_log_write_read(void) reftable_iterator_destroy(&it); reftable_ref_record_release(&ref); - reftable_reader_init_log_iterator(reader, &it); - + err = reftable_reader_init_log_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_log(&it, ""); check(!err); @@ -240,7 +292,7 @@ static void t_log_write_read(void) reftable_iterator_destroy(&it); /* cleanup. */ - strbuf_release(&buf); + reftable_buf_release(&buf); free_names(names); reftable_reader_decref(reader); } @@ -253,7 +305,7 @@ static void t_log_zlib_corruption(void) struct reftable_iterator it = { 0 }; struct reftable_reader *reader; struct reftable_block_source source = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); const struct reftable_stats *stats = NULL; char message[100] = { 0 }; @@ -273,7 +325,7 @@ static void t_log_zlib_corruption(void) }; for (i = 0; i < sizeof(message) - 1; i++) - message[i] = (uint8_t)(git_rand() % 64 + ' '); + message[i] = (uint8_t)(git_rand(0) % 64 + ' '); reftable_writer_set_limits(w, 1, 1); @@ -291,12 +343,13 @@ static void t_log_zlib_corruption(void) /* corrupt the data. */ buf.buf[50] ^= 0x99; - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.log"); check(!err); - reftable_reader_init_log_iterator(reader, &it); + err = reftable_reader_init_log_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_log(&it, "refname"); check_int(err, ==, REFTABLE_ZLIB_ERROR); @@ -304,13 +357,13 @@ static void t_log_zlib_corruption(void) /* cleanup. */ reftable_reader_decref(reader); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_table_read_write_sequential(void) { char **names; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 50; struct reftable_iterator it = { 0 }; struct reftable_block_source source = { 0 }; @@ -318,14 +371,15 @@ static void t_table_read_write_sequential(void) int err = 0; int j = 0; - write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID); + write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, ""); check(!err); @@ -343,25 +397,25 @@ static void t_table_read_write_sequential(void) reftable_iterator_destroy(&it); reftable_reader_decref(reader); - strbuf_release(&buf); + reftable_buf_release(&buf); free_names(names); } static void t_table_write_small_table(void) { char **names; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 1; - write_table(&names, &buf, N, 4096, GIT_SHA1_FORMAT_ID); + write_table(&names, &buf, N, 4096, REFTABLE_HASH_SHA1); check_int(buf.len, <, 200); - strbuf_release(&buf); + reftable_buf_release(&buf); free_names(names); } static void t_table_read_api(void) { char **names; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 50; struct reftable_reader *reader; struct reftable_block_source source = { 0 }; @@ -369,31 +423,32 @@ static void t_table_read_api(void) struct reftable_log_record log = { 0 }; struct reftable_iterator it = { 0 }; - write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID); + write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, names[0]); check(!err); err = reftable_iterator_next_log(&it, &log); check_int(err, ==, REFTABLE_API_ERROR); - strbuf_release(&buf); + reftable_buf_release(&buf); free_names(names); reftable_iterator_destroy(&it); reftable_reader_decref(reader); - strbuf_release(&buf); + reftable_buf_release(&buf); } -static void t_table_read_write_seek(int index, int hash_id) +static void t_table_read_write_seek(int index, enum reftable_hash hash_id) { char **names; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 50; struct reftable_reader *reader; struct reftable_block_source source = { 0 }; @@ -401,12 +456,12 @@ static void t_table_read_write_seek(int index, int hash_id) int i = 0; struct reftable_iterator it = { 0 }; - struct strbuf pastLast = STRBUF_INIT; + struct reftable_buf pastLast = REFTABLE_BUF_INIT; struct reftable_ref_record ref = { 0 }; write_table(&names, &buf, N, 256, hash_id); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); @@ -419,7 +474,8 @@ static void t_table_read_write_seek(int index, int hash_id) } for (i = 1; i < N; i++) { - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, names[i]); check(!err); err = reftable_iterator_next_ref(&it, &ref); @@ -432,10 +488,11 @@ static void t_table_read_write_seek(int index, int hash_id) reftable_iterator_destroy(&it); } - strbuf_addstr(&pastLast, names[N - 1]); - strbuf_addstr(&pastLast, "/"); + check(!reftable_buf_addstr(&pastLast, names[N - 1])); + check(!reftable_buf_addstr(&pastLast, "/")); - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, pastLast.buf); if (err == 0) { struct reftable_ref_record ref = { 0 }; @@ -445,54 +502,53 @@ static void t_table_read_write_seek(int index, int hash_id) check_int(err, >, 0); } - strbuf_release(&pastLast); + reftable_buf_release(&pastLast); reftable_iterator_destroy(&it); - strbuf_release(&buf); + reftable_buf_release(&buf); free_names(names); reftable_reader_decref(reader); } static void t_table_read_write_seek_linear(void) { - t_table_read_write_seek(0, GIT_SHA1_FORMAT_ID); + t_table_read_write_seek(0, REFTABLE_HASH_SHA1); } static void t_table_read_write_seek_linear_sha256(void) { - t_table_read_write_seek(0, GIT_SHA256_FORMAT_ID); + t_table_read_write_seek(0, REFTABLE_HASH_SHA256); } static void t_table_read_write_seek_index(void) { - t_table_read_write_seek(1, GIT_SHA1_FORMAT_ID); + t_table_read_write_seek(1, REFTABLE_HASH_SHA1); } static void t_table_refs_for(int indexed) { - int N = 50; - char **want_names = reftable_calloc(N + 1, sizeof(*want_names)); + char **want_names; int want_names_len = 0; - uint8_t want_hash[GIT_SHA1_RAWSZ]; + uint8_t want_hash[REFTABLE_HASH_SIZE_SHA1]; struct reftable_write_options opts = { .block_size = 256, }; struct reftable_ref_record ref = { 0 }; - int i = 0; - int n; - int err; struct reftable_reader *reader; struct reftable_block_source source = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_iterator it = { 0 }; - int j; + int N = 50, n, j, err, i; + + want_names = reftable_calloc(N + 1, sizeof(*want_names)); + check(want_names != NULL); - t_reftable_set_hash(want_hash, 4, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1); for (i = 0; i < N; i++) { - uint8_t hash[GIT_SHA1_RAWSZ]; + uint8_t hash[REFTABLE_HASH_SIZE_SHA1]; char fill[51] = { 0 }; char name[100]; struct reftable_ref_record ref = { 0 }; @@ -506,9 +562,9 @@ static void t_table_refs_for(int indexed) ref.value_type = REFTABLE_REF_VAL2; t_reftable_set_hash(ref.value.val2.value, i / 4, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); t_reftable_set_hash(ref.value.val2.target_value, 3 + i / 4, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); /* 80 bytes / entry, so 3 entries per block. Yields 17 */ @@ -516,8 +572,8 @@ static void t_table_refs_for(int indexed) n = reftable_writer_add_ref(w, &ref); check_int(n, ==, 0); - if (!memcmp(ref.value.val2.value, want_hash, GIT_SHA1_RAWSZ) || - !memcmp(ref.value.val2.target_value, want_hash, GIT_SHA1_RAWSZ)) + if (!memcmp(ref.value.val2.value, want_hash, REFTABLE_HASH_SIZE_SHA1) || + !memcmp(ref.value.val2.target_value, want_hash, REFTABLE_HASH_SIZE_SHA1)) want_names[want_names_len++] = xstrdup(name); } @@ -527,14 +583,15 @@ static void t_table_refs_for(int indexed) reftable_writer_free(w); w = NULL; - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.ref"); check(!err); if (!indexed) reader->obj_offsets.is_present = 0; - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, ""); check(!err); reftable_iterator_destroy(&it); @@ -553,7 +610,7 @@ static void t_table_refs_for(int indexed) } check_int(j, ==, want_names_len); - strbuf_release(&buf); + reftable_buf_release(&buf); free_names(want_names); reftable_iterator_destroy(&it); reftable_reader_decref(reader); @@ -572,7 +629,7 @@ static void t_table_refs_for_obj_index(void) static void t_write_empty_table(void) { struct reftable_write_options opts = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_block_source source = { 0 }; struct reftable_reader *rd = NULL; @@ -586,14 +643,15 @@ static void t_write_empty_table(void) check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR); reftable_writer_free(w); - check_int(buf.len, ==, header_size(1) + footer_size(1)); + check_uint(buf.len, ==, header_size(1) + footer_size(1)); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&rd, &source, "filename"); check(!err); - reftable_reader_init_ref_iterator(rd, &it); + err = reftable_reader_init_ref_iterator(rd, &it); + check(!err); err = reftable_iterator_seek_ref(&it, ""); check(!err); @@ -602,7 +660,7 @@ static void t_write_empty_table(void) reftable_iterator_destroy(&it); reftable_reader_decref(rd); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_write_object_id_min_length(void) @@ -610,7 +668,7 @@ static void t_write_object_id_min_length(void) struct reftable_write_options opts = { .block_size = 75, }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .update_index = 1, @@ -636,7 +694,7 @@ static void t_write_object_id_min_length(void) check(!err); check_int(reftable_writer_stats(w)->object_id_len, ==, 2); reftable_writer_free(w); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_write_object_id_length(void) @@ -644,7 +702,7 @@ static void t_write_object_id_length(void) struct reftable_write_options opts = { .block_size = 75, }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .update_index = 1, @@ -671,13 +729,13 @@ static void t_write_object_id_length(void) check(!err); check_int(reftable_writer_stats(w)->object_id_len, ==, 16); reftable_writer_free(w); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_write_empty_key(void) { struct reftable_write_options opts = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .refname = (char *) "", @@ -693,13 +751,13 @@ static void t_write_empty_key(void) err = reftable_writer_close(w); check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR); reftable_writer_free(w); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_write_key_order(void) { struct reftable_write_options opts = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record refs[2] = { { @@ -732,7 +790,7 @@ static void t_write_key_order(void) reftable_writer_close(w); reftable_writer_free(w); - strbuf_release(&buf); + reftable_buf_release(&buf); } static void t_write_multiple_indices(void) @@ -740,12 +798,13 @@ static void t_write_multiple_indices(void) struct reftable_write_options opts = { .block_size = 100, }; - struct strbuf writer_buf = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_buf writer_buf = REFTABLE_BUF_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; + char buf[128]; int err, i; writer = t_reftable_strbuf_writer(&writer_buf, &opts); @@ -757,9 +816,8 @@ static void t_write_multiple_indices(void) .value.val1 = {i}, }; - strbuf_reset(&buf); - strbuf_addf(&buf, "refs/heads/%04d", i); - ref.refname = buf.buf, + snprintf(buf, sizeof(buf), "refs/heads/%04d", i); + ref.refname = buf; err = reftable_writer_add_ref(writer, &ref); check(!err); @@ -775,9 +833,8 @@ static void t_write_multiple_indices(void) }, }; - strbuf_reset(&buf); - strbuf_addf(&buf, "refs/heads/%04d", i); - log.refname = buf.buf, + snprintf(buf, sizeof(buf), "refs/heads/%04d", i); + log.refname = buf; err = reftable_writer_add_log(writer, &log); check(!err); @@ -794,7 +851,7 @@ static void t_write_multiple_indices(void) check_int(stats->obj_stats.index_offset, >, 0); check_int(stats->log_stats.index_offset, >, 0); - block_source_from_strbuf(&source, &writer_buf); + block_source_from_buf(&source, &writer_buf); err = reftable_reader_new(&reader, &source, "filename"); check(!err); @@ -802,15 +859,15 @@ static void t_write_multiple_indices(void) * Seeking the log uses the log index now. In case there is any * confusion regarding indices we would notice here. */ - reftable_reader_init_log_iterator(reader, &it); + err = reftable_reader_init_log_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_log(&it, ""); check(!err); reftable_iterator_destroy(&it); reftable_writer_free(writer); reftable_reader_decref(reader); - strbuf_release(&writer_buf); - strbuf_release(&buf); + reftable_buf_release(&writer_buf); } static void t_write_multi_level_index(void) @@ -818,7 +875,7 @@ static void t_write_multi_level_index(void) struct reftable_write_options opts = { .block_size = 100, }; - struct strbuf writer_buf = STRBUF_INIT, buf = STRBUF_INIT; + struct reftable_buf writer_buf = REFTABLE_BUF_INIT, buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; struct reftable_iterator it = { 0 }; const struct reftable_stats *stats; @@ -834,10 +891,10 @@ static void t_write_multi_level_index(void) .value_type = REFTABLE_REF_VAL1, .value.val1 = {i}, }; + char buf[128]; - strbuf_reset(&buf); - strbuf_addf(&buf, "refs/heads/%03" PRIuMAX, (uintmax_t)i); - ref.refname = buf.buf, + snprintf(buf, sizeof(buf), "refs/heads/%03" PRIuMAX, (uintmax_t)i); + ref.refname = buf; err = reftable_writer_add_ref(writer, &ref); check(!err); @@ -851,32 +908,33 @@ static void t_write_multi_level_index(void) stats = reftable_writer_stats(writer); check_int(stats->ref_stats.max_index_level, ==, 2); - block_source_from_strbuf(&source, &writer_buf); + block_source_from_buf(&source, &writer_buf); err = reftable_reader_new(&reader, &source, "filename"); check(!err); /* * Seeking the last ref should work as expected. */ - reftable_reader_init_ref_iterator(reader, &it); + err = reftable_reader_init_ref_iterator(reader, &it); + check(!err); err = reftable_iterator_seek_ref(&it, "refs/heads/199"); check(!err); reftable_iterator_destroy(&it); reftable_writer_free(writer); reftable_reader_decref(reader); - strbuf_release(&writer_buf); - strbuf_release(&buf); + reftable_buf_release(&writer_buf); + reftable_buf_release(&buf); } static void t_corrupt_table_empty(void) { - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; struct reftable_reader *reader; int err; - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.log"); check_int(err, ==, REFTABLE_FORMAT_ERROR); } @@ -884,17 +942,17 @@ static void t_corrupt_table_empty(void) static void t_corrupt_table(void) { uint8_t zeros[1024] = { 0 }; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; struct reftable_reader *reader; int err; - strbuf_add(&buf, zeros, sizeof(zeros)); + check(!reftable_buf_add(&buf, zeros, sizeof(zeros))); - block_source_from_strbuf(&source, &buf); + block_source_from_buf(&source, &buf); err = reftable_reader_new(&reader, &source, "file.log"); check_int(err, ==, REFTABLE_FORMAT_ERROR); - strbuf_release(&buf); + reftable_buf_release(&buf); } int cmd_main(int argc UNUSED, const char *argv[] UNUSED) @@ -904,6 +962,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_corrupt_table_empty(), "read-write on an empty table"); TEST(t_log_buffer_size(), "buffer extension for log compression"); TEST(t_log_overflow(), "log overflow returns expected error"); + TEST(t_log_write_limits(), "writer limits for writing log records"); TEST(t_log_write_read(), "read-write on log records"); TEST(t_log_zlib_corruption(), "reading corrupted log record returns expected error"); TEST(t_table_read_api(), "read on a table"); diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c index a7f67d4d9f2601..d49d2a2729cb17 100644 --- a/t/unit-tests/t-reftable-record.c +++ b/t/unit-tests/t-reftable-record.c @@ -7,6 +7,7 @@ */ #include "test-lib.h" +#include "reftable/basics.h" #include "reftable/constants.h" #include "reftable/record.h" @@ -17,10 +18,10 @@ static void t_copy(struct reftable_record *rec) typ = reftable_record_type(rec); reftable_record_init(©, typ); - reftable_record_copy_from(©, rec, GIT_SHA1_RAWSZ); + reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1); /* do it twice to catch memory leaks */ - reftable_record_copy_from(©, rec, GIT_SHA1_RAWSZ); - check(reftable_record_equal(rec, ©, GIT_SHA1_RAWSZ)); + reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1); + check(reftable_record_equal(rec, ©, REFTABLE_HASH_SIZE_SHA1)); reftable_record_release(©); } @@ -57,9 +58,25 @@ static void t_varint_roundtrip(void) } } +static void t_varint_overflow(void) +{ + unsigned char buf[] = { + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, + }; + struct string_view view = { + .buf = buf, + .len = sizeof(buf), + }; + uint64_t value; + int err = get_var_int(&value, &view); + check_int(err, ==, -1); +} + static void set_hash(uint8_t *h, int j) { - for (int i = 0; i < hash_size(GIT_SHA1_FORMAT_ID); i++) + for (size_t i = 0; i < hash_size(REFTABLE_HASH_SHA1); i++) h[i] = (j >> i) & 0xff; } @@ -84,14 +101,14 @@ static void t_reftable_ref_record_comparison(void) }, }; - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); in[1].u.ref.value_type = in[0].u.ref.value_type; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); } @@ -116,7 +133,7 @@ static void t_reftable_ref_record_compare_name(void) static void t_reftable_ref_record_roundtrip(void) { - struct strbuf scratch = STRBUF_INIT; + struct reftable_buf scratch = REFTABLE_BUF_INIT; for (int i = REFTABLE_REF_DELETION; i < REFTABLE_NR_REF_VALUETYPES; i++) { struct reftable_record in = { @@ -124,7 +141,7 @@ static void t_reftable_ref_record_roundtrip(void) .u.ref.value_type = i, }; struct reftable_record out = { .type = BLOCK_TYPE_REF }; - struct strbuf key = STRBUF_INIT; + struct reftable_buf key = REFTABLE_BUF_INIT; uint8_t buffer[1024] = { 0 }; struct string_view dest = { .buf = buffer, @@ -155,22 +172,22 @@ static void t_reftable_ref_record_roundtrip(void) check_int(reftable_record_is_deletion(&in), ==, i == REFTABLE_REF_DELETION); reftable_record_key(&in, &key); - n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >, 0); /* decode into a non-zero reftable_record to test for leaks. */ - m = reftable_record_decode(&out, key, i, dest, GIT_SHA1_RAWSZ, &scratch); + m = reftable_record_decode(&out, key, i, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(n, ==, m); check(reftable_ref_record_equal(&in.u.ref, &out.u.ref, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_record_release(&in); - strbuf_release(&key); + reftable_buf_release(&key); reftable_record_release(&out); } - strbuf_release(&scratch); + reftable_buf_release(&scratch); } static void t_reftable_log_record_comparison(void) @@ -193,15 +210,15 @@ static void t_reftable_log_record_comparison(void) }, }; - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); /* comparison should be reversed for equal keys, because * comparison is now performed on the basis of update indices */ check_int(reftable_record_cmp(&in[0], &in[1]), <, 0); in[1].u.log.update_index = in[0].u.log.update_index; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); } @@ -262,7 +279,7 @@ static void t_reftable_log_record_roundtrip(void) .value_type = REFTABLE_LOG_UPDATE, } }; - struct strbuf scratch = STRBUF_INIT; + struct reftable_buf scratch = REFTABLE_BUF_INIT; set_hash(in[0].value.update.new_hash, 1); set_hash(in[0].value.update.old_hash, 2); set_hash(in[2].value.update.new_hash, 3); @@ -274,7 +291,7 @@ static void t_reftable_log_record_roundtrip(void) for (size_t i = 0; i < ARRAY_SIZE(in); i++) { struct reftable_record rec = { .type = BLOCK_TYPE_LOG }; - struct strbuf key = STRBUF_INIT; + struct reftable_buf key = REFTABLE_BUF_INIT; uint8_t buffer[1024] = { 0 }; struct string_view dest = { .buf = buffer, @@ -303,21 +320,21 @@ static void t_reftable_log_record_roundtrip(void) reftable_record_key(&rec, &key); - n = reftable_record_encode(&rec, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&rec, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >=, 0); valtype = reftable_record_val_type(&rec); m = reftable_record_decode(&out, key, valtype, dest, - GIT_SHA1_RAWSZ, &scratch); + REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(n, ==, m); check(reftable_log_record_equal(&in[i], &out.u.log, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_log_record_release(&in[i]); - strbuf_release(&key); + reftable_buf_release(&key); reftable_record_release(&out); } - strbuf_release(&scratch); + reftable_buf_release(&scratch); } static void t_key_roundtrip(void) @@ -327,30 +344,30 @@ static void t_key_roundtrip(void) .buf = buffer, .len = sizeof(buffer), }; - struct strbuf last_key = STRBUF_INIT; - struct strbuf key = STRBUF_INIT; - struct strbuf roundtrip = STRBUF_INIT; + struct reftable_buf last_key = REFTABLE_BUF_INIT; + struct reftable_buf key = REFTABLE_BUF_INIT; + struct reftable_buf roundtrip = REFTABLE_BUF_INIT; int restart; uint8_t extra; int n, m; uint8_t rt_extra; - strbuf_addstr(&last_key, "refs/heads/master"); - strbuf_addstr(&key, "refs/tags/bla"); + check(!reftable_buf_addstr(&last_key, "refs/heads/master")); + check(!reftable_buf_addstr(&key, "refs/tags/bla")); extra = 6; n = reftable_encode_key(&restart, dest, last_key, key, extra); check(!restart); check_int(n, >, 0); - strbuf_addstr(&roundtrip, "refs/heads/master"); + check(!reftable_buf_addstr(&roundtrip, "refs/heads/master")); m = reftable_decode_key(&roundtrip, &rt_extra, dest); check_int(n, ==, m); - check(!strbuf_cmp(&key, &roundtrip)); + check(!reftable_buf_cmp(&key, &roundtrip)); check_int(rt_extra, ==, extra); - strbuf_release(&last_key); - strbuf_release(&key); - strbuf_release(&roundtrip); + reftable_buf_release(&last_key); + reftable_buf_release(&key); + reftable_buf_release(&roundtrip); } static void t_reftable_obj_record_comparison(void) @@ -380,20 +397,20 @@ static void t_reftable_obj_record_comparison(void) }, }; - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); in[1].u.obj.offset_len = in[0].u.obj.offset_len; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); } static void t_reftable_obj_record_roundtrip(void) { - uint8_t testHash1[GIT_SHA1_RAWSZ] = { 1, 2, 3, 4, 0 }; + uint8_t testHash1[REFTABLE_HASH_SIZE_SHA1] = { 1, 2, 3, 4, 0 }; uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 }; struct reftable_obj_record recs[3] = { { @@ -413,7 +430,7 @@ static void t_reftable_obj_record_roundtrip(void) .hash_prefix_len = 5, }, }; - struct strbuf scratch = STRBUF_INIT; + struct reftable_buf scratch = REFTABLE_BUF_INIT; for (size_t i = 0; i < ARRAY_SIZE(recs); i++) { uint8_t buffer[1024] = { 0 }; @@ -427,7 +444,7 @@ static void t_reftable_obj_record_roundtrip(void) .obj = recs[i], }, }; - struct strbuf key = STRBUF_INIT; + struct reftable_buf key = REFTABLE_BUF_INIT; struct reftable_record out = { .type = BLOCK_TYPE_OBJ }; int n, m; uint8_t extra; @@ -435,19 +452,19 @@ static void t_reftable_obj_record_roundtrip(void) check(!reftable_record_is_deletion(&in)); t_copy(&in); reftable_record_key(&in, &key); - n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >, 0); extra = reftable_record_val_type(&in); m = reftable_record_decode(&out, key, extra, dest, - GIT_SHA1_RAWSZ, &scratch); + REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(n, ==, m); - check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ)); - strbuf_release(&key); + check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1)); + reftable_buf_release(&key); reftable_record_release(&out); } - strbuf_release(&scratch); + reftable_buf_release(&scratch); } static void t_reftable_index_record_comparison(void) @@ -456,31 +473,31 @@ static void t_reftable_index_record_comparison(void) { .type = BLOCK_TYPE_INDEX, .u.idx.offset = 22, - .u.idx.last_key = STRBUF_INIT, + .u.idx.last_key = REFTABLE_BUF_INIT, }, { .type = BLOCK_TYPE_INDEX, .u.idx.offset = 32, - .u.idx.last_key = STRBUF_INIT, + .u.idx.last_key = REFTABLE_BUF_INIT, }, { .type = BLOCK_TYPE_INDEX, .u.idx.offset = 32, - .u.idx.last_key = STRBUF_INIT, + .u.idx.last_key = REFTABLE_BUF_INIT, }, }; - strbuf_addstr(&in[0].u.idx.last_key, "refs/heads/master"); - strbuf_addstr(&in[1].u.idx.last_key, "refs/heads/master"); - strbuf_addstr(&in[2].u.idx.last_key, "refs/heads/branch"); + check(!reftable_buf_addstr(&in[0].u.idx.last_key, "refs/heads/master")); + check(!reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master")); + check(!reftable_buf_addstr(&in[2].u.idx.last_key, "refs/heads/branch")); - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); in[1].u.idx.offset = in[0].u.idx.offset; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); for (size_t i = 0; i < ARRAY_SIZE(in); i++) @@ -493,7 +510,7 @@ static void t_reftable_index_record_roundtrip(void) .type = BLOCK_TYPE_INDEX, .u.idx = { .offset = 42, - .last_key = STRBUF_INIT, + .last_key = REFTABLE_BUF_INIT, }, }; uint8_t buffer[1024] = { 0 }; @@ -501,35 +518,35 @@ static void t_reftable_index_record_roundtrip(void) .buf = buffer, .len = sizeof(buffer), }; - struct strbuf scratch = STRBUF_INIT; - struct strbuf key = STRBUF_INIT; + struct reftable_buf scratch = REFTABLE_BUF_INIT; + struct reftable_buf key = REFTABLE_BUF_INIT; struct reftable_record out = { .type = BLOCK_TYPE_INDEX, - .u.idx = { .last_key = STRBUF_INIT }, + .u.idx = { .last_key = REFTABLE_BUF_INIT }, }; int n, m; uint8_t extra; - strbuf_addstr(&in.u.idx.last_key, "refs/heads/master"); + check(!reftable_buf_addstr(&in.u.idx.last_key, "refs/heads/master")); reftable_record_key(&in, &key); t_copy(&in); check(!reftable_record_is_deletion(&in)); - check(!strbuf_cmp(&key, &in.u.idx.last_key)); - n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ); + check(!reftable_buf_cmp(&key, &in.u.idx.last_key)); + n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >, 0); extra = reftable_record_val_type(&in); - m = reftable_record_decode(&out, key, extra, dest, GIT_SHA1_RAWSZ, + m = reftable_record_decode(&out, key, extra, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(m, ==, n); - check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1)); reftable_record_release(&out); - strbuf_release(&key); - strbuf_release(&scratch); - strbuf_release(&in.u.idx.last_key); + reftable_buf_release(&key); + reftable_buf_release(&scratch); + reftable_buf_release(&in.u.idx.last_key); } int cmd_main(int argc UNUSED, const char *argv[] UNUSED) @@ -543,6 +560,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_reftable_log_record_roundtrip(), "record operations work on log record"); TEST(t_reftable_ref_record_roundtrip(), "record operations work on ref record"); TEST(t_varint_roundtrip(), "put_var_int and get_var_int work"); + TEST(t_varint_overflow(), "get_var_int notices an integer overflow"); TEST(t_key_roundtrip(), "reftable_encode_key and reftable_decode_key work"); TEST(t_reftable_obj_record_roundtrip(), "record operations work on obj record"); TEST(t_reftable_index_record_roundtrip(), "record operations work on index record"); diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c index 31d563d992912f..c3f0059c346edb 100644 --- a/t/unit-tests/t-reftable-stack.c +++ b/t/unit-tests/t-reftable-stack.c @@ -6,17 +6,22 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-lib.h" #include "lib-reftable.h" +#include "dir.h" #include "reftable/merged.h" #include "reftable/reader.h" #include "reftable/reftable-error.h" #include "reftable/stack.h" +#include "strbuf.h" +#include "tempfile.h" #include <dirent.h> static void clear_dir(const char *dirname) { - struct strbuf path = STRBUF_INIT; + struct strbuf path = REFTABLE_BUF_INIT; strbuf_addstr(&path, dirname); remove_dir_recursively(&path, 0); strbuf_release(&path); @@ -98,14 +103,14 @@ static void t_read_file(void) static int write_test_ref(struct reftable_writer *wr, void *arg) { struct reftable_ref_record *ref = arg; - reftable_writer_set_limits(wr, ref->update_index, ref->update_index); + check(!reftable_writer_set_limits(wr, ref->update_index, + ref->update_index)); return reftable_writer_add_ref(wr, ref); } static void write_n_ref_tables(struct reftable_stack *st, size_t n) { - struct strbuf buf = STRBUF_INIT; int disable_auto_compact; int err; @@ -117,18 +122,17 @@ static void write_n_ref_tables(struct reftable_stack *st, .update_index = reftable_stack_next_update_index(st), .value_type = REFTABLE_REF_VAL1, }; + char buf[128]; - strbuf_reset(&buf); - strbuf_addf(&buf, "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i); - ref.refname = buf.buf; - t_reftable_set_hash(ref.value.val1, i, GIT_SHA1_FORMAT_ID); + snprintf(buf, sizeof(buf), "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i); + ref.refname = buf; + t_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1); err = reftable_stack_add(st, &write_test_ref, &ref); check(!err); } st->opts.disable_auto_compact = disable_auto_compact; - strbuf_release(&buf); } struct write_log_arg { @@ -140,14 +144,15 @@ static int write_test_log(struct reftable_writer *wr, void *arg) { struct write_log_arg *wla = arg; - reftable_writer_set_limits(wr, wla->update_index, wla->update_index); + check(!reftable_writer_set_limits(wr, wla->update_index, + wla->update_index)); return reftable_writer_add_log(wr, wla->log); } static void t_reftable_stack_add_one(void) { char *dir = get_tmp_dir(__LINE__); - struct strbuf scratch = STRBUF_INIT; + struct reftable_buf scratch = REFTABLE_BUF_INIT; int mask = umask(002); struct reftable_write_options opts = { .default_permissions = 0660, @@ -170,21 +175,21 @@ static void t_reftable_stack_add_one(void) err = reftable_stack_read_ref(st, ref.refname, &dest); check(!err); - check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); check_int(st->readers_len, >, 0); #ifndef GIT_WINDOWS_NATIVE - strbuf_addstr(&scratch, dir); - strbuf_addstr(&scratch, "/tables.list"); + check(!reftable_buf_addstr(&scratch, dir)); + check(!reftable_buf_addstr(&scratch, "/tables.list")); err = stat(scratch.buf, &stat_result); check(!err); check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); - strbuf_reset(&scratch); - strbuf_addstr(&scratch, dir); - strbuf_addstr(&scratch, "/"); + reftable_buf_reset(&scratch); + check(!reftable_buf_addstr(&scratch, dir)); + check(!reftable_buf_addstr(&scratch, "/")); /* do not try at home; not an external API for reftable. */ - strbuf_addstr(&scratch, st->readers[0]->name); + check(!reftable_buf_addstr(&scratch, st->readers[0]->name)); err = stat(scratch.buf, &stat_result); check(!err); check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); @@ -194,7 +199,7 @@ static void t_reftable_stack_add_one(void) reftable_ref_record_release(&dest); reftable_stack_destroy(st); - strbuf_release(&scratch); + reftable_buf_release(&scratch); clear_dir(dir); umask(mask); } @@ -281,7 +286,7 @@ static void t_reftable_stack_transaction_api(void) err = reftable_stack_read_ref(st, ref.refname, &dest); check(!err); check_int(REFTABLE_REF_SYMREF, ==, dest.value_type); - check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&dest); reftable_stack_destroy(st); @@ -341,7 +346,7 @@ static void t_reftable_stack_transaction_with_reload(void) for (size_t i = 0; i < ARRAY_SIZE(refs); i++) { err = reftable_stack_read_ref(st2, refs[i].refname, &ref); check(!err); - check(reftable_ref_record_equal(&refs[i], &ref, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&refs[i], &ref, REFTABLE_HASH_SIZE_SHA1)); } reftable_ref_record_release(&ref); @@ -416,7 +421,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void) }; struct reftable_write_options opts = { 0 }; struct reftable_stack *st; - struct strbuf table_path = STRBUF_INIT; + struct reftable_buf table_path = REFTABLE_BUF_INIT; char *dir = get_tmp_dir(__LINE__); int err; @@ -434,7 +439,10 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void) * Adding a new table to the stack should not be impacted by this, even * though auto-compaction will now fail. */ - strbuf_addf(&table_path, "%s/%s.lock", dir, st->readers[0]->name); + check(!reftable_buf_addstr(&table_path, dir)); + check(!reftable_buf_addstr(&table_path, "/")); + check(!reftable_buf_addstr(&table_path, st->readers[0]->name)); + check(!reftable_buf_addstr(&table_path, ".lock")); write_file_buf(table_path.buf, "", 0); ref.update_index = 2; @@ -445,7 +453,7 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void) check_int(st->stats.failures, ==, 1); reftable_stack_destroy(st); - strbuf_release(&table_path); + reftable_buf_release(&table_path); clear_dir(dir); } @@ -515,7 +523,7 @@ static void t_reftable_stack_add(void) char *dir = get_tmp_dir(__LINE__); struct reftable_ref_record refs[2] = { 0 }; struct reftable_log_record logs[2] = { 0 }; - struct strbuf path = STRBUF_INIT; + struct reftable_buf path = REFTABLE_BUF_INIT; struct stat stat_result; size_t i, N = ARRAY_SIZE(refs); @@ -528,13 +536,13 @@ static void t_reftable_stack_add(void) refs[i].refname = xstrdup(buf); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); logs[i].refname = xstrdup(buf); logs[i].update_index = N + i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("identity@invalid"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { @@ -560,7 +568,7 @@ static void t_reftable_stack_add(void) int err = reftable_stack_read_ref(st, refs[i].refname, &dest); check(!err); check(reftable_ref_record_equal(&dest, refs + i, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&dest); } @@ -569,22 +577,22 @@ static void t_reftable_stack_add(void) int err = reftable_stack_read_log(st, refs[i].refname, &dest); check(!err); check(reftable_log_record_equal(&dest, logs + i, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_log_record_release(&dest); } #ifndef GIT_WINDOWS_NATIVE - strbuf_addstr(&path, dir); - strbuf_addstr(&path, "/tables.list"); + check(!reftable_buf_addstr(&path, dir)); + check(!reftable_buf_addstr(&path, "/tables.list")); err = stat(path.buf, &stat_result); check(!err); check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); - strbuf_reset(&path); - strbuf_addstr(&path, dir); - strbuf_addstr(&path, "/"); + reftable_buf_reset(&path); + check(!reftable_buf_addstr(&path, dir)); + check(!reftable_buf_addstr(&path, "/")); /* do not try at home; not an external API for reftable. */ - strbuf_addstr(&path, st->readers[0]->name); + check(!reftable_buf_addstr(&path, st->readers[0]->name)); err = stat(path.buf, &stat_result); check(!err); check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); @@ -598,7 +606,7 @@ static void t_reftable_stack_add(void) reftable_ref_record_release(&refs[i]); reftable_log_record_release(&logs[i]); } - strbuf_release(&path); + reftable_buf_release(&path); clear_dir(dir); } @@ -620,14 +628,14 @@ static void t_reftable_stack_iterator(void) refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); logs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); logs[i].update_index = i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("johndoe@invalid"); logs[i].value.update.message = xstrdup("commit\n"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { @@ -654,14 +662,16 @@ static void t_reftable_stack_iterator(void) if (err > 0) break; check(!err); - check(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &refs[i], REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&ref); } check_int(i, ==, N); reftable_iterator_destroy(&it); - reftable_stack_init_log_iterator(st, &it); + err = reftable_stack_init_log_iterator(st, &it); + check(!err); + reftable_iterator_seek_log(&it, logs[0].refname); for (i = 0; ; i++) { struct reftable_log_record log = { 0 }; @@ -670,7 +680,7 @@ static void t_reftable_stack_iterator(void) if (err > 0) break; check(!err); - check(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ)); + check(reftable_log_record_equal(&log, &logs[i], REFTABLE_HASH_SIZE_SHA1)); reftable_log_record_release(&log); } check_int(i, ==, N); @@ -763,16 +773,20 @@ static void t_reftable_stack_tombstone(void) if (i % 2 == 0) { refs[i].value_type = REFTABLE_REF_VAL1; t_reftable_set_hash(refs[i].value.val1, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); } logs[i].refname = xstrdup(buf); - /* update_index is part of the key. */ - logs[i].update_index = 42; + /* + * update_index is part of the key so should be constant. + * The value itself should be less than the writer's upper + * limit. + */ + logs[i].update_index = 1; if (i % 2 == 0) { logs[i].value_type = REFTABLE_LOG_UPDATE; t_reftable_set_hash(logs[i].value.update.new_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); logs[i].value.update.email = xstrdup("identity@invalid"); } @@ -832,7 +846,7 @@ static void t_reftable_stack_hash_id(void) .value.symref = (char *) "target", .update_index = 1, }; - struct reftable_write_options opts32 = { .hash_id = GIT_SHA256_FORMAT_ID }; + struct reftable_write_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 }; struct reftable_stack *st32 = NULL; struct reftable_write_options opts_default = { 0 }; struct reftable_stack *st_default = NULL; @@ -855,7 +869,7 @@ static void t_reftable_stack_hash_id(void) err = reftable_stack_read_ref(st_default, "master", &dest); check(!err); - check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&dest); reftable_stack_destroy(st); reftable_stack_destroy(st_default); @@ -905,7 +919,7 @@ static void t_reflog_expire(void) logs[i].value.update.time = i; logs[i].value.update.email = xstrdup("identity@invalid"); t_reftable_set_hash(logs[i].value.update.new_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); } for (i = 1; i <= N; i++) { @@ -949,7 +963,7 @@ static void t_reflog_expire(void) static int write_nothing(struct reftable_writer *wr, void *arg UNUSED) { - reftable_writer_set_limits(wr, 1, 1); + check(!reftable_writer_set_limits(wr, 1, 1)); return 0; } @@ -1060,7 +1074,7 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void) .disable_auto_compact = 1, }; struct reftable_stack *st = NULL; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; char *dir = get_tmp_dir(__LINE__); int err; @@ -1075,8 +1089,10 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void) * size, we expect that auto-compaction will want to compact all of the * tables. Locking any of the tables will keep it from doing so. */ - strbuf_reset(&buf); - strbuf_addf(&buf, "%s/%s.lock", dir, st->readers[2]->name); + check(!reftable_buf_addstr(&buf, dir)); + check(!reftable_buf_addstr(&buf, "/")); + check(!reftable_buf_addstr(&buf, st->readers[2]->name)); + check(!reftable_buf_addstr(&buf, ".lock")); write_file_buf(buf.buf, "", 0); /* @@ -1091,7 +1107,7 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void) check_int(st->merged->readers_len, ==, 4); reftable_stack_destroy(st); - strbuf_release(&buf); + reftable_buf_release(&buf); clear_dir(dir); } @@ -1099,7 +1115,6 @@ static void t_reftable_stack_add_performs_auto_compaction(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - struct strbuf refname = STRBUF_INIT; char *dir = get_tmp_dir(__LINE__); int err; size_t i, n = 20; @@ -1113,6 +1128,7 @@ static void t_reftable_stack_add_performs_auto_compaction(void) .value_type = REFTABLE_REF_SYMREF, .value.symref = (char *) "master", }; + char buf[128]; /* * Disable auto-compaction for all but the last runs. Like this @@ -1121,9 +1137,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void) */ st->opts.disable_auto_compact = i != n; - strbuf_reset(&refname); - strbuf_addf(&refname, "branch-%04"PRIuMAX, (uintmax_t)i); - ref.refname = refname.buf; + snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i); + ref.refname = buf; err = reftable_stack_add(st, write_test_ref, &ref); check(!err); @@ -1140,7 +1155,6 @@ static void t_reftable_stack_add_performs_auto_compaction(void) } reftable_stack_destroy(st); - strbuf_release(&refname); clear_dir(dir); } @@ -1150,7 +1164,7 @@ static void t_reftable_stack_compaction_with_locked_tables(void) .disable_auto_compact = 1, }; struct reftable_stack *st = NULL; - struct strbuf buf = STRBUF_INIT; + struct reftable_buf buf = REFTABLE_BUF_INIT; char *dir = get_tmp_dir(__LINE__); int err; @@ -1161,8 +1175,10 @@ static void t_reftable_stack_compaction_with_locked_tables(void) check_int(st->merged->readers_len, ==, 3); /* Lock one of the tables that we're about to compact. */ - strbuf_reset(&buf); - strbuf_addf(&buf, "%s/%s.lock", dir, st->readers[1]->name); + check(!reftable_buf_addstr(&buf, dir)); + check(!reftable_buf_addstr(&buf, "/")); + check(!reftable_buf_addstr(&buf, st->readers[1]->name)); + check(!reftable_buf_addstr(&buf, ".lock")); write_file_buf(buf.buf, "", 0); /* @@ -1175,7 +1191,7 @@ static void t_reftable_stack_compaction_with_locked_tables(void) check_int(st->merged->readers_len, ==, 3); reftable_stack_destroy(st); - strbuf_release(&buf); + reftable_buf_release(&buf); clear_dir(dir); } @@ -1209,7 +1225,7 @@ static void unclean_stack_close(struct reftable_stack *st) for (size_t i = 0; i < st->readers_len; i++) reftable_reader_decref(st->readers[i]); st->readers_len = 0; - FREE_AND_NULL(st->readers); + REFTABLE_FREE_AND_NULL(st->readers); } static void t_reftable_stack_compaction_concurrent_clean(void) @@ -1301,7 +1317,7 @@ static void t_reftable_stack_reload_with_missing_table(void) struct reftable_stack *st = NULL; struct reftable_ref_record rec = { 0 }; struct reftable_iterator it = { 0 }; - struct strbuf table_path = STRBUF_INIT, content = STRBUF_INIT; + struct reftable_buf table_path = REFTABLE_BUF_INIT, content = REFTABLE_BUF_INIT; char *dir = get_tmp_dir(__LINE__); int err; @@ -1319,10 +1335,13 @@ static void t_reftable_stack_reload_with_missing_table(void) * our old readers. This should trigger a partial reload of the stack, * where we try to reuse our old readers. */ - strbuf_addf(&content, "%s\n", st->readers[0]->name); - strbuf_addf(&content, "%s\n", st->readers[1]->name); - strbuf_addstr(&content, "garbage\n"); - strbuf_addf(&table_path, "%s.lock", st->list_file); + check(!reftable_buf_addstr(&content, st->readers[0]->name)); + check(!reftable_buf_addstr(&content, "\n")); + check(!reftable_buf_addstr(&content, st->readers[1]->name)); + check(!reftable_buf_addstr(&content, "\n")); + check(!reftable_buf_addstr(&content, "garbage\n")); + check(!reftable_buf_addstr(&table_path, st->list_file)); + check(!reftable_buf_addstr(&table_path, ".lock")); write_file_buf(table_path.buf, content.buf, content.len); err = rename(table_path.buf, st->list_file); check(!err); @@ -1347,8 +1366,53 @@ static void t_reftable_stack_reload_with_missing_table(void) reftable_ref_record_release(&rec); reftable_iterator_destroy(&it); reftable_stack_destroy(st); - strbuf_release(&table_path); - strbuf_release(&content); + reftable_buf_release(&table_path); + reftable_buf_release(&content); + clear_dir(dir); +} + +static int write_limits_after_ref(struct reftable_writer *wr, void *arg) +{ + struct reftable_ref_record *ref = arg; + check(!reftable_writer_set_limits(wr, ref->update_index, ref->update_index)); + check(!reftable_writer_add_ref(wr, ref)); + return reftable_writer_set_limits(wr, ref->update_index, ref->update_index); +} + +static void t_reftable_invalid_limit_updates(void) +{ + struct reftable_ref_record ref = { + .refname = (char *) "HEAD", + .update_index = 1, + .value_type = REFTABLE_REF_SYMREF, + .value.symref = (char *) "master", + }; + struct reftable_write_options opts = { + .default_permissions = 0660, + }; + struct reftable_addition *add = NULL; + char *dir = get_tmp_dir(__LINE__); + struct reftable_stack *st = NULL; + int err; + + err = reftable_new_stack(&st, dir, &opts); + check(!err); + + reftable_addition_destroy(add); + + err = reftable_stack_new_addition(&add, st, 0); + check(!err); + + /* + * write_limits_after_ref also updates the update indexes after adding + * the record. This should cause an err to be returned, since the limits + * must be set at the start. + */ + err = reftable_addition_add(add, write_limits_after_ref, &ref); + check_int(err, ==, REFTABLE_API_ERROR); + + reftable_addition_destroy(add); + reftable_stack_destroy(st); clear_dir(dir); } @@ -1357,6 +1421,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_empty_add(), "empty addition to stack"); TEST(t_read_file(), "read_lines works"); TEST(t_reflog_expire(), "expire reflog entries"); + TEST(t_reftable_invalid_limit_updates(), "prevent limit updates after adding records"); TEST(t_reftable_stack_add(), "add multiple refs and logs to stack"); TEST(t_reftable_stack_add_one(), "add a single ref record to stack"); TEST(t_reftable_stack_add_performs_auto_compaction(), "addition to stack triggers auto-compaction"); diff --git a/t/unit-tests/t-strbuf.c b/t/unit-tests/t-strbuf.c deleted file mode 100644 index 3f4044d69797cb..00000000000000 --- a/t/unit-tests/t-strbuf.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "test-lib.h" -#include "strbuf.h" - -/* wrapper that supplies tests with an empty, initialized strbuf */ -static void setup(void (*f)(struct strbuf*, const void*), - const 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*, const void*), - const char *init_str, const 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, const 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, const 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 UNUSED, const char **argv UNUSED) -{ - 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/t-strcmp-offset.c b/t/unit-tests/t-strcmp-offset.c deleted file mode 100644 index 6880f21161e6a8..00000000000000 --- a/t/unit-tests/t-strcmp-offset.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "test-lib.h" -#include "read-cache-ll.h" - -static void check_strcmp_offset(const char *string1, const char *string2, - int expect_result, uintmax_t expect_offset) -{ - size_t offset; - int result = strcmp_offset(string1, string2, &offset); - - /* - * Because different CRTs behave differently, only rely on signs of the - * result values. - */ - result = (result < 0 ? -1 : - result > 0 ? 1 : - 0); - - check_int(result, ==, expect_result); - check_uint((uintmax_t)offset, ==, expect_offset); -} - -#define TEST_STRCMP_OFFSET(string1, string2, expect_result, expect_offset) \ - TEST(check_strcmp_offset(string1, string2, expect_result, \ - expect_offset), \ - "strcmp_offset(%s, %s) works", #string1, #string2) - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - TEST_STRCMP_OFFSET("abc", "abc", 0, 3); - TEST_STRCMP_OFFSET("abc", "def", -1, 0); - TEST_STRCMP_OFFSET("abc", "abz", -1, 2); - TEST_STRCMP_OFFSET("abc", "abcdef", -1, 3); - - return test_done(); -} diff --git a/t/unit-tests/t-trailer.c b/t/unit-tests/t-trailer.c index e1c6ad7461ed2e..184593e73d6e23 100644 --- a/t/unit-tests/t-trailer.c +++ b/t/unit-tests/t-trailer.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-lib.h" #include "trailer.h" diff --git a/t/unit-tests/test-lib.c b/t/unit-tests/test-lib.c index fa1f95965c709a..87e1f5c201f253 100644 --- a/t/unit-tests/test-lib.c +++ b/t/unit-tests/test-lib.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "test-lib.h" enum result { diff --git a/t/unit-tests/ctype.c b/t/unit-tests/u-ctype.c similarity index 100% rename from t/unit-tests/ctype.c rename to t/unit-tests/u-ctype.c diff --git a/t/unit-tests/u-example-decorate.c b/t/unit-tests/u-example-decorate.c new file mode 100644 index 00000000000000..9b1d1ce753c02e --- /dev/null +++ b/t/unit-tests/u-example-decorate.c @@ -0,0 +1,64 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "unit-test.h" +#include "object.h" +#include "decorate.h" +#include "repository.h" + +struct test_vars { + struct object *one, *two, *three; + struct decoration n; + int decoration_a, decoration_b; +}; + +static struct test_vars vars; + +void test_example_decorate__initialize(void) +{ + struct object_id one_oid = { { 1 } }, two_oid = { { 2 } }, three_oid = { { 3 } }; + + vars.one = lookup_unknown_object(the_repository, &one_oid); + vars.two = lookup_unknown_object(the_repository, &two_oid); + vars.three = lookup_unknown_object(the_repository, &three_oid); +} + +void test_example_decorate__cleanup(void) +{ + clear_decoration(&vars.n, NULL); +} + +void test_example_decorate__add(void) +{ + cl_assert_equal_p(add_decoration(&vars.n, vars.one, &vars.decoration_a), NULL); + cl_assert_equal_p(add_decoration(&vars.n, vars.two, NULL), NULL); +} + +void test_example_decorate__readd(void) +{ + cl_assert_equal_p(add_decoration(&vars.n, vars.one, &vars.decoration_a), NULL); + cl_assert_equal_p(add_decoration(&vars.n, vars.two, NULL), NULL); + cl_assert_equal_p(add_decoration(&vars.n, vars.one, NULL), &vars.decoration_a); + cl_assert_equal_p(add_decoration(&vars.n, vars.two, &vars.decoration_b), NULL); +} + +void test_example_decorate__lookup(void) +{ + cl_assert_equal_p(add_decoration(&vars.n, vars.two, &vars.decoration_b), NULL); + cl_assert_equal_p(add_decoration(&vars.n, vars.one, NULL), NULL); + cl_assert_equal_p(lookup_decoration(&vars.n, vars.two), &vars.decoration_b); + cl_assert_equal_p(lookup_decoration(&vars.n, vars.one), NULL); +} + +void test_example_decorate__loop(void) +{ + int objects_noticed = 0; + + cl_assert_equal_p(add_decoration(&vars.n, vars.one, &vars.decoration_a), NULL); + cl_assert_equal_p(add_decoration(&vars.n, vars.two, &vars.decoration_b), NULL); + + for (size_t i = 0; i < vars.n.size; i++) + if (vars.n.entries[i].base) + objects_noticed++; + + cl_assert_equal_i(objects_noticed, 2); +} diff --git a/t/unit-tests/t-hash.c b/t/unit-tests/u-hash.c similarity index 77% rename from t/unit-tests/t-hash.c rename to t/unit-tests/u-hash.c index e62647019bcd47..bd4ac6a6e1f05f 100644 --- a/t/unit-tests/t-hash.c +++ b/t/unit-tests/u-hash.c @@ -1,84 +1,109 @@ -#include "test-lib.h" +#include "unit-test.h" #include "hex.h" #include "strbuf.h" static void check_hash_data(const void *data, size_t data_length, const char *expected_hashes[]) { - if (!check(data != NULL)) { - test_msg("BUG: NULL data pointer provided"); - return; - } + cl_assert(data != NULL); for (size_t i = 1; i < ARRAY_SIZE(hash_algos); i++) { - git_hash_ctx ctx; + struct git_hash_ctx ctx; unsigned char hash[GIT_MAX_HEXSZ]; const struct git_hash_algo *algop = &hash_algos[i]; algop->init_fn(&ctx); - algop->update_fn(&ctx, data, data_length); - algop->final_fn(hash, &ctx); + git_hash_update(&ctx, data, data_length); + git_hash_final(hash, &ctx); - if (!check_str(hash_to_hex_algop(hash, algop), expected_hashes[i - 1])) - test_msg("result does not match with the expected for %s\n", hash_algos[i].name); + cl_assert_equal_s(hash_to_hex_algop(hash,algop), expected_hashes[i - 1]); } } /* Works with a NUL terminated string. Doesn't work if it should contain a NUL character. */ #define TEST_HASH_STR(data, expected_sha1, expected_sha256) do { \ const char *expected_hashes[] = { expected_sha1, expected_sha256 }; \ - TEST(check_hash_data(data, strlen(data), expected_hashes), \ - "SHA1 and SHA256 (%s) works", #data); \ + check_hash_data(data, strlen(data), expected_hashes); \ } while (0) /* Only works with a literal string, useful when it contains a NUL character. */ #define TEST_HASH_LITERAL(literal, expected_sha1, expected_sha256) do { \ const char *expected_hashes[] = { expected_sha1, expected_sha256 }; \ - TEST(check_hash_data(literal, (sizeof(literal) - 1), expected_hashes), \ - "SHA1 and SHA256 (%s) works", #literal); \ + check_hash_data(literal, (sizeof(literal) - 1), expected_hashes); \ } while (0) -int cmd_main(int argc UNUSED, const char **argv UNUSED) +void test_hash__empty_string(void) { - struct strbuf aaaaaaaaaa_100000 = STRBUF_INIT; - struct strbuf alphabet_100000 = STRBUF_INIT; - - strbuf_addstrings(&aaaaaaaaaa_100000, "aaaaaaaaaa", 100000); - strbuf_addstrings(&alphabet_100000, "abcdefghijklmnopqrstuvwxyz", 100000); - TEST_HASH_STR("", "da39a3ee5e6b4b0d3255bfef95601890afd80709", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); +} + +void test_hash__single_character(void) +{ TEST_HASH_STR("a", "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"); +} + +void test_hash__multi_character(void) +{ TEST_HASH_STR("abc", "a9993e364706816aba3e25717850c26c9cd0d89d", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); +} + +void test_hash__message_digest(void) +{ TEST_HASH_STR("message digest", "c12252ceda8be8994d5fa0290a47231c1d16aae3", "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650"); +} + +void test_hash__alphabet(void) +{ TEST_HASH_STR("abcdefghijklmnopqrstuvwxyz", "32d10c7b8cf96570ca04ce37f2a19d84240d3a89", "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73"); +} + +void test_hash__aaaaaaaaaa_100000(void) +{ + struct strbuf aaaaaaaaaa_100000 = STRBUF_INIT; + strbuf_addstrings(&aaaaaaaaaa_100000, "aaaaaaaaaa", 100000); TEST_HASH_STR(aaaaaaaaaa_100000.buf, "34aa973cd4c4daa4f61eeb2bdbad27316534016f", "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); + strbuf_release(&aaaaaaaaaa_100000); +} + +void test_hash__alphabet_100000(void) +{ + struct strbuf alphabet_100000 = STRBUF_INIT; + strbuf_addstrings(&alphabet_100000, "abcdefghijklmnopqrstuvwxyz", 100000); TEST_HASH_STR(alphabet_100000.buf, "e7da7c55b3484fdf52aebec9cbe7b85a98f02fd4", "e406ba321ca712ad35a698bf0af8d61fc4dc40eca6bdcea4697962724ccbde35"); + strbuf_release(&alphabet_100000); +} + +void test_hash__zero_blob_literal(void) +{ TEST_HASH_LITERAL("blob 0\0", "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391", "473a0f4c3be8a93681a267e3b1e9a7dcda1185436fe141f7749120a303721813"); +} + +void test_hash__three_blob_literal(void) +{ TEST_HASH_LITERAL("blob 3\0abc", "f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f", "c1cf6e465077930e88dc5136641d402f72a229ddd996f627d60e9639eaba35a6"); +} + +void test_hash__zero_tree_literal(void) +{ TEST_HASH_LITERAL("tree 0\0", "4b825dc642cb6eb9a060e54bf8d69288fbee4904", "6ef19b41225c5369f1c104d45d8d85efa9b057b53b14b4b9b939dd74decc5321"); - - strbuf_release(&aaaaaaaaaa_100000); - strbuf_release(&alphabet_100000); - - return test_done(); } diff --git a/t/unit-tests/t-hashmap.c b/t/unit-tests/u-hashmap.c similarity index 60% rename from t/unit-tests/t-hashmap.c rename to t/unit-tests/u-hashmap.c index 83b79dff391c17..eb80aa13481281 100644 --- a/t/unit-tests/t-hashmap.c +++ b/t/unit-tests/u-hashmap.c @@ -1,4 +1,4 @@ -#include "test-lib.h" +#include "unit-test.h" #include "hashmap.h" #include "strbuf.h" @@ -83,23 +83,23 @@ static void t_replace(struct hashmap *map, unsigned int ignore_case) struct test_entry *entry; entry = alloc_test_entry("key1", "value1", ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); entry = alloc_test_entry(ignore_case ? "Key1" : "key1", "value2", ignore_case); entry = hashmap_put_entry(map, entry, ent); - if (check(entry != NULL)) - check_str(get_value(entry), "value1"); + cl_assert(entry != NULL); + cl_assert_equal_s(get_value(entry), "value1"); free(entry); entry = alloc_test_entry("fooBarFrotz", "value3", ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); entry = alloc_test_entry(ignore_case ? "FOObarFrotz" : "fooBarFrotz", "value4", ignore_case); entry = hashmap_put_entry(map, entry, ent); - if (check(entry != NULL)) - check_str(get_value(entry), "value3"); + cl_assert(entry != NULL); + cl_assert_equal_s(get_value(entry), "value3"); free(entry); } @@ -122,20 +122,18 @@ static void t_get(struct hashmap *map, unsigned int ignore_case) for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) { entry = alloc_test_entry(key_val[i][0], key_val[i][1], ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); } for (size_t i = 0; i < ARRAY_SIZE(query); i++) { entry = get_test_entry(map, query[i][0], ignore_case); - if (check(entry != NULL)) - check_str(get_value(entry), query[i][1]); - else - test_msg("query key: %s", query[i][0]); + cl_assert(entry != NULL); + cl_assert_equal_s(get_value(entry), query[i][1]); } - check_pointer_eq(get_test_entry(map, "notInMap", ignore_case), NULL); - check_int(map->tablesize, ==, 64); - check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val)); + cl_assert_equal_p(get_test_entry(map, "notInMap", ignore_case), NULL); + cl_assert_equal_i(map->tablesize, 64); + cl_assert_equal_i(hashmap_get_size(map), ARRAY_SIZE(key_val)); } static void t_add(struct hashmap *map, unsigned int ignore_case) @@ -165,39 +163,19 @@ static void t_add(struct hashmap *map, unsigned int ignore_case) hashmap_for_each_entry_from(map, entry, ent) { - int ret; - if (!check_int((ret = key_val_contains( - key_val, seen, - ARRAY_SIZE(key_val), entry)), - ==, 0)) { - switch (ret) { - case 1: - test_msg("found entry was not given in the input\n" - " key: %s\n value: %s", - entry->key, get_value(entry)); - break; - case 2: - test_msg("duplicate entry detected\n" - " key: %s\n value: %s", - entry->key, get_value(entry)); - break; - } - } else { - count++; - } + int ret = key_val_contains(key_val, seen, + ARRAY_SIZE(key_val), entry); + cl_assert_equal_i(ret, 0); + count++; } - check_int(count, ==, 2); + cl_assert_equal_i(count, 2); } - for (size_t i = 0; i < ARRAY_SIZE(seen); i++) { - if (!check_int(seen[i], ==, 1)) - test_msg("following key-val pair was not iterated over:\n" - " key: %s\n value: %s", - key_val[i][0], key_val[i][1]); - } + for (size_t i = 0; i < ARRAY_SIZE(seen); i++) + cl_assert_equal_i(seen[i], 1); - check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val)); - check_pointer_eq(get_test_entry(map, "notInMap", ignore_case), NULL); + cl_assert_equal_i(hashmap_get_size(map), ARRAY_SIZE(key_val)); + cl_assert_equal_p(get_test_entry(map, "notInMap", ignore_case), NULL); } static void t_remove(struct hashmap *map, unsigned int ignore_case) @@ -211,24 +189,25 @@ static void t_remove(struct hashmap *map, unsigned int ignore_case) for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) { entry = alloc_test_entry(key_val[i][0], key_val[i][1], ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); } for (size_t i = 0; i < ARRAY_SIZE(remove); i++) { entry = alloc_test_entry(remove[i][0], "", ignore_case); removed = hashmap_remove_entry(map, entry, ent, remove[i][0]); - if (check(removed != NULL)) - check_str(get_value(removed), remove[i][1]); + cl_assert(removed != NULL); + cl_assert_equal_s(get_value(removed), remove[i][1]); free(entry); free(removed); } entry = alloc_test_entry("notInMap", "", ignore_case); - check_pointer_eq(hashmap_remove_entry(map, entry, ent, "notInMap"), NULL); + cl_assert_equal_p(hashmap_remove_entry(map, entry, ent, "notInMap"), NULL); free(entry); - check_int(map->tablesize, ==, 64); - check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val) - ARRAY_SIZE(remove)); + cl_assert_equal_i(map->tablesize, 64); + cl_assert_equal_i(hashmap_get_size(map), + ARRAY_SIZE(key_val) - ARRAY_SIZE(remove)); } static void t_iterate(struct hashmap *map, unsigned int ignore_case) @@ -242,38 +221,21 @@ static void t_iterate(struct hashmap *map, unsigned int ignore_case) for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) { entry = alloc_test_entry(key_val[i][0], key_val[i][1], ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); } hashmap_for_each_entry(map, &iter, entry, ent /* member name */) { - int ret; - if (!check_int((ret = key_val_contains(key_val, seen, - ARRAY_SIZE(key_val), - entry)), ==, 0)) { - switch (ret) { - case 1: - test_msg("found entry was not given in the input\n" - " key: %s\n value: %s", - entry->key, get_value(entry)); - break; - case 2: - test_msg("duplicate entry detected\n" - " key: %s\n value: %s", - entry->key, get_value(entry)); - break; - } - } + int ret = key_val_contains(key_val, seen, + ARRAY_SIZE(key_val), + entry); + cl_assert(ret == 0); } - for (size_t i = 0; i < ARRAY_SIZE(seen); i++) { - if (!check_int(seen[i], ==, 1)) - test_msg("following key-val pair was not iterated over:\n" - " key: %s\n value: %s", - key_val[i][0], key_val[i][1]); - } + for (size_t i = 0; i < ARRAY_SIZE(seen); i++) + cl_assert_equal_i(seen[i], 1); - check_int(hashmap_get_size(map), ==, ARRAY_SIZE(key_val)); + cl_assert_equal_i(hashmap_get_size(map), ARRAY_SIZE(key_val)); } static void t_alloc(struct hashmap *map, unsigned int ignore_case) @@ -284,17 +246,17 @@ static void t_alloc(struct hashmap *map, unsigned int ignore_case) char *key = xstrfmt("key%d", i); char *value = xstrfmt("value%d", i); entry = alloc_test_entry(key, value, ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); free(key); free(value); } - check_int(map->tablesize, ==, 64); - check_int(hashmap_get_size(map), ==, 51); + cl_assert_equal_i(map->tablesize, 64); + cl_assert_equal_i(hashmap_get_size(map), 51); entry = alloc_test_entry("key52", "value52", ignore_case); - check_pointer_eq(hashmap_put_entry(map, entry, ent), NULL); - check_int(map->tablesize, ==, 256); - check_int(hashmap_get_size(map), ==, 52); + cl_assert_equal_p(hashmap_put_entry(map, entry, ent), NULL); + cl_assert_equal_i(map->tablesize, 256); + cl_assert_equal_i(hashmap_get_size(map), 52); for (int i = 1; i <= 12; i++) { char *key = xstrfmt("key%d", i); @@ -302,27 +264,27 @@ static void t_alloc(struct hashmap *map, unsigned int ignore_case) entry = alloc_test_entry(key, "", ignore_case); removed = hashmap_remove_entry(map, entry, ent, key); - if (check(removed != NULL)) - check_str(value, get_value(removed)); + cl_assert(removed != NULL); + cl_assert_equal_s(value, get_value(removed)); free(key); free(value); free(entry); free(removed); } - check_int(map->tablesize, ==, 256); - check_int(hashmap_get_size(map), ==, 40); + cl_assert_equal_i(map->tablesize, 256); + cl_assert_equal_i(hashmap_get_size(map), 40); entry = alloc_test_entry("key40", "", ignore_case); removed = hashmap_remove_entry(map, entry, ent, "key40"); - if (check(removed != NULL)) - check_str("value40", get_value(removed)); - check_int(map->tablesize, ==, 64); - check_int(hashmap_get_size(map), ==, 39); + cl_assert(removed != NULL); + cl_assert_equal_s("value40", get_value(removed)); + cl_assert_equal_i(map->tablesize, 64); + cl_assert_equal_i(hashmap_get_size(map), 39); free(entry); free(removed); } -static void t_intern(void) +void test_hashmap__intern(void) { const char *values[] = { "value1", "Value1", "value2", "value2" }; @@ -330,32 +292,68 @@ static void t_intern(void) const char *i1 = strintern(values[i]); const char *i2 = strintern(values[i]); - if (!check(!strcmp(i1, values[i]))) - test_msg("strintern(%s) returns %s\n", values[i], i1); - else if (!check(i1 != values[i])) - test_msg("strintern(%s) returns input pointer\n", - values[i]); - else if (!check_pointer_eq(i1, i2)) - test_msg("address('%s') != address('%s'), so strintern('%s') != strintern('%s')", - i1, i2, values[i], values[i]); - else - check_str(i1, values[i]); + cl_assert_equal_s(i1, values[i]); + cl_assert(i1 != values[i]); + cl_assert_equal_p(i1, i2); } } -int cmd_main(int argc UNUSED, const char **argv UNUSED) +void test_hashmap__replace_case_sensitive(void) +{ + setup(t_replace, 0); +} + +void test_hashmap__replace_case_insensitive(void) +{ + setup(t_replace, 1); +} + +void test_hashmap__get_case_sensitive(void) +{ + setup(t_get, 0); +} + +void test_hashmap__get_case_insensitive(void) +{ + setup(t_get, 1); +} + +void test_hashmap__add_case_sensitive(void) +{ + setup(t_add, 0); +} + +void test_hashmap__add_case_insensitive(void) +{ + setup(t_add, 1); +} + +void test_hashmap__remove_case_sensitive(void) +{ + setup(t_remove, 0); +} + +void test_hashmap__remove_case_insensitive(void) +{ + setup(t_remove, 1); +} + +void test_hashmap__iterate_case_sensitive(void) +{ + setup(t_iterate, 0); +} + +void test_hashmap__iterate_case_insensitive(void) +{ + setup(t_iterate, 1); +} + +void test_hashmap__alloc_case_sensitive(void) +{ + setup(t_alloc, 0); +} + +void test_hashmap__alloc_case_insensitive(void) { - TEST(setup(t_replace, 0), "replace works"); - TEST(setup(t_replace, 1), "replace (case insensitive) works"); - TEST(setup(t_get, 0), "get works"); - TEST(setup(t_get, 1), "get (case insensitive) works"); - TEST(setup(t_add, 0), "add works"); - TEST(setup(t_add, 1), "add (case insensitive) works"); - TEST(setup(t_remove, 0), "remove works"); - TEST(setup(t_remove, 1), "remove (case insensitive) works"); - TEST(setup(t_iterate, 0), "iterate works"); - TEST(setup(t_iterate, 1), "iterate (case insensitive) works"); - TEST(setup(t_alloc, 0), "grow / shrink works"); - TEST(t_intern(), "string interning works"); - return test_done(); + setup(t_alloc, 1); } diff --git a/t/unit-tests/u-mem-pool.c b/t/unit-tests/u-mem-pool.c new file mode 100644 index 00000000000000..2bc2493b7ef62b --- /dev/null +++ b/t/unit-tests/u-mem-pool.c @@ -0,0 +1,25 @@ +#include "unit-test.h" +#include "mem-pool.h" + +static void test_many_pool_allocations(size_t block_alloc) +{ + struct mem_pool pool = { .block_alloc = block_alloc }; + size_t size = 100; + char *buffer = mem_pool_calloc(&pool, 1, size); + for (size_t i = 0; i < size; i++) + cl_assert_equal_i(0, buffer[i]); + cl_assert(pool.mp_block != NULL); + cl_assert(pool.mp_block->next_free != NULL); + cl_assert(pool.mp_block->end != NULL); + mem_pool_discard(&pool, 0); +} + +void test_mem_pool__big_block(void) +{ + test_many_pool_allocations(1024 * 1024); +} + +void test_mem_pool__tiny_block(void) +{ + test_many_pool_allocations(1); +} diff --git a/t/unit-tests/u-oid-array.c b/t/unit-tests/u-oid-array.c new file mode 100644 index 00000000000000..e48a433f2153b1 --- /dev/null +++ b/t/unit-tests/u-oid-array.c @@ -0,0 +1,129 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "unit-test.h" +#include "lib-oid.h" +#include "oid-array.h" +#include "hex.h" + +static void fill_array(struct oid_array *array, const char *hexes[], size_t n) +{ + for (size_t i = 0; i < n; i++) { + struct object_id oid; + + cl_parse_any_oid(hexes[i], &oid); + oid_array_append(array, &oid); + } + cl_assert_equal_i(array->nr, n); +} + +static int add_to_oid_array(const struct object_id *oid, void *data) +{ + struct oid_array *array = data; + + oid_array_append(array, oid); + return 0; +} + +static void t_enumeration(const char **input_args, size_t input_sz, + const char **expect_args, size_t expect_sz) +{ + struct oid_array input = OID_ARRAY_INIT, expect = OID_ARRAY_INIT, + actual = OID_ARRAY_INIT; + size_t i; + + fill_array(&input, input_args, input_sz); + fill_array(&expect, expect_args, expect_sz); + + oid_array_for_each_unique(&input, add_to_oid_array, &actual); + cl_assert_equal_i(actual.nr, expect.nr); + + for (i = 0; i < actual.nr; i++) + cl_assert(oideq(&actual.oid[i], &expect.oid[i])); + + oid_array_clear(&actual); + oid_array_clear(&input); + oid_array_clear(&expect); +} + +#define TEST_ENUMERATION(input, expect) \ + t_enumeration(input, ARRAY_SIZE(input), expect, ARRAY_SIZE(expect)); + +static void t_lookup(const char **input_hexes, size_t n, const char *query_hex, + int lower_bound, int upper_bound) +{ + struct oid_array array = OID_ARRAY_INIT; + struct object_id oid_query; + int ret; + + cl_parse_any_oid(query_hex, &oid_query); + fill_array(&array, input_hexes, n); + ret = oid_array_lookup(&array, &oid_query); + + cl_assert(ret <= upper_bound); + cl_assert(ret >= lower_bound); + + oid_array_clear(&array); +} + +#define TEST_LOOKUP(input_hexes, query, lower_bound, upper_bound) \ + t_lookup(input_hexes, ARRAY_SIZE(input_hexes), query, \ + lower_bound, upper_bound); + +void test_oid_array__initialize(void) +{ + /* The hash algo is used by oid_array_lookup() internally */ + int algo = cl_setup_hash_algo(); + repo_set_hash_algo(the_repository, algo); +} + +static const char *arr_input[] = { "88", "44", "aa", "55" }; +static const char *arr_input_dup[] = { "88", "44", "aa", "55", + "88", "44", "aa", "55", + "88", "44", "aa", "55" }; +static const char *res_sorted[] = { "44", "55", "88", "aa" }; + +void test_oid_array__enumerate_unique(void) +{ + TEST_ENUMERATION(arr_input, res_sorted); +} + +void test_oid_array__enumerate_duplicate(void) +{ + TEST_ENUMERATION(arr_input_dup, res_sorted); +} + +void test_oid_array__lookup(void) +{ + TEST_LOOKUP(arr_input, "55", 1, 1); +} + +void test_oid_array__lookup_non_existent(void) +{ + TEST_LOOKUP(arr_input, "33", INT_MIN, -1); +} + +void test_oid_array__lookup_duplicates(void) +{ + TEST_LOOKUP(arr_input_dup, "55", 3, 5); +} + +void test_oid_array__lookup_non_existent_dup(void) +{ + TEST_LOOKUP(arr_input_dup, "66", INT_MIN, -1); +} + +void test_oid_array__lookup_almost_dup(void) +{ + const char *nearly_55; + + nearly_55 = cl_setup_hash_algo() == GIT_HASH_SHA1 ? + "5500000000000000000000000000000000000001" : + "5500000000000000000000000000000000000000000000000000000000000001"; + + TEST_LOOKUP(((const char *[]){ "55", nearly_55 }), "55", 0, 0); +} + +void test_oid_array__lookup_single_dup(void) +{ + TEST_LOOKUP(((const char *[]){ "55", "55" }), "55", 0, 1); +} diff --git a/t/unit-tests/u-oidmap.c b/t/unit-tests/u-oidmap.c new file mode 100644 index 00000000000000..dc805b7e3cb424 --- /dev/null +++ b/t/unit-tests/u-oidmap.c @@ -0,0 +1,136 @@ +#include "unit-test.h" +#include "lib-oid.h" +#include "oidmap.h" +#include "hash.h" +#include "hex.h" + +/* + * Elements we will put in oidmap structs are made of a key: the entry.oid + * field, which is of type struct object_id, and a value: the name field (could + * be a refname for example). + */ +struct test_entry { + struct oidmap_entry entry; + char name[FLEX_ARRAY]; +}; + +static const char *const key_val[][2] = { { "11", "one" }, + { "22", "two" }, + { "33", "three" } }; + +static struct oidmap map; + +void test_oidmap__initialize(void) +{ + oidmap_init(&map, 0); + + for (size_t i = 0; i < ARRAY_SIZE(key_val); i++){ + struct test_entry *entry; + + FLEX_ALLOC_STR(entry, name, key_val[i][1]); + cl_parse_any_oid(key_val[i][0], &entry->entry.oid); + cl_assert(oidmap_put(&map, entry) == NULL); + } +} + +void test_oidmap__cleanup(void) +{ + oidmap_free(&map, 1); +} + +void test_oidmap__replace(void) +{ + struct test_entry *entry, *prev; + + FLEX_ALLOC_STR(entry, name, "un"); + cl_parse_any_oid("11", &entry->entry.oid); + prev = oidmap_put(&map, entry); + cl_assert(prev != NULL); + cl_assert_equal_s(prev->name, "one"); + free(prev); + + FLEX_ALLOC_STR(entry, name, "deux"); + cl_parse_any_oid("22", &entry->entry.oid); + prev = oidmap_put(&map, entry); + cl_assert(prev != NULL); + cl_assert_equal_s(prev->name, "two"); + free(prev); +} + +void test_oidmap__get(void) +{ + struct test_entry *entry; + struct object_id oid; + + cl_parse_any_oid("22", &oid); + entry = oidmap_get(&map, &oid); + cl_assert(entry != NULL); + cl_assert_equal_s(entry->name, "two"); + + cl_parse_any_oid("44", &oid); + cl_assert(oidmap_get(&map, &oid) == NULL); + + cl_parse_any_oid("11", &oid); + entry = oidmap_get(&map, &oid); + cl_assert(entry != NULL); + cl_assert_equal_s(entry->name, "one"); +} + +void test_oidmap__remove(void) +{ + struct test_entry *entry; + struct object_id oid; + + cl_parse_any_oid("11", &oid); + entry = oidmap_remove(&map, &oid); + cl_assert(entry != NULL); + cl_assert_equal_s(entry->name, "one"); + cl_assert(oidmap_get(&map, &oid) == NULL); + free(entry); + + cl_parse_any_oid("22", &oid); + entry = oidmap_remove(&map, &oid); + cl_assert(entry != NULL); + cl_assert_equal_s(entry->name, "two"); + cl_assert(oidmap_get(&map, &oid) == NULL); + free(entry); + + cl_parse_any_oid("44", &oid); + cl_assert(oidmap_remove(&map, &oid) == NULL); +} + +static int key_val_contains(struct test_entry *entry, char seen[]) +{ + for (size_t i = 0; i < ARRAY_SIZE(key_val); i++) { + struct object_id oid; + + cl_parse_any_oid(key_val[i][0], &oid); + + if (oideq(&entry->entry.oid, &oid)) { + if (seen[i]) + return 2; + seen[i] = 1; + return 0; + } + } + return 1; +} + +void test_oidmap__iterate(void) +{ + struct oidmap_iter iter; + struct test_entry *entry; + char seen[ARRAY_SIZE(key_val)] = { 0 }; + int count = 0; + + oidmap_iter_init(&map, &iter); + while ((entry = oidmap_iter_next(&iter))) { + if (key_val_contains(entry, seen) != 0) { + cl_failf("Unexpected entry: name = %s, oid = %s", + entry->name, oid_to_hex(&entry->entry.oid)); + } + count++; + } + cl_assert_equal_i(count, ARRAY_SIZE(key_val)); + cl_assert_equal_i(hashmap_get_size(&map.map), ARRAY_SIZE(key_val)); +} diff --git a/t/unit-tests/u-oidtree.c b/t/unit-tests/u-oidtree.c new file mode 100644 index 00000000000000..e6eede27404842 --- /dev/null +++ b/t/unit-tests/u-oidtree.c @@ -0,0 +1,107 @@ +#include "unit-test.h" +#include "lib-oid.h" +#include "oidtree.h" +#include "hash.h" +#include "hex.h" +#include "strvec.h" + +static struct oidtree ot; + +#define FILL_TREE(tree, ...) \ + do { \ + const char *hexes[] = { __VA_ARGS__ }; \ + if (fill_tree_loc(tree, hexes, ARRAY_SIZE(hexes))) \ + return; \ + } while (0) + +static int fill_tree_loc(struct oidtree *ot, const char *hexes[], size_t n) +{ + for (size_t i = 0; i < n; i++) { + struct object_id oid; + cl_parse_any_oid(hexes[i], &oid); + oidtree_insert(ot, &oid); + } + return 0; +} + +static void check_contains(struct oidtree *ot, const char *hex, int expected) +{ + struct object_id oid; + + cl_parse_any_oid(hex, &oid); + cl_assert_equal_i(oidtree_contains(ot, &oid), expected); +} + +struct expected_hex_iter { + size_t i; + struct strvec expected_hexes; + const char *query; +}; + +static enum cb_next check_each_cb(const struct object_id *oid, void *data) +{ + struct expected_hex_iter *hex_iter = data; + struct object_id expected; + + cl_assert(hex_iter->i < hex_iter->expected_hexes.nr); + + cl_parse_any_oid(hex_iter->expected_hexes.v[hex_iter->i], + &expected); + cl_assert_equal_s(oid_to_hex(oid), oid_to_hex(&expected)); + hex_iter->i += 1; + return CB_CONTINUE; +} + +LAST_ARG_MUST_BE_NULL +static void check_each(struct oidtree *ot, const char *query, ...) +{ + struct object_id oid; + struct expected_hex_iter hex_iter = { .expected_hexes = STRVEC_INIT, + .query = query }; + const char *arg; + va_list hex_args; + + va_start(hex_args, query); + while ((arg = va_arg(hex_args, const char *))) + strvec_push(&hex_iter.expected_hexes, arg); + va_end(hex_args); + + cl_parse_any_oid(query, &oid); + oidtree_each(ot, &oid, strlen(query), check_each_cb, &hex_iter); + + if (hex_iter.i != hex_iter.expected_hexes.nr) + cl_failf("error: could not find some 'object_id's for query ('%s')", query); + + strvec_clear(&hex_iter.expected_hexes); +} + +void test_oidtree__initialize(void) +{ + oidtree_init(&ot); +} + +void test_oidtree__cleanup(void) +{ + oidtree_clear(&ot); +} + +void test_oidtree__contains(void) +{ + FILL_TREE(&ot, "444", "1", "2", "3", "4", "5", "a", "b", "c", "d", "e"); + check_contains(&ot, "44", 0); + check_contains(&ot, "441", 0); + check_contains(&ot, "440", 0); + check_contains(&ot, "444", 1); + check_contains(&ot, "4440", 1); + check_contains(&ot, "4444", 0); +} + +void test_oidtree__each(void) +{ + FILL_TREE(&ot, "f", "9", "8", "123", "321", "320", "a", "b", "c", "d", "e"); + check_each(&ot, "12300", "123", NULL); + check_each(&ot, "3211", NULL); /* should not reach callback */ + check_each(&ot, "3210", "321", NULL); + check_each(&ot, "32100", "321", NULL); + check_each(&ot, "32", "320", "321", NULL); +} diff --git a/t/unit-tests/u-prio-queue.c b/t/unit-tests/u-prio-queue.c new file mode 100644 index 00000000000000..145e689c9c2e31 --- /dev/null +++ b/t/unit-tests/u-prio-queue.c @@ -0,0 +1,94 @@ +#include "unit-test.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, size_t input_size, + int *result, size_t result_size) +{ + struct prio_queue pq = { intcmp }; + size_t j = 0; + + for (size_t i = 0; i < input_size; i++) { + void *peek, *get; + switch(input[i]) { + case GET: + peek = prio_queue_peek(&pq); + get = prio_queue_get(&pq); + cl_assert(peek == get); + cl_assert(j < result_size); + cl_assert_equal_i(result[j], show(get)); + j++; + break; + case DUMP: + while ((peek = prio_queue_peek(&pq))) { + get = prio_queue_get(&pq); + cl_assert(peek == get); + cl_assert(j < result_size); + cl_assert_equal_i(result[j], show(get)); + j++; + } + break; + case STACK: + pq.compare = NULL; + break; + case REVERSE: + prio_queue_reverse(&pq); + break; + default: + prio_queue_put(&pq, &input[i]); + break; + } + } + cl_assert_equal_i(j, result_size); + clear_prio_queue(&pq); +} + +#define TEST_INPUT(input, result) \ + test_prio_queue(input, ARRAY_SIZE(input), result, ARRAY_SIZE(result)) + +void test_prio_queue__basic(void) +{ + TEST_INPUT(((int []){ 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP }), + ((int []){ 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10 })); +} + +void test_prio_queue__mixed(void) +{ + TEST_INPUT(((int []){ 6, 2, 4, GET, 5, 3, GET, GET, 1, DUMP }), + ((int []){ 2, 3, 4, 1, 5, 6 })); +} + +void test_prio_queue__empty(void) +{ + TEST_INPUT(((int []){ 1, 2, GET, GET, GET, 1, 2, GET, GET, GET }), + ((int []){ 1, 2, MISSING, 1, 2, MISSING })); +} + +void test_prio_queue__stack(void) +{ + TEST_INPUT(((int []){ STACK, 8, 1, 5, 4, 6, 2, 3, DUMP }), + ((int []){ 3, 2, 6, 4, 5, 1, 8 })); +} + +void test_prio_queue__reverse_stack(void) +{ + TEST_INPUT(((int []){ STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP }), + ((int []){ 1, 2, 3, 4, 5, 6 })); +} diff --git a/t/unit-tests/t-reftable-tree.c b/t/unit-tests/u-reftable-tree.c similarity index 63% rename from t/unit-tests/t-reftable-tree.c rename to t/unit-tests/u-reftable-tree.c index 700479d34b1096..bcf90610717d53 100644 --- a/t/unit-tests/t-reftable-tree.c +++ b/t/unit-tests/u-reftable-tree.c @@ -6,7 +6,7 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ -#include "test-lib.h" +#include "unit-test.h" #include "reftable/tree.h" static int t_compare(const void *a, const void *b) @@ -25,7 +25,7 @@ static void store(void *arg, void *key) c->arr[c->len++] = key; } -static void t_tree_search(void) +void test_reftable_tree__tree_search(void) { struct tree_node *root = NULL; void *values[11] = { 0 }; @@ -37,20 +37,21 @@ static void t_tree_search(void) * values[1] and values[10] (inclusive) in the tree. */ do { - nodes[i] = tree_search(&values[i], &root, &t_compare, 1); + nodes[i] = tree_insert(&root, &values[i], &t_compare); + cl_assert(nodes[i] != NULL); i = (i * 7) % 11; } while (i != 1); for (i = 1; i < ARRAY_SIZE(nodes); i++) { - check_pointer_eq(&values[i], nodes[i]->key); - check_pointer_eq(nodes[i], tree_search(&values[i], &root, &t_compare, 0)); + cl_assert_equal_p(&values[i], nodes[i]->key); + cl_assert_equal_p(nodes[i], tree_search(root, &values[i], &t_compare)); } - check(!tree_search(values, &root, t_compare, 0)); + cl_assert(tree_search(root, values, t_compare) == NULL); tree_free(root); } -static void t_infix_walk(void) +void test_reftable_tree__infix_walk(void) { struct tree_node *root = NULL; void *values[11] = { 0 }; @@ -62,23 +63,16 @@ static void t_infix_walk(void) size_t count = 0; do { - tree_search(&values[i], &root, t_compare, 1); + struct tree_node *node = tree_insert(&root, &values[i], t_compare); + cl_assert(node != NULL); i = (i * 7) % 11; count++; } while (i != 1); infix_walk(root, &store, &c); for (i = 1; i < ARRAY_SIZE(values); i++) - check_pointer_eq(&values[i], out[i - 1]); - check(!out[i - 1]); - check_int(c.len, ==, count); + cl_assert_equal_p(&values[i], out[i - 1]); + cl_assert(out[i - 1] == NULL); + cl_assert_equal_i(c.len, count); tree_free(root); } - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_tree_search(), "tree_search works"); - TEST(t_infix_walk(), "infix_walk works"); - - return test_done(); -} diff --git a/t/unit-tests/u-strbuf.c b/t/unit-tests/u-strbuf.c new file mode 100644 index 00000000000000..caa5d78aa34289 --- /dev/null +++ b/t/unit-tests/u-strbuf.c @@ -0,0 +1,119 @@ +#include "unit-test.h" +#include "strbuf.h" + +/* wrapper that supplies tests with an empty, initialized strbuf */ +static void setup(void (*f)(struct strbuf*, const void*), + const void *data) +{ + struct strbuf buf = STRBUF_INIT; + + f(&buf, data); + strbuf_release(&buf); + cl_assert_equal_i(buf.len, 0); + cl_assert_equal_i(buf.alloc, 0); +} + +/* wrapper that supplies tests with a populated, initialized strbuf */ +static void setup_populated(void (*f)(struct strbuf*, const void*), + const char *init_str, const void *data) +{ + struct strbuf buf = STRBUF_INIT; + + strbuf_addstr(&buf, init_str); + cl_assert_equal_i(buf.len, strlen(init_str)); + f(&buf, data); + strbuf_release(&buf); + cl_assert_equal_i(buf.len, 0); + cl_assert_equal_i(buf.alloc, 0); +} + +static void assert_sane_strbuf(struct strbuf *buf) +{ + /* Initialized strbufs should always have a non-NULL buffer */ + cl_assert(buf->buf != NULL); + /* Buffers should always be NUL-terminated */ + cl_assert(buf->buf[buf->len] == '\0'); + /* + * In case the buffer contains anything, `alloc` must alloc must + * be at least one byte larger than `len`. + */ + if (buf->len) + cl_assert(buf->len < buf->alloc); +} + +void test_strbuf__static_init(void) +{ + struct strbuf buf = STRBUF_INIT; + + cl_assert_equal_i(buf.len, 0); + cl_assert_equal_i(buf.alloc, 0); + cl_assert(buf.buf[0] == '\0'); +} + +void test_strbuf__dynamic_init(void) +{ + struct strbuf buf; + + strbuf_init(&buf, 1024); + assert_sane_strbuf(&buf); + cl_assert_equal_i(buf.len, 0); + cl_assert(buf.alloc >= 1024); + cl_assert(buf.buf[0] == '\0'); + strbuf_release(&buf); +} + +static void t_addch(struct strbuf *buf, const void *data) +{ + const char *p_ch = data; + const char ch = *p_ch; + size_t orig_alloc = buf->alloc; + size_t orig_len = buf->len; + + assert_sane_strbuf(buf); + strbuf_addch(buf, ch); + assert_sane_strbuf(buf); + cl_assert_equal_i(buf->len, orig_len + 1); + cl_assert(buf->alloc >= orig_alloc); + cl_assert(buf->buf[buf->len] == '\0'); +} + +static void t_addstr(struct strbuf *buf, const void *data) +{ + const char *text = data; + size_t len = strlen(text); + size_t orig_alloc = buf->alloc; + size_t orig_len = buf->len; + + assert_sane_strbuf(buf); + strbuf_addstr(buf, text); + assert_sane_strbuf(buf); + cl_assert_equal_i(buf->len, orig_len + len); + cl_assert(buf->alloc >= orig_alloc); + cl_assert(buf->buf[buf->len] == '\0'); + cl_assert_equal_s(buf->buf + orig_len, text); +} + +void test_strbuf__add_single_char(void) +{ + setup(t_addch, "a"); +} + +void test_strbuf__add_empty_char(void) +{ + setup(t_addch, ""); +} + +void test_strbuf__add_append_char(void) +{ + setup_populated(t_addch, "initial value", "a"); +} + +void test_strbuf__add_single_str(void) +{ + setup(t_addstr, "hello there"); +} + +void test_strbuf__add_append_str(void) +{ + setup_populated(t_addstr, "initial value", "hello there"); +} diff --git a/t/unit-tests/u-strcmp-offset.c b/t/unit-tests/u-strcmp-offset.c new file mode 100644 index 00000000000000..7e8e9acf3c617a --- /dev/null +++ b/t/unit-tests/u-strcmp-offset.c @@ -0,0 +1,45 @@ +#include "unit-test.h" +#include "read-cache-ll.h" + +static void check_strcmp_offset(const char *string1, const char *string2, + int expect_result, uintmax_t expect_offset) +{ + size_t offset; + int result = strcmp_offset(string1, string2, &offset); + + /* + * Because different CRTs behave differently, only rely on signs of the + * result values. + */ + result = (result < 0 ? -1 : + result > 0 ? 1 : + 0); + + cl_assert_equal_i(result, expect_result); + cl_assert_equal_i((uintmax_t)offset, expect_offset); +} + +void test_strcmp_offset__empty(void) +{ + check_strcmp_offset("", "", 0, 0); +} + +void test_strcmp_offset__equal(void) +{ + check_strcmp_offset("abc", "abc", 0, 3); +} + +void test_strcmp_offset__different(void) +{ + check_strcmp_offset("abc", "def", -1, 0); +} + +void test_strcmp_offset__mismatch(void) +{ + check_strcmp_offset("abc", "abz", -1, 2); +} + +void test_strcmp_offset__different_length(void) +{ + check_strcmp_offset("abc", "abcdef", -1, 3); +} diff --git a/t/unit-tests/strvec.c b/t/unit-tests/u-strvec.c similarity index 71% rename from t/unit-tests/strvec.c rename to t/unit-tests/u-strvec.c index bf4c0cb172e1f0..e66b7bbfae724a 100644 --- a/t/unit-tests/strvec.c +++ b/t/unit-tests/u-strvec.c @@ -88,6 +88,81 @@ void test_strvec__pushv(void) strvec_clear(&vec); } +void test_strvec__splice_just_initialized_strvec(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "foo" }; + + strvec_splice(&vec, 0, 0, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "foo", NULL); + strvec_clear(&vec); +} + +void test_strvec__splice_with_same_size_replacement(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "1" }; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_splice(&vec, 1, 1, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "foo", "1", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__splice_with_smaller_replacement(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "1" }; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_splice(&vec, 1, 2, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "foo", "1", NULL); + strvec_clear(&vec); +} + +void test_strvec__splice_with_bigger_replacement(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "1", "2", "3" }; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_splice(&vec, 0, 2, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "1", "2", "3", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__splice_with_empty_replacement(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_splice(&vec, 0, 2, NULL, 0); + check_strvec(&vec, "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__splice_with_empty_original(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "1", "2" }; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_splice(&vec, 1, 0, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "foo", "1", "2", "bar", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__splice_at_tail(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "1", "2" }; + + strvec_pushl(&vec, "foo", "bar", NULL); + strvec_splice(&vec, 2, 0, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "foo", "bar", "1", "2", NULL); + strvec_clear(&vec); +} + void test_strvec__replace_at_head(void) { struct strvec vec = STRVEC_INIT; diff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c index a474cdcfd351d9..5af645048adf4e 100644 --- a/t/unit-tests/unit-test.c +++ b/t/unit-tests/unit-test.c @@ -1,5 +1,7 @@ #include "unit-test.h" +#include "hex.h" #include "parse-options.h" +#include "strbuf.h" #include "string-list.h" #include "strvec.h" @@ -18,8 +20,25 @@ int cmd_main(int argc, const char **argv) N_("immediately exit upon the first failed test")), OPT_STRING_LIST('r', "run", &run_args, N_("suite[::test]"), N_("run only test suite or individual test <suite[::test]>")), - OPT_STRING_LIST('x', "exclude", &exclude_args, N_("suite"), + OPT_STRING_LIST(0, "exclude", &exclude_args, N_("suite"), N_("exclude test suite <suite>")), + /* + * Compatibility wrappers so that we don't have to filter + * options understood by integration tests. + */ + OPT_NOOP_NOARG('d', "debug"), + OPT_NOOP_NOARG(0, "github-workflow-markup"), + OPT_NOOP_NOARG(0, "no-bin-wrappers"), + OPT_NOOP_ARG(0, "root"), + OPT_NOOP_ARG(0, "stress"), + OPT_NOOP_NOARG(0, "tee"), + OPT_NOOP_NOARG(0, "with-dashes"), + OPT_NOOP_ARG(0, "valgrind"), + OPT_NOOP_ARG(0, "valgrind-only"), + OPT_NOOP_NOARG('v', "verbose"), + OPT_NOOP_NOARG('V', "verbose-log"), + OPT_NOOP_ARG(0, "verbose-only"), + OPT_NOOP_NOARG('x', NULL), OPT_END(), }; struct strvec args = STRVEC_INIT; diff --git a/tag.c b/tag.c index d24170e34062f0..8d9e9e29304c58 100644 --- a/tag.c +++ b/tag.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "environment.h" @@ -84,7 +85,7 @@ struct object *deref_tag(struct repository *r, struct object *o, const char *war o = NULL; } if (!o && warn) { - if (last_oid && is_promisor_object(last_oid)) + if (last_oid && is_promisor_object(r, last_oid)) return NULL; if (!warnlen) warnlen = strlen(warn); diff --git a/tempfile.c b/tempfile.c index ed88cf84314753..82dfa3d82f2ac9 100644 --- a/tempfile.c +++ b/tempfile.c @@ -42,6 +42,8 @@ * file created by its parent. */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "path.h" @@ -148,7 +150,7 @@ struct tempfile *create_tempfile_mode(const char *path, int mode) return NULL; } activate_tempfile(tempfile); - if (adjust_shared_perm(tempfile->filename.buf)) { + if (adjust_shared_perm(the_repository, tempfile->filename.buf)) { int save_errno = errno; error("cannot fix permission bits on %s", tempfile->filename.buf); delete_tempfile(&tempfile); diff --git a/templates/Makefile b/templates/Makefile index 367ad00c24cb34..722755338dbe9d 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -1,3 +1,6 @@ +# The default target of this Makefile is... +all:: + # Import tree-wide shared Makefile behavior and libraries include ../shared.mak @@ -23,30 +26,41 @@ PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) template_instdir_SQ = $(subst ','\'',$(template_instdir)) -all: boilerplates.made custom +all:: boilerplates.made custom # Put templates that can be copied straight from the source # in a file direc--tory--file in the source. They will be # just copied to the destination. -bpsrc = $(filter-out %~,$(wildcard *--*)) -boilerplates.made : $(bpsrc) - $(QUIET)umask 022 && ls *--* 2>/dev/null | \ - while read boilerplate; \ +TEMPLATES = +TEMPLATES += description +TEMPLATES += hooks/applypatch-msg.sample +TEMPLATES += hooks/commit-msg.sample +TEMPLATES += hooks/fsmonitor-watchman.sample +TEMPLATES += hooks/post-update.sample +TEMPLATES += hooks/pre-applypatch.sample +TEMPLATES += hooks/pre-commit.sample +TEMPLATES += hooks/pre-merge-commit.sample +TEMPLATES += hooks/prepare-commit-msg.sample +TEMPLATES += hooks/pre-push.sample +TEMPLATES += hooks/pre-rebase.sample +TEMPLATES += hooks/pre-receive.sample +TEMPLATES += hooks/push-to-checkout.sample +TEMPLATES += hooks/sendemail-validate.sample +TEMPLATES += hooks/update.sample +TEMPLATES += info/exclude + +boilerplates.made: $(TEMPLATES) + $(QUIET)umask 022 && for template in $(TEMPLATES); \ do \ - case "$$boilerplate" in *~) continue ;; esac && \ - dst=`echo "$$boilerplate" | sed -e 's|^this|.|;s|--|/|g'` && \ - dir=`expr "$$dst" : '\(.*\)/'` && \ + dir=$$(dirname "$$template") && \ mkdir -p blt/$$dir && \ - case "$$boilerplate" in \ - *--) continue;; \ - esac && \ sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ - -e 's|@PERL_PATH@|$(PERL_PATH_SQ)|g' $$boilerplate > \ - blt/$$dst && \ - if test -x "$$boilerplate"; then rx=rx; else rx=r; fi && \ - chmod a+$$rx "blt/$$dst" || exit; \ + -e 's|@PERL_PATH@|$(PERL_PATH_SQ)|g' $$template > \ + blt/$$template && \ + if test -x "$$template"; then rx=rx; else rx=r; fi && \ + chmod a+$$rx "blt/$$template" || exit; \ done && \ date >$@ diff --git a/templates/branches-- b/templates/branches-- deleted file mode 100644 index fae88709a636f3..00000000000000 --- a/templates/branches-- +++ /dev/null @@ -1 +0,0 @@ -: this is just to ensure the directory exists. diff --git a/templates/this--description b/templates/description similarity index 100% rename from templates/this--description rename to templates/description diff --git a/templates/hooks--applypatch-msg.sample b/templates/hooks/applypatch-msg.sample similarity index 100% rename from templates/hooks--applypatch-msg.sample rename to templates/hooks/applypatch-msg.sample diff --git a/templates/hooks--commit-msg.sample b/templates/hooks/commit-msg.sample similarity index 100% rename from templates/hooks--commit-msg.sample rename to templates/hooks/commit-msg.sample diff --git a/templates/hooks--fsmonitor-watchman.sample b/templates/hooks/fsmonitor-watchman.sample similarity index 100% rename from templates/hooks--fsmonitor-watchman.sample rename to templates/hooks/fsmonitor-watchman.sample diff --git a/templates/hooks/meson.build b/templates/hooks/meson.build new file mode 100644 index 00000000000000..ef85e10a16ccd6 --- /dev/null +++ b/templates/hooks/meson.build @@ -0,0 +1,26 @@ +hooks = [ + 'applypatch-msg.sample', + 'commit-msg.sample', + 'fsmonitor-watchman.sample', + 'post-update.sample', + 'pre-applypatch.sample', + 'pre-commit.sample', + 'pre-merge-commit.sample', + 'prepare-commit-msg.sample', + 'pre-push.sample', + 'pre-rebase.sample', + 'pre-receive.sample', + 'push-to-checkout.sample', + 'sendemail-validate.sample', + 'update.sample', +] + +foreach hook : hooks + configure_file( + input: hook, + output: hook, + configuration: template_config, + install: true, + install_dir: get_option('datadir') / 'git-core/templates/hooks', + ) +endforeach diff --git a/templates/hooks--post-update.sample b/templates/hooks/post-update.sample similarity index 100% rename from templates/hooks--post-update.sample rename to templates/hooks/post-update.sample diff --git a/templates/hooks--pre-applypatch.sample b/templates/hooks/pre-applypatch.sample similarity index 100% rename from templates/hooks--pre-applypatch.sample rename to templates/hooks/pre-applypatch.sample diff --git a/templates/hooks--pre-commit.sample b/templates/hooks/pre-commit.sample similarity index 100% rename from templates/hooks--pre-commit.sample rename to templates/hooks/pre-commit.sample diff --git a/templates/hooks--pre-merge-commit.sample b/templates/hooks/pre-merge-commit.sample similarity index 100% rename from templates/hooks--pre-merge-commit.sample rename to templates/hooks/pre-merge-commit.sample diff --git a/templates/hooks--pre-push.sample b/templates/hooks/pre-push.sample similarity index 100% rename from templates/hooks--pre-push.sample rename to templates/hooks/pre-push.sample diff --git a/templates/hooks--pre-rebase.sample b/templates/hooks/pre-rebase.sample similarity index 100% rename from templates/hooks--pre-rebase.sample rename to templates/hooks/pre-rebase.sample diff --git a/templates/hooks--pre-receive.sample b/templates/hooks/pre-receive.sample similarity index 100% rename from templates/hooks--pre-receive.sample rename to templates/hooks/pre-receive.sample diff --git a/templates/hooks--prepare-commit-msg.sample b/templates/hooks/prepare-commit-msg.sample similarity index 100% rename from templates/hooks--prepare-commit-msg.sample rename to templates/hooks/prepare-commit-msg.sample diff --git a/templates/hooks--push-to-checkout.sample b/templates/hooks/push-to-checkout.sample similarity index 100% rename from templates/hooks--push-to-checkout.sample rename to templates/hooks/push-to-checkout.sample diff --git a/templates/hooks--sendemail-validate.sample b/templates/hooks/sendemail-validate.sample similarity index 100% rename from templates/hooks--sendemail-validate.sample rename to templates/hooks/sendemail-validate.sample diff --git a/templates/hooks--update.sample b/templates/hooks/update.sample similarity index 100% rename from templates/hooks--update.sample rename to templates/hooks/update.sample diff --git a/templates/info--exclude b/templates/info/exclude similarity index 100% rename from templates/info--exclude rename to templates/info/exclude diff --git a/templates/info/meson.build b/templates/info/meson.build new file mode 100644 index 00000000000000..026f2313858c24 --- /dev/null +++ b/templates/info/meson.build @@ -0,0 +1,7 @@ +configure_file( + input: 'exclude', + output: 'exclude', + configuration: template_config, + install: true, + install_dir: get_option('datadir') / 'git-core/templates/info', +) diff --git a/templates/meson.build b/templates/meson.build new file mode 100644 index 00000000000000..1faf9a44ceaa5a --- /dev/null +++ b/templates/meson.build @@ -0,0 +1,15 @@ +template_config = configuration_data() +template_config.set('PERL_PATH', perl.found() ? fs.as_posix(perl.full_path()) : '') +template_config.set('SHELL_PATH', fs.as_posix(shell.full_path())) +template_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb')) + +configure_file( + input: 'description', + output: 'description', + configuration: template_config, + install: true, + install_dir: get_option('datadir') / 'git-core/templates', +) + +subdir('hooks') +subdir('info') diff --git a/tmp-objdir.c b/tmp-objdir.c index c2fb9f91930a30..31d16a4c2c576e 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "tmp-objdir.h" #include "abspath.h" @@ -16,6 +14,7 @@ #include "repository.h" struct tmp_objdir { + struct repository *repo; struct strbuf path; struct strvec env; struct object_directory *prev_odb; @@ -116,7 +115,8 @@ static int setup_tmp_objdir(const char *root) return ret; } -struct tmp_objdir *tmp_objdir_create(const char *prefix) +struct tmp_objdir *tmp_objdir_create(struct repository *r, + const char *prefix) { static int installed_handlers; struct tmp_objdir *t; @@ -125,6 +125,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) BUG("only one tmp_objdir can be used at a time"); t = xcalloc(1, sizeof(*t)); + t->repo = r; strbuf_init(&t->path, 0); strvec_init(&t->env); @@ -134,7 +135,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) * them. */ strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", - repo_get_object_directory(the_repository), prefix); + repo_get_object_directory(r), prefix); if (!mkdtemp(t->path.buf)) { /* free, not destroy, as we never touched the filesystem */ @@ -154,7 +155,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) } env_append(&t->env, ALTERNATE_DB_ENVIRONMENT, - absolute_path(repo_get_object_directory(the_repository))); + absolute_path(repo_get_object_directory(r))); env_replace(&t->env, DB_ENVIRONMENT, absolute_path(t->path.buf)); env_replace(&t->env, GIT_QUARANTINE_ENVIRONMENT, absolute_path(t->path.buf)); @@ -206,9 +207,13 @@ static int read_dir_paths(struct string_list *out, const char *path) return 0; } -static int migrate_paths(struct strbuf *src, struct strbuf *dst); +static int migrate_paths(struct tmp_objdir *t, + struct strbuf *src, struct strbuf *dst, + enum finalize_object_file_flags flags); -static int migrate_one(struct strbuf *src, struct strbuf *dst) +static int migrate_one(struct tmp_objdir *t, + struct strbuf *src, struct strbuf *dst, + enum finalize_object_file_flags flags) { struct stat st; @@ -216,20 +221,26 @@ static int migrate_one(struct strbuf *src, struct strbuf *dst) return -1; if (S_ISDIR(st.st_mode)) { if (!mkdir(dst->buf, 0777)) { - if (adjust_shared_perm(dst->buf)) + if (adjust_shared_perm(t->repo, dst->buf)) return -1; } else if (errno != EEXIST) return -1; - return migrate_paths(src, dst); + return migrate_paths(t, src, dst, flags); } - return finalize_object_file(src->buf, dst->buf); + return finalize_object_file_flags(src->buf, dst->buf, flags); } -static int migrate_paths(struct strbuf *src, struct strbuf *dst) +static int is_loose_object_shard(const char *name) +{ + return strlen(name) == 2 && isxdigit(name[0]) && isxdigit(name[1]); +} + +static int migrate_paths(struct tmp_objdir *t, + struct strbuf *src, struct strbuf *dst, + enum finalize_object_file_flags flags) { size_t src_len = src->len, dst_len = dst->len; struct string_list paths = STRING_LIST_INIT_DUP; - int i; int ret = 0; if (read_dir_paths(&paths, src->buf) < 0) @@ -237,13 +248,17 @@ static int migrate_paths(struct strbuf *src, struct strbuf *dst) paths.cmp = pack_copy_cmp; string_list_sort(&paths); - for (i = 0; i < paths.nr; i++) { + for (size_t i = 0; i < paths.nr; i++) { const char *name = paths.items[i].string; + enum finalize_object_file_flags flags_copy = flags; strbuf_addf(src, "/%s", name); strbuf_addf(dst, "/%s", name); - ret |= migrate_one(src, dst); + if (is_loose_object_shard(name)) + flags_copy |= FOF_SKIP_COLLISION_CHECK; + + ret |= migrate_one(t, src, dst, flags_copy); strbuf_setlen(src, src_len); strbuf_setlen(dst, dst_len); @@ -262,16 +277,16 @@ int tmp_objdir_migrate(struct tmp_objdir *t) return 0; if (t->prev_odb) { - if (the_repository->objects->odb->will_destroy) + if (t->repo->objects->odb->will_destroy) BUG("migrating an ODB that was marked for destruction"); restore_primary_odb(t->prev_odb, t->path.buf); t->prev_odb = NULL; } strbuf_addbuf(&src, &t->path); - strbuf_addstr(&dst, repo_get_object_directory(the_repository)); + strbuf_addstr(&dst, repo_get_object_directory(t->repo)); - ret = migrate_paths(&src, &dst); + ret = migrate_paths(t, &src, &dst, 0); strbuf_release(&src); strbuf_release(&dst); diff --git a/tmp-objdir.h b/tmp-objdir.h index 237d96b66050c8..fceda14979648f 100644 --- a/tmp-objdir.h +++ b/tmp-objdir.h @@ -11,7 +11,7 @@ * Example: * * struct child_process child = CHILD_PROCESS_INIT; - * struct tmp_objdir *t = tmp_objdir_create("incoming"); + * struct tmp_objdir *t = tmp_objdir_create(repo, "incoming"); * strvec_push(&child.args, cmd); * strvec_pushv(&child.env, tmp_objdir_env(t)); * if (!run_command(&child)) && !tmp_objdir_migrate(t)) @@ -21,13 +21,14 @@ * */ +struct repository; struct tmp_objdir; /* * Create a new temporary object directory with the specified prefix; * returns NULL on failure. */ -struct tmp_objdir *tmp_objdir_create(const char *prefix); +struct tmp_objdir *tmp_objdir_create(struct repository *r, const char *prefix); /* * Return a list of environment strings, suitable for use with diff --git a/trace.c b/trace.c index d8c43773ae8b96..9b99460db82a28 100644 --- a/trace.c +++ b/trace.c @@ -21,7 +21,7 @@ * along with this program; if not, see <https://www.gnu.org/licenses/>. */ -#define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -297,7 +297,7 @@ static const char *quote_crnl(const char *path) return new_path.buf; } -void trace_repo_setup(void) +void trace_repo_setup(struct repository *r) { const char *git_work_tree, *prefix = startup_info->prefix; char *cwd; @@ -307,14 +307,14 @@ void trace_repo_setup(void) cwd = xgetcwd(); - if (!(git_work_tree = repo_get_work_tree(the_repository))) + if (!(git_work_tree = repo_get_work_tree(r))) git_work_tree = "(null)"; if (!startup_info->prefix) prefix = "(null)"; - trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(repo_get_git_dir(the_repository))); - trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(repo_get_common_dir(the_repository))); + trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(repo_get_git_dir(r))); + trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(repo_get_common_dir(r))); trace_printf_key(&trace_setup_key, "setup: worktree: %s\n", quote_crnl(git_work_tree)); trace_printf_key(&trace_setup_key, "setup: cwd: %s\n", quote_crnl(cwd)); trace_printf_key(&trace_setup_key, "setup: prefix: %s\n", quote_crnl(prefix)); diff --git a/trace.h b/trace.h index d304d55aa1d706..9152fe9b3e565e 100644 --- a/trace.h +++ b/trace.h @@ -92,7 +92,9 @@ extern struct trace_key trace_default_key; extern struct trace_key trace_perf_key; extern struct trace_key trace_setup_key; -void trace_repo_setup(void); +struct repository; + +void trace_repo_setup(struct repository *r); /** * Checks whether the trace key is enabled. Used to prevent expensive diff --git a/trace2.c b/trace2.c index f894532d05331c..c23c0a227b7032 100644 --- a/trace2.c +++ b/trace2.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "repository.h" @@ -762,7 +764,7 @@ void trace2_def_param_fl(const char *file, int line, const char *param, if (!trace2_enabled) return; - redacted = redact_arg(value); + redacted = value ? redact_arg(value) : NULL; for_each_wanted_builtin (j, tgt_j) if (tgt_j->pfn_param_fl) diff --git a/trace2.h b/trace2.h index 901f39253a6593..e4f23784e4620f 100644 --- a/trace2.h +++ b/trace2.h @@ -31,7 +31,7 @@ * * For more info about: trace2 targets, conventions for public functions and * macros, trace2 target formats and examples on trace2 API usage refer to - * Documentation/technical/api-trace2.txt + * Documentation/technical/api-trace2.adoc * */ diff --git a/trace2/tr2_ctr.c b/trace2/tr2_ctr.c index 036b643578b126..ee17bfa86b401b 100644 --- a/trace2/tr2_ctr.c +++ b/trace2/tr2_ctr.c @@ -4,7 +4,7 @@ #include "trace2/tr2_ctr.h" /* - * A global counter block to aggregrate values from the partial sums + * A global counter block to aggregate values from the partial sums * from each thread. */ static struct tr2_counter_block final_counter_block; /* access under tr2tls_mutex */ diff --git a/trace2/tr2_sid.c b/trace2/tr2_sid.c index 09c4ef0d173787..1c1d27b0eee935 100644 --- a/trace2/tr2_sid.c +++ b/trace2/tr2_sid.c @@ -32,7 +32,7 @@ static void tr2_sid_append_my_sid_component(void) { const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA1]; struct tr2_tbuf tb_now; - git_hash_ctx ctx; + struct git_hash_ctx ctx; pid_t pid = getpid(); unsigned char hash[GIT_MAX_RAWSZ + 1]; char hex[GIT_MAX_HEXSZ + 1]; @@ -46,8 +46,8 @@ static void tr2_sid_append_my_sid_component(void) strbuf_add(&tr2sid_buf, "Localhost", 9); else { algo->init_fn(&ctx); - algo->update_fn(&ctx, hostname, strlen(hostname)); - algo->final_fn(hash, &ctx); + git_hash_update(&ctx, hostname, strlen(hostname)); + git_hash_final(hash, &ctx); hash_to_hex_algop_r(hex, hash, algo); strbuf_addch(&tr2sid_buf, 'H'); strbuf_add(&tr2sid_buf, hex, 8); diff --git a/trace2/tr2_sysenv.c b/trace2/tr2_sysenv.c index 048cdd54383041..4abc218514fdbc 100644 --- a/trace2/tr2_sysenv.c +++ b/trace2/tr2_sysenv.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "dir.h" @@ -5,7 +7,7 @@ /* * Each entry represents a trace2 setting. - * See Documentation/technical/api-trace2.txt + * See Documentation/technical/api-trace2.adoc */ struct tr2_sysenv_entry { const char *env_var_name; diff --git a/trace2/tr2_tgt_event.c b/trace2/tr2_tgt_event.c index 45b0850a5ec5c8..5a0381791f7eb4 100644 --- a/trace2/tr2_tgt_event.c +++ b/trace2/tr2_tgt_event.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "json-writer.h" @@ -491,7 +493,8 @@ static void fn_param_fl(const char *file, int line, const char *param, event_fmt_prepare(event_name, file, line, NULL, &jw); jw_object_string(&jw, "scope", scope_name); jw_object_string(&jw, "param", param); - jw_object_string(&jw, "value", value); + if (value) + jw_object_string(&jw, "value", value); jw_end(&jw); tr2_dst_write_line(&tr2dst_event, &jw.json); diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c index baef48aa6989ce..924736ab36093b 100644 --- a/trace2/tr2_tgt_normal.c +++ b/trace2/tr2_tgt_normal.c @@ -307,8 +307,9 @@ static void fn_param_fl(const char *file, int line, const char *param, enum config_scope scope = kvi->scope; const char *scope_name = config_scope_name(scope); - strbuf_addf(&buf_payload, "def_param scope:%s %s=%s", scope_name, param, - value); + strbuf_addf(&buf_payload, "def_param scope:%s %s", scope_name, param); + if (value) + strbuf_addf(&buf_payload, "=%s", value); normal_io_write_fl(file, line, &buf_payload); strbuf_release(&buf_payload); } diff --git a/trace2/tr2_tgt_perf.c b/trace2/tr2_tgt_perf.c index a6f9a8a193e058..4eb9289f950505 100644 --- a/trace2/tr2_tgt_perf.c +++ b/trace2/tr2_tgt_perf.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "config.h" #include "repository.h" @@ -446,8 +448,9 @@ static void fn_param_fl(const char *file, int line, const char *param, struct strbuf scope_payload = STRBUF_INIT; enum config_scope scope = kvi->scope; const char *scope_name = config_scope_name(scope); - - strbuf_addf(&buf_payload, "%s:%s", param, value); + strbuf_addstr(&buf_payload, param); + if (value) + strbuf_addf(&buf_payload, ":%s", value); strbuf_addf(&scope_payload, "%s:%s", "scope", scope_name); perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c index 4f75392952b6a4..7b023c1bfc65fa 100644 --- a/trace2/tr2_tls.c +++ b/trace2/tr2_tls.c @@ -152,11 +152,19 @@ uint64_t tr2tls_absolute_elapsed(uint64_t us) return us - tr2tls_us_start_process; } +static void tr2tls_key_destructor(void *payload) +{ + struct tr2tls_thread_ctx *ctx = payload; + free((char *)ctx->thread_name); + free(ctx->array_us_start); + free(ctx); +} + void tr2tls_init(void) { tr2tls_start_process_clock(); - pthread_key_create(&tr2tls_key, NULL); + pthread_key_create(&tr2tls_key, tr2tls_key_destructor); init_recursive_mutex(&tr2tls_mutex); tr2tls_thread_main = diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h index 3dfe6557fc4612..3bdbf4d2754b40 100644 --- a/trace2/tr2_tls.h +++ b/trace2/tr2_tls.h @@ -11,7 +11,7 @@ */ /* - * Arbitry limit for thread names for column alignment. + * Arbitrary limit for thread names for column alignment. */ #define TR2_MAX_THREAD_NAME (24) diff --git a/trailer.c b/trailer.c index 682d74505bfbb9..310cf582dc3703 100644 --- a/trailer.c +++ b/trailer.c @@ -13,19 +13,20 @@ * Copyright (c) 2013, 2014 Christian Couder <chriscool@tuxfamily.org> */ -struct trailer_info { +struct trailer_block { /* * True if there is a blank line before the location pointed to by - * trailer_block_start. + * "start". */ int blank_line_before_trailer; /* - * 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()). + * The locations of the start and end positions of the trailer block + * found, as offsets from the beginning of the source text from which + * this trailer block was parsed. If no trailer block is found, these + * are both set to 0. */ - size_t trailer_block_start, trailer_block_end; + size_t start, end; /* * Array of trailers found. @@ -249,7 +250,9 @@ static char *apply_command(struct conf_info *conf, const char *arg) static void apply_item_command(struct trailer_item *in_tok, struct arg_item *arg_tok) { if (arg_tok->conf.command || arg_tok->conf.cmd) { - const char *arg; + char *value_to_free = NULL; + char *arg; + if (arg_tok->value && arg_tok->value[0]) { arg = arg_tok->value; } else { @@ -257,9 +260,13 @@ static void apply_item_command(struct trailer_item *in_tok, struct arg_item *arg arg = xstrdup(in_tok->value); else arg = xstrdup(""); + value_to_free = arg_tok->value; } + arg_tok->value = apply_command(&arg_tok->conf, arg); - free((char *)arg); + + free(value_to_free); + free(arg); } } @@ -515,7 +522,6 @@ static int git_trailer_config(const char *conf_key, const char *value, struct conf_info *conf; char *name = NULL; enum trailer_info_type type; - int i; if (!skip_prefix(conf_key, "trailer.", &trailer_item)) return 0; @@ -525,7 +531,7 @@ static int git_trailer_config(const char *conf_key, const char *value, return 0; variable_name++; - for (i = 0; i < ARRAY_SIZE(trailer_config_items); i++) { + for (size_t i = 0; i < ARRAY_SIZE(trailer_config_items); i++) { if (strcmp(trailer_config_items[i].name, variable_name)) continue; name = xstrndup(trailer_item, variable_name - trailer_item - 1); @@ -975,16 +981,16 @@ static void unfold_value(struct strbuf *val) strbuf_release(&out); } -static struct trailer_info *trailer_info_new(void) +static struct trailer_block *trailer_block_new(void) { - struct trailer_info *info = xcalloc(1, sizeof(*info)); - return info; + struct trailer_block *trailer_block = xcalloc(1, sizeof(*trailer_block)); + return trailer_block; } -static struct trailer_info *trailer_info_get(const struct process_trailer_options *opts, - const char *str) +static struct trailer_block *trailer_block_get(const struct process_trailer_options *opts, + const char *str) { - struct trailer_info *info = trailer_info_new(); + struct trailer_block *trailer_block = trailer_block_new(); size_t end_of_log_message = 0, trailer_block_start = 0; struct strbuf **trailer_lines, **ptr; char **trailer_strings = NULL; @@ -1017,34 +1023,34 @@ static struct trailer_info *trailer_info_get(const struct process_trailer_option } strbuf_list_free(trailer_lines); - info->blank_line_before_trailer = ends_with_blank_line(str, - 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; + trailer_block->blank_line_before_trailer = ends_with_blank_line(str, + trailer_block_start); + trailer_block->start = trailer_block_start; + trailer_block->end = end_of_log_message; + trailer_block->trailers = trailer_strings; + trailer_block->trailer_nr = nr; - return info; + return trailer_block; } /* - * Parse trailers in "str", populating the trailer info and "trailer_objects" + * Parse trailers in "str", populating the trailer_block and "trailer_objects" * linked list structure. */ -struct trailer_info *parse_trailers(const struct process_trailer_options *opts, - const char *str, - struct list_head *trailer_objects) +struct trailer_block *parse_trailers(const struct process_trailer_options *opts, + const char *str, + struct list_head *trailer_objects) { - struct trailer_info *info; + struct trailer_block *trailer_block; struct strbuf tok = STRBUF_INIT; struct strbuf val = STRBUF_INIT; size_t i; - info = trailer_info_get(opts, str); + trailer_block = trailer_block_get(opts, str); - for (i = 0; i < info->trailer_nr; i++) { + for (i = 0; i < trailer_block->trailer_nr; i++) { int separator_pos; - char *trailer = info->trailers[i]; + char *trailer = trailer_block->trailers[i]; if (starts_with(trailer, comment_line_str)) continue; separator_pos = find_separator(trailer, separators); @@ -1065,7 +1071,7 @@ struct trailer_info *parse_trailers(const struct process_trailer_options *opts, } } - return info; + return trailer_block; } void free_trailers(struct list_head *trailers) @@ -1077,34 +1083,36 @@ void free_trailers(struct list_head *trailers) } } -size_t trailer_block_start(struct trailer_info *info) +size_t trailer_block_start(struct trailer_block *trailer_block) { - return info->trailer_block_start; + return trailer_block->start; } -size_t trailer_block_end(struct trailer_info *info) +size_t trailer_block_end(struct trailer_block *trailer_block) { - return info->trailer_block_end; + return trailer_block->end; } -int blank_line_before_trailer_block(struct trailer_info *info) +int blank_line_before_trailer_block(struct trailer_block *trailer_block) { - return info->blank_line_before_trailer; + return trailer_block->blank_line_before_trailer; } -void trailer_info_release(struct trailer_info *info) +void trailer_block_release(struct trailer_block *trailer_block) { size_t i; - for (i = 0; i < info->trailer_nr; i++) - free(info->trailers[i]); - free(info->trailers); - free(info); + for (i = 0; i < trailer_block->trailer_nr; i++) + free(trailer_block->trailers[i]); + free(trailer_block->trailers); + free(trailer_block); } void format_trailers(const struct process_trailer_options *opts, struct list_head *trailers, struct strbuf *out) { + struct strbuf tok = STRBUF_INIT; + struct strbuf val = STRBUF_INIT; size_t origlen = out->len; struct list_head *pos; struct trailer_item *item; @@ -1112,9 +1120,9 @@ void format_trailers(const struct process_trailer_options *opts, list_for_each(pos, trailers) { item = list_entry(pos, struct trailer_item, list); if (item->token) { - struct strbuf tok = STRBUF_INIT; - struct strbuf val = STRBUF_INIT; + strbuf_reset(&tok); strbuf_addstr(&tok, item->token); + strbuf_reset(&val); strbuf_addstr(&val, item->value); /* @@ -1145,9 +1153,6 @@ void format_trailers(const struct process_trailer_options *opts, if (!opts->separator) strbuf_addch(out, '\n'); } - strbuf_release(&tok); - strbuf_release(&val); - } else if (!opts->only_trailers) { if (opts->separator && out->len != origlen) { strbuf_addbuf(out, opts->separator); @@ -1159,6 +1164,9 @@ void format_trailers(const struct process_trailer_options *opts, strbuf_addch(out, '\n'); } } + + strbuf_release(&tok); + strbuf_release(&val); } void format_trailers_from_commit(const struct process_trailer_options *opts, @@ -1166,19 +1174,19 @@ void format_trailers_from_commit(const struct process_trailer_options *opts, struct strbuf *out) { LIST_HEAD(trailer_objects); - struct trailer_info *info = parse_trailers(opts, msg, &trailer_objects); + struct trailer_block *trailer_block = parse_trailers(opts, msg, &trailer_objects); /* If we want the whole block untouched, we can take the fast path. */ if (!opts->only_trailers && !opts->unfold && !opts->filter && !opts->separator && !opts->key_only && !opts->value_only && !opts->key_value_separator) { - strbuf_add(out, msg + info->trailer_block_start, - info->trailer_block_end - info->trailer_block_start); + strbuf_add(out, msg + trailer_block->start, + trailer_block->end - trailer_block->start); } else format_trailers(opts, &trailer_objects, out); free_trailers(&trailer_objects); - trailer_info_release(info); + trailer_block_release(trailer_block); } void trailer_iterator_init(struct trailer_iterator *iter, const char *msg) @@ -1187,14 +1195,14 @@ void trailer_iterator_init(struct trailer_iterator *iter, const char *msg) strbuf_init(&iter->key, 0); strbuf_init(&iter->val, 0); opts.no_divider = 1; - iter->internal.info = trailer_info_get(&opts, msg); + iter->internal.trailer_block = trailer_block_get(&opts, msg); iter->internal.cur = 0; } int trailer_iterator_advance(struct trailer_iterator *iter) { - if (iter->internal.cur < iter->internal.info->trailer_nr) { - char *line = iter->internal.info->trailers[iter->internal.cur++]; + if (iter->internal.cur < iter->internal.trailer_block->trailer_nr) { + char *line = iter->internal.trailer_block->trailers[iter->internal.cur++]; int separator_pos = find_separator(line, separators); iter->raw = line; @@ -1211,7 +1219,7 @@ int trailer_iterator_advance(struct trailer_iterator *iter) void trailer_iterator_release(struct trailer_iterator *iter) { - trailer_info_release(iter->internal.info); + trailer_block_release(iter->internal.trailer_block); strbuf_release(&iter->val); strbuf_release(&iter->key); } diff --git a/trailer.h b/trailer.h index 6eb53df155eb45..4740549586a8e5 100644 --- a/trailer.h +++ b/trailer.h @@ -4,7 +4,7 @@ #include "list.h" #include "strbuf.h" -struct trailer_info; +struct trailer_block; struct strvec; enum trailer_where { @@ -72,12 +72,12 @@ void process_trailers_lists(struct list_head *head, struct list_head *arg_head); /* - * Given some input string "str", return a pointer to an opaque trailer_info + * Given some input string "str", return a pointer to an opaque trailer_block * structure. Also populate the trailer_objects list with parsed trailer * objects. Internally this calls trailer_info_get() to get the opaque pointer, * but does some extra work to populate the trailer_objects linked list. * - * The opaque trailer_info pointer can be used to check the position of the + * The opaque trailer_block pointer can be used to check the position of the * trailer block as offsets relative to the beginning of "str" in * trailer_block_start() and trailer_block_end(). * blank_line_before_trailer_block() returns 1 if there is a blank line just @@ -89,21 +89,21 @@ void process_trailers_lists(struct list_head *head, * For iterating through the parsed trailer block (if you don't care about the * position of the trailer block itself in the context of the larger string text * from which it was parsed), please see trailer_iterator_init() which uses the - * trailer_info struct internally. + * trailer_block struct internally. * * Lastly, callers should call trailer_info_release() when they are done using * the opaque pointer. * - * NOTE: Callers should treat both trailer_info and trailer_objects as - * read-only items, because there is some overlap between the two (trailer_info + * NOTE: Callers should treat both trailer_block and trailer_objects as + * read-only items, because there is some overlap between the two (trailer_block * has "char **trailers" string array, and trailer_objects will have the same * data but as a linked list of trailer_item objects). This API does not perform * any synchronization between the two. In the future we should be able to * reduce the duplication and use just the linked list. */ -struct trailer_info *parse_trailers(const struct process_trailer_options *, - const char *str, - struct list_head *trailer_objects); +struct trailer_block *parse_trailers(const struct process_trailer_options *, + const char *str, + struct list_head *trailer_objects); /* * Return the offset of the start of the trailer block. That is, 0 is the start @@ -111,24 +111,24 @@ struct trailer_info *parse_trailers(const struct process_trailer_options *, * indicates how many bytes we have to skip over before we get to the beginning * of the trailer block. */ -size_t trailer_block_start(struct trailer_info *); +size_t trailer_block_start(struct trailer_block *); /* * Return the end of the trailer block, again relative to the start of the * input. */ -size_t trailer_block_end(struct trailer_info *); +size_t trailer_block_end(struct trailer_block *); /* * Return 1 if the trailer block had an extra newline (blank line) just before * it. */ -int blank_line_before_trailer_block(struct trailer_info *); +int blank_line_before_trailer_block(struct trailer_block *); /* - * Free trailer_info struct. + * Free trailer_block struct. */ -void trailer_info_release(struct trailer_info *info); +void trailer_block_release(struct trailer_block *); void trailer_config_init(void); void format_trailers(const struct process_trailer_options *, @@ -167,7 +167,7 @@ struct trailer_iterator { /* private */ struct { - struct trailer_info *info; + struct trailer_block *trailer_block; size_t cur; } internal; }; diff --git a/transport-helper.c b/transport-helper.c index c688967b8c817f..d457b425501a74 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -313,9 +313,9 @@ static int string_list_set_helper_option(struct helper_data *data, struct string_list *list) { struct strbuf buf = STRBUF_INIT; - int i, ret = 0; + int ret = 0; - for (i = 0; i < list->nr; i++) { + for (size_t i = 0; i < list->nr; i++) { strbuf_addf(&buf, "option %s ", name); quote_c_style(list->items[i].string, &buf, NULL, 0); strbuf_addch(&buf, '\n'); @@ -333,7 +333,7 @@ static int set_helper_option(struct transport *transport, { struct helper_data *data = transport->data; struct strbuf buf = STRBUF_INIT; - int i, ret, is_bool = 0; + int ret, is_bool = 0; get_helper(transport); @@ -344,12 +344,12 @@ static int set_helper_option(struct transport *transport, return string_list_set_helper_option(data, name, (struct string_list *)value); - for (i = 0; i < ARRAY_SIZE(unsupported_options); i++) { + for (size_t i = 0; i < ARRAY_SIZE(unsupported_options); i++) { if (!strcmp(name, unsupported_options[i])) return 1; } - for (i = 0; i < ARRAY_SIZE(boolean_options); i++) { + for (size_t i = 0; i < ARRAY_SIZE(boolean_options); i++) { if (!strcmp(name, boolean_options[i])) { is_bool = 1; break; @@ -399,6 +399,8 @@ static int release_helper(struct transport *transport) int res = 0; struct helper_data *data = transport->data; refspec_clear(&data->rs); + free(data->import_marks); + free(data->export_marks); res = disconnect_helper(transport); free(transport->data); return res; @@ -479,7 +481,6 @@ static int get_exporter(struct transport *transport, { struct helper_data *data = transport->data; struct child_process *helper = get_helper(transport); - int i; child_process_init(fastexport); @@ -495,7 +496,7 @@ static int get_exporter(struct transport *transport, if (data->import_marks) strvec_pushf(&fastexport->args, "--import-marks=%s", data->import_marks); - for (i = 0; i < revlist_args->nr; i++) + for (size_t i = 0; i < revlist_args->nr; i++) strvec_push(&fastexport->args, revlist_args->items[i].string); fastexport->git_cmd = 1; @@ -717,8 +718,14 @@ static int fetch_refs(struct transport *transport, return -1; } - if (!data->get_refs_list_called) - get_refs_list_using_list(transport, 0); + if (!data->get_refs_list_called) { + /* + * We do not care about the list of refs returned, but only + * that the "list" command was sent. + */ + struct ref *dummy = get_refs_list_using_list(transport, 0); + free_refs(dummy); + } count = 0; for (i = 0; i < nr_heads; i++) @@ -1023,6 +1030,7 @@ static int push_refs_with_push(struct transport *transport, if (atomic) { reject_atomic_push(remote_refs, mirror); string_list_clear(&cas_options, 0); + strbuf_release(&buf); return 0; } else continue; diff --git a/transport.c b/transport.c index 3c4714581f58eb..6c2801bcbd9d02 100644 --- a/transport.c +++ b/transport.c @@ -19,6 +19,7 @@ #include "branch.h" #include "url.h" #include "submodule.h" +#include "strbuf.h" #include "string-list.h" #include "oid-array.h" #include "sigchain.h" @@ -47,7 +48,6 @@ static int transport_color_config(void) "color.transport.rejected" }, *key = "color.transport"; char *value; - int i; static int initialized; if (initialized) @@ -60,7 +60,7 @@ static int transport_color_config(void) if (!want_color_stderr(transport_use_color)) return 0; - for (i = 0; i < ARRAY_SIZE(keys); i++) + for (size_t i = 0; i < ARRAY_SIZE(keys); i++) if (!git_config_get_string(keys[i], &value)) { if (!value) return config_error_nonbool(keys[i]); @@ -153,14 +153,13 @@ static struct ref *get_refs_from_bundle(struct transport *transport, { struct bundle_transport_data *data = transport->data; struct ref *result = NULL; - int i; if (for_push) return NULL; get_refs_from_bundle_inner(transport); - for (i = 0; i < data->header.references.nr; i++) { + for (size_t i = 0; i < data->header.references.nr; i++) { struct string_list_item *e = data->header.references.items + i; const char *name = e->string; struct ref *ref = alloc_ref(name); @@ -172,12 +171,29 @@ static struct ref *get_refs_from_bundle(struct transport *transport, return result; } +static int fetch_fsck_config_cb(const char *var, const char *value, + const struct config_context *ctx UNUSED, void *cb) +{ + struct strbuf *msg_types = cb; + int ret; + + ret = fetch_pack_fsck_config(var, value, msg_types); + if (ret > 0) + return 0; + + return ret; +} + static int fetch_refs_from_bundle(struct transport *transport, int nr_heads UNUSED, struct ref **to_fetch UNUSED) { + struct unbundle_opts opts = { + .flags = fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0, + }; struct bundle_transport_data *data = transport->data; struct strvec extra_index_pack_args = STRVEC_INIT; + struct strbuf msg_types = STRBUF_INIT; int ret; if (transport->progress) @@ -185,12 +201,17 @@ static int fetch_refs_from_bundle(struct transport *transport, if (!data->get_refs_from_bundle_called) get_refs_from_bundle_inner(transport); + + git_config(fetch_fsck_config_cb, &msg_types); + opts.fsck_msg_types = msg_types.buf; + ret = unbundle(the_repository, &data->header, data->fd, - &extra_index_pack_args, - fetch_pack_fsck_objects() ? VERIFY_BUNDLE_FSCK : 0); + &extra_index_pack_args, &opts); + data->fd = -1; /* `unbundle()` closes the file descriptor */ transport->hash_algo = data->header.hash_algo; strvec_clear(&extra_index_pack_args); + strbuf_release(&msg_types); return ret; } @@ -334,6 +355,9 @@ static struct ref *handshake(struct transport *transport, int for_push, data->version = discover_version(&reader); switch (data->version) { case protocol_v2: + if ((!transport->server_options || !transport->server_options->nr) && + transport->remote->server_options.nr) + transport->server_options = &transport->remote->server_options; if (server_feature_v2("session-id", &server_sid)) trace2_data_string("transfer", NULL, "server-sid", server_sid); if (must_list_refs) @@ -414,7 +438,7 @@ static int fetch_refs_via_pack(struct transport *transport, struct git_transport_data *data = transport->data; struct ref *refs = NULL; struct fetch_pack_args args; - struct ref *refs_tmp = NULL; + struct ref *refs_tmp = NULL, **to_fetch_dup = NULL; memset(&args, 0, sizeof(args)); args.uploadpack = data->options.uploadpack; @@ -477,6 +501,14 @@ static int fetch_refs_via_pack(struct transport *transport, goto cleanup; } + /* + * Create a shallow copy of `sought` so that we can free all of its entries. + * This is because `fetch_pack()` will modify the array to evict some + * entries, but won't free those. + */ + DUP_ARRAY(to_fetch_dup, to_fetch, nr_heads); + to_fetch = to_fetch_dup; + refs = fetch_pack(&args, data->fd, refs_tmp ? refs_tmp : transport->remote_refs, to_fetch, nr_heads, &data->shallow, @@ -500,6 +532,7 @@ static int fetch_refs_via_pack(struct transport *transport, ret = -1; data->conn = NULL; + free(to_fetch_dup); free_refs(refs_tmp); free_refs(refs); list_objects_filter_release(&args.filter_options); @@ -900,8 +933,15 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re break; case protocol_v1: case protocol_v0: - ret = send_pack(&args, data->fd, data->conn, remote_refs, + ret = send_pack(the_repository, &args, data->fd, data->conn, remote_refs, &data->extra_have); + /* + * Ignore the specific error code to maintain consistent behavior + * with the "push_refs()" function across different transports, + * such as "push_refs_with_push()" for HTTP protocol. + */ + if (ret == ERROR_SEND_PACK_BAD_REF_STATUS) + ret = 0; break; case protocol_unknown_version: BUG("unknown protocol version"); @@ -909,15 +949,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re close(data->fd[1]); close(data->fd[0]); - /* - * Atomic push may abort the connection early and close the pipe, - * which may cause an error for `finish_connect()`. Ignore this error - * for atomic git-push. - */ - if (ret || args.atomic) - finish_connect(data->conn); - else - ret = finish_connect(data->conn); + ret |= finish_connect(data->conn); data->conn = NULL; data->finished_handshake = 0; @@ -1099,6 +1131,18 @@ int is_transport_allowed(const char *type, int from_user) BUG("invalid protocol_allow_config type"); } +int parse_transport_option(const char *var, const char *value, + struct string_list *transport_options) +{ + if (!value) + return config_error_nonbool(var); + if (!*value) + string_list_clear(transport_options, 0); + else + string_list_append(transport_options, value); + return 0; +} + void transport_check_allowed(const char *type) { if (!is_transport_allowed(type, -1)) @@ -1257,11 +1301,9 @@ void transport_set_verbosity(struct transport *transport, int verbosity, static void die_with_unpushed_submodules(struct string_list *needs_pushing) { - int i; - fprintf(stderr, _("The following submodule paths contain changes that can\n" "not be found on any remote:\n")); - for (i = 0; i < needs_pushing->nr; i++) + for (size_t i = 0; i < needs_pushing->nr; i++) fprintf(stderr, " %s\n", needs_pushing->items[i].string); fprintf(stderr, _("\nPlease try\n\n" " git push --recurse-submodules=on-demand\n\n" @@ -1577,9 +1619,8 @@ int transport_get_remote_bundle_uri(struct transport *transport) void transport_unlock_pack(struct transport *transport, unsigned int flags) { int in_signal_handler = !!(flags & TRANSPORT_UNLOCK_PACK_IN_SIGNAL_HANDLER); - int i; - for (i = 0; i < transport->pack_lockfiles.nr; i++) + for (size_t i = 0; i < transport->pack_lockfiles.nr; i++) if (in_signal_handler) unlink(transport->pack_lockfiles.items[i].string); else diff --git a/transport.h b/transport.h index 6393cd9823c01f..892f19454a75d6 100644 --- a/transport.h +++ b/transport.h @@ -168,7 +168,7 @@ struct transport *transport_get(struct remote *, const char *); * Check whether a transport is allowed by the environment. * * Type should generally be the URL scheme, as described in - * Documentation/git.txt + * Documentation/git.adoc * * from_user specifies if the transport was given by the user. If unknown pass * a -1 to read from the environment to determine if the transport was given by @@ -342,4 +342,8 @@ void transport_print_push_status(const char *dest, struct ref *refs, /* common method used by transport-helper.c and send-pack.c */ void reject_atomic_push(struct ref *refs, int mirror_mode); +/* common method to parse push-option or server-option from config */ +int parse_transport_option(const char *var, const char *value, + struct string_list *transport_options); + #endif diff --git a/tree-diff.c b/tree-diff.c index 5eab8af631b789..60c558c2b56373 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -3,6 +3,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "diff.h" @@ -47,8 +48,8 @@ free((x)); \ } while(0) -static struct combine_diff_path *ll_diff_tree_paths( - struct combine_diff_path *p, const struct object_id *oid, +static void ll_diff_tree_paths( + struct combine_diff_path ***tail, const struct object_id *oid, const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt, int depth); @@ -123,72 +124,6 @@ static int emit_diff_first_parent_only(struct diff_options *opt, struct combine_ } -/* - * Make a new combine_diff_path from path/mode/sha1 - * and append it to paths list tail. - * - * Memory for created elements could be reused: - * - * - if last->next == NULL, the memory is allocated; - * - * - if last->next != NULL, it is assumed that p=last->next was returned - * earlier by this function, and p->next was *not* modified. - * The memory is then reused from p. - * - * so for clients, - * - * - if you do need to keep the element - * - * p = path_appendnew(p, ...); - * process(p); - * p->next = NULL; - * - * - if you don't need to keep the element after processing - * - * pprev = p; - * p = path_appendnew(p, ...); - * process(p); - * p = pprev; - * ; don't forget to free tail->next in the end - * - * p->parent[] remains uninitialized. - */ -static struct combine_diff_path *path_appendnew(struct combine_diff_path *last, - int nparent, const struct strbuf *base, const char *path, int pathlen, - unsigned mode, const struct object_id *oid) -{ - struct combine_diff_path *p; - size_t len = st_add(base->len, pathlen); - size_t alloclen = combine_diff_path_size(nparent, len); - - /* if last->next is !NULL - it is a pre-allocated memory, we can reuse */ - p = last->next; - if (p && (alloclen > (intptr_t)p->next)) { - FREE_AND_NULL(p); - } - - if (!p) { - p = xmalloc(alloclen); - - /* - * until we go to it next round, .next holds how many bytes we - * allocated (for faster realloc - we don't need copying old data). - */ - p->next = (struct combine_diff_path *)(intptr_t)alloclen; - } - - last->next = p; - - p->path = (char *)&(p->parent[nparent]); - memcpy(p->path, base->buf, base->len); - memcpy(p->path + base->len, path, pathlen); - p->path[len] = 0; - p->mode = mode; - oidcpy(&p->oid, oid ? oid : null_oid()); - - return p; -} - /* * new path should be added to combine diff * @@ -199,10 +134,10 @@ static struct combine_diff_path *path_appendnew(struct combine_diff_path *last, * t, tp -> path modified/added * (M for tp[i]=tp[imin], A otherwise) */ -static struct combine_diff_path *emit_path(struct combine_diff_path *p, - struct strbuf *base, struct diff_options *opt, int nparent, - struct tree_desc *t, struct tree_desc *tp, - int imin, int depth) +static void emit_path(struct combine_diff_path ***tail, + struct strbuf *base, struct diff_options *opt, + int nparent, struct tree_desc *t, struct tree_desc *tp, + int imin, int depth) { unsigned short mode; const char *path; @@ -242,8 +177,13 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, if (emitthis) { int keep; - struct combine_diff_path *pprev = p; - p = path_appendnew(p, nparent, base, path, pathlen, mode, oid); + struct combine_diff_path *p; + + strbuf_add(base, path, pathlen); + p = combine_diff_path_new(base->buf, base->len, mode, + oid ? oid : null_oid(), + nparent); + strbuf_setlen(base, old_baselen); for (i = 0; i < nparent; ++i) { /* @@ -278,21 +218,12 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, if (opt->pathchange) keep = opt->pathchange(opt, p); - /* - * If a path was filtered or consumed - we don't need to add it - * to the list and can reuse its memory, leaving it as - * pre-allocated element on the tail. - * - * On the other hand, if path needs to be kept, we need to - * correct its .next to NULL, as it was pre-initialized to how - * much memory was allocated. - * - * see path_appendnew() for details. - */ - if (!keep) - p = pprev; - else - p->next = NULL; + if (keep) { + **tail = p; + *tail = &p->next; + } else { + free(p); + } } if (recurse) { @@ -308,13 +239,12 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, strbuf_add(base, path, pathlen); strbuf_addch(base, '/'); - p = ll_diff_tree_paths(p, oid, parents_oid, nparent, base, opt, - depth + 1); + ll_diff_tree_paths(tail, oid, parents_oid, nparent, base, opt, + depth + 1); FAST_ARRAY_FREE(parents_oid, nparent); } strbuf_setlen(base, old_baselen); - return p; } static void skip_uninteresting(struct tree_desc *t, struct strbuf *base, @@ -427,8 +357,8 @@ static inline void update_tp_entries(struct tree_desc *tp, int nparent) update_tree_entry(&tp[i]); } -static struct combine_diff_path *ll_diff_tree_paths( - struct combine_diff_path *p, const struct object_id *oid, +static void ll_diff_tree_paths( + struct combine_diff_path ***tail, const struct object_id *oid, const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt, int depth) @@ -532,8 +462,8 @@ static struct combine_diff_path *ll_diff_tree_paths( } /* D += {δ(t,pi) if pi=p[imin]; "+a" if pi > p[imin]} */ - p = emit_path(p, base, opt, nparent, - &t, tp, imin, depth); + emit_path(tail, base, opt, nparent, + &t, tp, imin, depth); skip_emit_t_tp: /* t↓, ∀ pi=p[imin] pi↓ */ @@ -544,8 +474,8 @@ static struct combine_diff_path *ll_diff_tree_paths( /* t < p[imin] */ else if (cmp < 0) { /* D += "+t" */ - p = emit_path(p, base, opt, nparent, - &t, /*tp=*/NULL, -1, depth); + emit_path(tail, base, opt, nparent, + &t, /*tp=*/NULL, -1, depth); /* t↓ */ update_tree_entry(&t); @@ -560,8 +490,8 @@ static struct combine_diff_path *ll_diff_tree_paths( goto skip_emit_tp; } - p = emit_path(p, base, opt, nparent, - /*t=*/NULL, tp, imin, depth); + emit_path(tail, base, opt, nparent, + /*t=*/NULL, tp, imin, depth); skip_emit_tp: /* ∀ pi=p[imin] pi↓ */ @@ -574,24 +504,16 @@ static struct combine_diff_path *ll_diff_tree_paths( free(tptree[i]); FAST_ARRAY_FREE(tptree, nparent); FAST_ARRAY_FREE(tp, nparent); - - return p; } struct combine_diff_path *diff_tree_paths( - struct combine_diff_path *p, const struct object_id *oid, + const struct object_id *oid, const struct object_id **parents_oid, int nparent, struct strbuf *base, struct diff_options *opt) { - p = ll_diff_tree_paths(p, oid, parents_oid, nparent, base, opt, 0); - - /* - * free pre-allocated last element, if any - * (see path_appendnew() for details about why) - */ - FREE_AND_NULL(p->next); - - return p; + struct combine_diff_path *head = NULL, **tail = &head; + ll_diff_tree_paths(&tail, oid, parents_oid, nparent, base, opt, 0); + return head; } /* @@ -707,14 +629,13 @@ static void ll_diff_tree_oid(const struct object_id *old_oid, const struct object_id *new_oid, struct strbuf *base, struct diff_options *opt) { - struct combine_diff_path phead, *p; + struct combine_diff_path *paths, *p; pathchange_fn_t pathchange_old = opt->pathchange; - phead.next = NULL; opt->pathchange = emit_diff_first_parent_only; - diff_tree_paths(&phead, new_oid, &old_oid, 1, base, opt); + paths = diff_tree_paths(new_oid, &old_oid, 1, base, opt); - for (p = phead.next; p;) { + for (p = paths; p;) { struct combine_diff_path *pprev = p; p = p->next; free(pprev); diff --git a/unimplemented.sh b/unimplemented.sh index fee21d24e8ab89..41776b279d4263 100644 --- a/unimplemented.sh +++ b/unimplemented.sh @@ -1,4 +1,4 @@ #!/bin/sh -echo >&2 "fatal: git was built without support for $(basename $0) (@@REASON@@)." +echo >&2 "fatal: git was built without support for $(basename $0) (@REASON@)." exit 128 diff --git a/unix-socket.c b/unix-socket.c index 79800d80636fc5..8860203c3f46dc 100644 --- a/unix-socket.c +++ b/unix-socket.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "strbuf.h" #include "unix-socket.h" @@ -63,8 +65,10 @@ static int unix_sockaddr_init(struct sockaddr_un *sa, const char *path, if (strbuf_getcwd(&cwd)) return -1; ctx->orig_dir = strbuf_detach(&cwd, NULL); - if (chdir_len(dir, slash - dir) < 0) + if (chdir_len(dir, slash - dir) < 0) { + FREE_AND_NULL(ctx->orig_dir); return -1; + } } memset(sa, 0, sizeof(*sa)); diff --git a/unpack-trees.c b/unpack-trees.c index 9a55cb62040c9c..cf5b73c84be2ff 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "advice.h" @@ -371,7 +372,8 @@ static struct progress *get_progress(struct unpack_trees_options *o, total++; } - return start_delayed_progress(_("Updating files"), total); + return start_delayed_progress(the_repository, + _("Updating files"), total); } static void setup_collided_checkout_detection(struct checkout *state, @@ -808,6 +810,8 @@ static int traverse_by_cache_tree(int pos, int nr_entries, int nr_names, if (!o->merge) BUG("We need cache-tree to do this optimization"); + if (nr_entries + pos > o->src_index->cache_nr) + return error(_("corrupted cache-tree has entries not present in index")); /* * Do what unpack_callback() and unpack_single_entry() normally @@ -1770,6 +1774,7 @@ static int clear_ce_flags(struct index_state *istate, strbuf_reset(&prefix); if (show_progress) istate->progress = start_delayed_progress( + the_repository, _("Updating index flags"), istate->cache_nr); @@ -2070,9 +2075,13 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options if (o->dst_index) { move_index_extensions(&o->internal.result, o->src_index); if (!ret) { - if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0)) - cache_tree_verify(the_repository, - &o->internal.result); + if (git_env_bool("GIT_TEST_CHECK_CACHE_TREE", 0) && + cache_tree_verify(the_repository, + &o->internal.result) < 0) { + ret = -1; + goto done; + } + if (!o->skip_cache_tree_update && !cache_tree_fully_valid(o->internal.result.cache_tree)) cache_tree_update(&o->internal.result, @@ -2895,7 +2904,7 @@ int threeway_merge(const struct cache_entry * const *stages, * The rule is to "carry forward" what is in the index without losing * information across a "fast-forward", favoring a successful merge * over a merge failure when it makes sense. For details of the - * "carry forward" rule, please see <Documentation/git-read-tree.txt>. + * "carry forward" rule, please see <Documentation/git-read-tree.adoc>. * */ int twoway_merge(const struct cache_entry * const *src, diff --git a/upload-pack.c b/upload-pack.c index 6d6e0f9f9800f9..7498b45e2e1e21 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" @@ -31,6 +32,7 @@ #include "write-or-die.h" #include "json-writer.h" #include "strmap.h" +#include "promisor-remote.h" /* Remember to update object flag allocation in object.h */ #define THEY_HAVE (1u << 11) @@ -166,6 +168,7 @@ static void upload_pack_data_clear(struct upload_pack_data *data) object_array_clear(&data->extra_edge_obj); list_objects_filter_release(&data->filter_options); string_list_clear(&data->allowed_filters, 0); + string_list_clear(&data->uri_protocols, 0); free((char *)data->pack_objects_hook); } @@ -317,6 +320,8 @@ static void create_pack_file(struct upload_pack_data *pack_data, strvec_push(&pack_objects.args, "--delta-base-offset"); if (pack_data->use_include_tag) strvec_push(&pack_objects.args, "--include-tag"); + if (repo_has_accepted_promisor_remote(the_repository)) + strvec_push(&pack_objects.args, "--missing=allow-promisor"); if (pack_data->filter_options.choice) { const char *spec = expand_list_objects_filter_spec(&pack_data->filter_options); @@ -1025,10 +1030,14 @@ static int process_deepen_not(const char *line, struct oidset *deepen_not, int * { const char *arg; if (skip_prefix(line, "deepen-not ", &arg)) { + int cnt; char *ref = NULL; struct object_id oid; - if (expand_ref(the_repository, arg, strlen(arg), &oid, &ref) != 1) + cnt = expand_ref(the_repository, arg, strlen(arg), &oid, &ref); + if (cnt > 1) die("git upload-pack: ambiguous deepen-not: %s", line); + if (cnt < 1) + die("git upload-pack: deepen-not is not a ref: %s", line); oidset_insert(deepen_not, &oid); free(ref); *deepen_rev_list = 1; diff --git a/urlmatch.c b/urlmatch.c index 1d0254abacbc3f..eea8300489d79b 100644 --- a/urlmatch.c +++ b/urlmatch.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "gettext.h" #include "hex-ll.h" diff --git a/usage.c b/usage.c index 7a2f7805f57737..38b46bbbfe7208 100644 --- a/usage.c +++ b/usage.c @@ -3,11 +3,12 @@ * * Copyright (C) Linus Torvalds, 2005 */ + #include "git-compat-util.h" #include "gettext.h" #include "trace2.h" -static void vreportf(const char *prefix, const char *err, va_list params) +static void vfreportf(FILE *f, const char *prefix, const char *err, va_list params) { char msg[4096]; char *p, *pend = msg + sizeof(msg); @@ -31,8 +32,13 @@ static void vreportf(const char *prefix, const char *err, va_list params) } *(p++) = '\n'; /* we no longer need a NUL */ - fflush(stderr); - write_in_full(2, msg, p - msg); + fflush(f); + write_in_full(fileno(f), msg, p - msg); +} + +static void vreportf(const char *prefix, const char *err, va_list params) +{ + vfreportf(stderr, prefix, err, params); } static NORETURN void usage_builtin(const char *err, va_list params) @@ -172,6 +178,22 @@ void NORETURN usage(const char *err) usagef("%s", err); } +static void show_usage_if_asked_helper(const char *err, ...) +{ + va_list params; + + va_start(params, err); + vfreportf(stdout, _("usage: "), err, params); + va_end(params); + exit(129); +} + +void show_usage_if_asked(int ac, const char **av, const char *err) +{ + if (ac == 2 && !strcmp(av[1], "-h")) + show_usage_if_asked_helper(err); +} + void NORETURN die(const char *err, ...) { va_list params; @@ -189,7 +211,7 @@ void NORETURN die(const char *err, ...) static const char *fmt_with_err(char *buf, int n, const char *fmt) { char str_error[256], *err; - int i, j; + size_t i, j; err = strerror(errno); for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) { @@ -350,18 +372,3 @@ void bug_fl(const char *file, int line, const char *fmt, ...) trace2_cmd_error_va(fmt, ap); va_end(ap); } - -#ifdef SUPPRESS_ANNOTATED_LEAKS -void unleak_memory(const void *ptr, size_t len) -{ - static struct suppressed_leak_root { - struct suppressed_leak_root *next; - char data[FLEX_ARRAY]; - } *suppressed_leaks; - struct suppressed_leak_root *root; - - FLEX_ALLOC_MEM(root, data, ptr, len); - root->next = suppressed_leaks; - suppressed_leaks = root; -} -#endif diff --git a/userdiff.c b/userdiff.c index d43d8360d17227..340c4eb4f77ab1 100644 --- a/userdiff.c +++ b/userdiff.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" diff --git a/utf8.c b/utf8.c index 6bfaefa28ebbbf..35a02519392e65 100644 --- a/utf8.c +++ b/utf8.c @@ -1,3 +1,5 @@ +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "strbuf.h" #include "utf8.h" diff --git a/utf8.h b/utf8.h index 35df76086a6c91..cf8ecb0f21a6da 100644 --- a/utf8.h +++ b/utf8.h @@ -33,8 +33,9 @@ char *reencode_string_len(const char *in, size_t insz, const char *in_encoding, size_t *outsz); #else -static inline char *reencode_string_len(const char *a, size_t b, - const char *c, const char *d, size_t *e) +static inline char *reencode_string_len(const char *a UNUSED, size_t b UNUSED, + const char *c UNUSED, + const char *d UNUSED, size_t *e) { if (e) *e = 0; return NULL; } #endif diff --git a/version-def.h.in b/version-def.h.in new file mode 100644 index 00000000000000..347995df0611e1 --- /dev/null +++ b/version-def.h.in @@ -0,0 +1,8 @@ +#ifndef VERSION_DEF_H +#define VERSION_DEF_H + +#define GIT_VERSION "@GIT_VERSION@" +#define GIT_BUILT_FROM_COMMIT "@GIT_BUILT_FROM_COMMIT@" +#define GIT_USER_AGENT "@GIT_USER_AGENT@" + +#endif /* VERSION_DEF_H */ diff --git a/version.c b/version.c index 41b718c29e1b9f..279269cc50fe72 100644 --- a/version.c +++ b/version.c @@ -1,10 +1,32 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "version.h" #include "strbuf.h" +#include "gettext.h" + +#ifndef GIT_VERSION_H +# include "version-def.h" +#else +# include GIT_VERSION_H +#endif const char git_version_string[] = GIT_VERSION; const char git_built_from_commit_string[] = GIT_BUILT_FROM_COMMIT; +/* + * Trim and replace each character with ascii code below 32 or above + * 127 (included) using a dot '.' character. + */ +static void redact_non_printables(struct strbuf *buf) +{ + strbuf_trim(buf); + for (size_t i = 0; i < buf->len; i++) { + if (!isprint(buf->buf[i]) || buf->buf[i] == ' ') + buf->buf[i] = '.'; + } +} + const char *git_user_agent(void) { static const char *agent = NULL; @@ -18,22 +40,64 @@ const char *git_user_agent(void) return agent; } +/* + Retrieve, sanitize and cache operating system info for subsequent + calls. Return a pointer to the sanitized operating system info + string. +*/ +static const char *os_info(void) +{ + static const char *os = NULL; + + if (!os) { + struct strbuf buf = STRBUF_INIT; + + get_uname_info(&buf, 0); + /* Sanitize the os information immediately */ + redact_non_printables(&buf); + os = strbuf_detach(&buf, NULL); + } + + return os; +} + const char *git_user_agent_sanitized(void) { static const char *agent = NULL; if (!agent) { struct strbuf buf = STRBUF_INIT; - int i; strbuf_addstr(&buf, git_user_agent()); - strbuf_trim(&buf); - for (i = 0; i < buf.len; i++) { - if (buf.buf[i] <= 32 || buf.buf[i] >= 127) - buf.buf[i] = '.'; + + if (!getenv("GIT_USER_AGENT")) { + strbuf_addch(&buf, '-'); + strbuf_addstr(&buf, os_info()); } - agent = buf.buf; + redact_non_printables(&buf); + agent = strbuf_detach(&buf, NULL); } return agent; } + +int get_uname_info(struct strbuf *buf, unsigned int full) +{ + struct utsname uname_info; + + if (uname(&uname_info)) { + strbuf_addf(buf, _("uname() failed with error '%s' (%d)\n"), + strerror(errno), + errno); + return -1; + } + if (full) + strbuf_addf(buf, "%s %s %s %s\n", + uname_info.sysname, + uname_info.release, + uname_info.version, + uname_info.machine); + else + strbuf_addf(buf, "%s\n", uname_info.sysname); + return 0; +} diff --git a/version.h b/version.h index 7c62e80577154d..bbde6d371affb7 100644 --- a/version.h +++ b/version.h @@ -1,10 +1,20 @@ #ifndef VERSION_H #define VERSION_H +struct repository; + extern const char git_version_string[]; extern const char git_built_from_commit_string[]; const char *git_user_agent(void); const char *git_user_agent_sanitized(void); +/* + Try to get information about the system using uname(2). + Return -1 and put an error message into 'buf' in case of uname() + error. Return 0 and put uname info into 'buf' otherwise. +*/ +int get_uname_info(struct strbuf *buf, unsigned int full); + + #endif /* VERSION_H */ diff --git a/versioncmp.c b/versioncmp.c index e3b2a6e330a3e8..b6eebdb989c042 100644 --- a/versioncmp.c +++ b/versioncmp.c @@ -77,11 +77,10 @@ static int swap_prereleases(const char *s1, int off, int *diff) { - int i; struct suffix_match match1 = { -1, off, -1 }; struct suffix_match match2 = { -1, off, -1 }; - for (i = 0; i < prereleases->nr; i++) { + for (size_t i = 0; i < prereleases->nr; i++) { const char *suffix = prereleases->items[i].string; int start, suffix_len = strlen(suffix); if (suffix_len < off) diff --git a/walker.c b/walker.c index 807a7a388131fe..1cf3da02193531 100644 --- a/walker.c +++ b/walker.c @@ -157,7 +157,7 @@ static int process(struct walker *walker, struct object *obj) else { if (obj->flags & COMPLETE) return 0; - walker->prefetch(walker, obj->oid.hash); + walker->prefetch(walker, &obj->oid); } object_list_insert(obj, process_queue_end); @@ -172,7 +172,8 @@ static int loop(struct walker *walker) uint64_t nr = 0; if (walker->get_progress) - progress = start_delayed_progress(_("Fetching objects"), 0); + progress = start_delayed_progress(the_repository, + _("Fetching objects"), 0); while (process_queue) { struct object *obj = process_queue->item; @@ -186,7 +187,7 @@ static int loop(struct walker *walker) * the queue because we needed to fetch it first. */ if (! (obj->flags & TO_SCAN)) { - if (walker->fetch(walker, obj->oid.hash)) { + if (walker->fetch(walker, &obj->oid)) { stop_progress(&progress); report_missing(obj); return -1; @@ -290,7 +291,7 @@ int walker_fetch(struct walker *walker, int targets, char **target, if (write_ref) { transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), - &err); + 0, &err); if (!transaction) { error("%s", err.buf); goto done; diff --git a/walker.h b/walker.h index d40b016bab8798..25aaa3631c4258 100644 --- a/walker.h +++ b/walker.h @@ -6,8 +6,8 @@ struct walker { void *data; int (*fetch_ref)(struct walker *, struct ref *ref); - void (*prefetch)(struct walker *, unsigned char *sha1); - int (*fetch)(struct walker *, unsigned char *sha1); + void (*prefetch)(struct walker *, const struct object_id *oid); + int (*fetch)(struct walker *, const struct object_id *oid); void (*cleanup)(struct walker *); int get_verbosely; int get_progress; diff --git a/worktree.c b/worktree.c index 0f032ccedffe63..6449b6798db35d 100644 --- a/worktree.c +++ b/worktree.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "abspath.h" @@ -58,12 +59,35 @@ static void add_head_info(struct worktree *wt) static int is_current_worktree(struct worktree *wt) { char *git_dir = absolute_pathdup(repo_get_git_dir(the_repository)); - const char *wt_git_dir = get_worktree_git_dir(wt); + char *wt_git_dir = get_worktree_git_dir(wt); int is_current = !fspathcmp(git_dir, absolute_path(wt_git_dir)); + free(wt_git_dir); free(git_dir); return is_current; } +/* +* When in a secondary worktree, and when extensions.worktreeConfig +* is true, only $commondir/config and $commondir/worktrees/<id>/ +* config.worktree are consulted, hence any core.bare=true setting in +* $commondir/config.worktree gets overlooked. Thus, check it manually +* to determine if the repository is bare. +*/ +static int is_main_worktree_bare(struct repository *repo) +{ + int bare = 0; + struct config_set cs = {0}; + char *worktree_config = xstrfmt("%s/config.worktree", repo_get_common_dir(repo)); + + git_configset_init(&cs); + git_configset_add_file(&cs, worktree_config); + git_configset_get_bool(&cs, "core.bare", &bare); + + git_configset_clear(&cs); + free(worktree_config); + return bare; +} + /** * get the main worktree */ @@ -78,16 +102,17 @@ static struct worktree *get_main_worktree(int skip_reading_head) CALLOC_ARRAY(worktree, 1); worktree->repo = the_repository; worktree->path = strbuf_detach(&worktree_path, NULL); - /* - * NEEDSWORK: If this function is called from a secondary worktree and - * config.worktree is present, is_bare_repository_cfg will reflect the - * contents of config.worktree, not the contents of the main worktree. - * This means that worktree->is_bare may be set to 0 even if the main - * worktree is configured to be bare. - */ - worktree->is_bare = (is_bare_repository_cfg == 1) || - is_bare_repository(); worktree->is_current = is_current_worktree(worktree); + worktree->is_bare = (is_bare_repository_cfg == 1) || + is_bare_repository() || + /* + * When in a secondary worktree we have to also verify if the main + * worktree is bare in $commondir/config.worktree. + * This check is unnecessary if we're currently in the main worktree, + * as prior checks already consulted all configs of the current worktree. + */ + (!worktree->is_current && is_main_worktree_bare(the_repository)); + if (!skip_reading_head) add_head_info(worktree); return worktree; @@ -103,13 +128,19 @@ struct worktree *get_linked_worktree(const char *id, if (!id) die("Missing linked worktree name"); - strbuf_git_common_path(&path, the_repository, "worktrees/%s/gitdir", id); + repo_common_path_append(the_repository, &path, "worktrees/%s/gitdir", id); if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0) /* invalid gitdir file */ goto done; strbuf_rtrim(&worktree_path); strbuf_strip_suffix(&worktree_path, "/.git"); + if (!is_absolute_path(worktree_path.buf)) { + strbuf_strip_suffix(&path, "gitdir"); + strbuf_addbuf(&path, &worktree_path); + strbuf_realpath_forgiving(&worktree_path, path.buf, 0); + } + CALLOC_ARRAY(worktree, 1); worktree->repo = the_repository; worktree->path = strbuf_detach(&worktree_path, NULL); @@ -168,14 +199,14 @@ struct worktree **get_worktrees(void) return get_worktrees_internal(0); } -const char *get_worktree_git_dir(const struct worktree *wt) +char *get_worktree_git_dir(const struct worktree *wt) { if (!wt) - return repo_get_git_dir(the_repository); + return xstrdup(repo_get_git_dir(the_repository)); else if (!wt->id) - return repo_get_common_dir(the_repository); + return xstrdup(repo_get_common_dir(the_repository)); else - return git_common_path("worktrees/%s", wt->id); + return repo_common_path(the_repository, "worktrees/%s", wt->id); } static struct worktree *find_worktree_by_suffix(struct worktree **list, @@ -306,6 +337,7 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg, { struct strbuf wt_path = STRBUF_INIT; struct strbuf realpath = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; char *path = NULL; int err, ret = -1; @@ -335,7 +367,7 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg, if (!is_absolute_path(wt->path)) { strbuf_addf_gently(errmsg, _("'%s' file does not contain absolute path to the working tree location"), - git_common_path("worktrees/%s/gitdir", wt->id)); + repo_common_path_replace(the_repository, &buf, "worktrees/%s/gitdir", wt->id)); goto done; } @@ -357,34 +389,46 @@ int validate_worktree(const struct worktree *wt, struct strbuf *errmsg, goto done; } - strbuf_realpath(&realpath, git_common_path("worktrees/%s", wt->id), 1); + strbuf_realpath(&realpath, repo_common_path_replace(the_repository, &buf, "worktrees/%s", wt->id), 1); ret = fspathcmp(path, realpath.buf); if (ret) strbuf_addf_gently(errmsg, _("'%s' does not point back to '%s'"), - wt->path, git_common_path("worktrees/%s", wt->id)); + wt->path, repo_common_path_replace(the_repository, &buf, + "worktrees/%s", wt->id)); done: free(path); + strbuf_release(&buf); strbuf_release(&wt_path); strbuf_release(&realpath); return ret; } -void update_worktree_location(struct worktree *wt, const char *path_) +void update_worktree_location(struct worktree *wt, const char *path_, + int use_relative_paths) { struct strbuf path = STRBUF_INIT; + struct strbuf dotgit = STRBUF_INIT; + struct strbuf gitdir = STRBUF_INIT; + char *wt_gitdir; if (is_main_worktree(wt)) BUG("can't relocate main worktree"); + wt_gitdir = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id); + strbuf_realpath(&gitdir, wt_gitdir, 1); strbuf_realpath(&path, path_, 1); + strbuf_addf(&dotgit, "%s/.git", path.buf); if (fspathcmp(wt->path, path.buf)) { - write_file(git_common_path("worktrees/%s/gitdir", wt->id), - "%s/.git", path.buf); + write_worktree_linking_files(dotgit, gitdir, use_relative_paths); + free(wt->path); wt->path = strbuf_detach(&path, NULL); } strbuf_release(&path); + strbuf_release(&dotgit); + strbuf_release(&gitdir); + free(wt_gitdir); } int is_worktree_being_rebased(const struct worktree *wt, @@ -473,7 +517,8 @@ int submodule_uses_worktrees(const char *path) int ret = 0; struct repository_format format = REPOSITORY_FORMAT_INIT; - submodule_gitdir = git_pathdup_submodule(path, "%s", ""); + submodule_gitdir = repo_submodule_path(the_repository, + path, "%s", ""); if (!submodule_gitdir) return 0; @@ -560,42 +605,63 @@ int other_head_refs(each_ref_fn fn, void *cb_data) * pointing at <repo>/worktrees/<id>. */ static void repair_gitfile(struct worktree *wt, - worktree_repair_fn fn, void *cb_data) + worktree_repair_fn fn, void *cb_data, + int use_relative_paths) { struct strbuf dotgit = STRBUF_INIT; + struct strbuf gitdir = STRBUF_INIT; struct strbuf repo = STRBUF_INIT; - char *backlink; + struct strbuf backlink = STRBUF_INIT; + char *dotgit_contents = NULL; const char *repair = NULL; + char *path = NULL; int err; /* missing worktree can't be repaired */ if (!file_exists(wt->path)) - return; + goto done; if (!is_directory(wt->path)) { fn(1, wt->path, _("not a directory"), cb_data); - return; + goto done; } - strbuf_realpath(&repo, git_common_path("worktrees/%s", wt->id), 1); + path = repo_common_path(the_repository, "worktrees/%s", wt->id); + strbuf_realpath(&repo, path, 1); strbuf_addf(&dotgit, "%s/.git", wt->path); - backlink = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err)); + strbuf_addf(&gitdir, "%s/gitdir", repo.buf); + dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err)); + + if (dotgit_contents) { + if (is_absolute_path(dotgit_contents)) { + strbuf_addstr(&backlink, dotgit_contents); + } else { + strbuf_addf(&backlink, "%s/%s", wt->path, dotgit_contents); + strbuf_realpath_forgiving(&backlink, backlink.buf, 0); + } + } if (err == READ_GITFILE_ERR_NOT_A_FILE) fn(1, wt->path, _(".git is not a file"), cb_data); else if (err) repair = _(".git file broken"); - else if (fspathcmp(backlink, repo.buf)) + else if (fspathcmp(backlink.buf, repo.buf)) repair = _(".git file incorrect"); + else if (use_relative_paths == is_absolute_path(dotgit_contents)) + repair = _(".git file absolute/relative path mismatch"); if (repair) { fn(0, wt->path, repair, cb_data); - write_file(dotgit.buf, "gitdir: %s", repo.buf); + write_worktree_linking_files(dotgit, gitdir, use_relative_paths); } - free(backlink); +done: + free(dotgit_contents); + free(path); strbuf_release(&repo); strbuf_release(&dotgit); + strbuf_release(&gitdir); + strbuf_release(&backlink); } static void repair_noop(int iserr UNUSED, @@ -606,7 +672,7 @@ static void repair_noop(int iserr UNUSED, /* nothing */ } -void repair_worktrees(worktree_repair_fn fn, void *cb_data) +void repair_worktrees(worktree_repair_fn fn, void *cb_data, int use_relative_paths) { struct worktree **worktrees = get_worktrees_internal(1); struct worktree **wt = worktrees + 1; /* +1 skips main worktree */ @@ -614,7 +680,50 @@ void repair_worktrees(worktree_repair_fn fn, void *cb_data) if (!fn) fn = repair_noop; for (; *wt; wt++) - repair_gitfile(*wt, fn, cb_data); + repair_gitfile(*wt, fn, cb_data, use_relative_paths); + free_worktrees(worktrees); +} + +void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path) +{ + struct strbuf gitdir = STRBUF_INIT; + struct strbuf dotgit = STRBUF_INIT; + int is_relative_path; + char *path = NULL; + + if (is_main_worktree(wt)) + goto done; + + path = repo_common_path(the_repository, "worktrees/%s/gitdir", wt->id); + strbuf_realpath(&gitdir, path, 1); + + if (strbuf_read_file(&dotgit, gitdir.buf, 0) < 0) + goto done; + + strbuf_rtrim(&dotgit); + is_relative_path = ! is_absolute_path(dotgit.buf); + if (is_relative_path) { + strbuf_insertf(&dotgit, 0, "%s/worktrees/%s/", old_path, wt->id); + strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0); + } + + if (!file_exists(dotgit.buf)) + goto done; + + write_worktree_linking_files(dotgit, gitdir, is_relative_path); +done: + strbuf_release(&gitdir); + strbuf_release(&dotgit); + free(path); +} + +void repair_worktrees_after_gitdir_move(const char *old_path) +{ + struct worktree **worktrees = get_worktrees_internal(1); + struct worktree **wt = worktrees + 1; /* +1 skips main worktree */ + + for (; *wt; wt++) + repair_worktree_after_gitdir_move(*wt, old_path); free_worktrees(worktrees); } @@ -641,11 +750,12 @@ static int is_main_worktree_path(const char *path) * won't know which <repo>/worktrees/<id>/gitdir to repair. However, we may * be able to infer the gitdir by manually reading /path/to/worktree/.git, * extracting the <id>, and checking if <repo>/worktrees/<id> exists. + * + * Returns -1 on failure and strbuf.len on success. */ -static char *infer_backlink(const char *gitfile) +static ssize_t infer_backlink(const char *gitfile, struct strbuf *inferred) { struct strbuf actual = STRBUF_INIT; - struct strbuf inferred = STRBUF_INIT; const char *id; if (strbuf_read_file(&actual, gitfile, 0) < 0) @@ -658,17 +768,16 @@ static char *infer_backlink(const char *gitfile) id++; /* advance past '/' to point at <id> */ if (!*id) goto error; - strbuf_git_common_path(&inferred, the_repository, "worktrees/%s", id); - if (!is_directory(inferred.buf)) + repo_common_path_replace(the_repository, inferred, "worktrees/%s", id); + if (!is_directory(inferred->buf)) goto error; strbuf_release(&actual); - return strbuf_detach(&inferred, NULL); - + return inferred->len; error: strbuf_release(&actual); - strbuf_release(&inferred); - return NULL; + strbuf_reset(inferred); /* clear invalid path */ + return -1; } /* @@ -676,13 +785,15 @@ static char *infer_backlink(const char *gitfile) * the worktree's path. */ void repair_worktree_at_path(const char *path, - worktree_repair_fn fn, void *cb_data) + worktree_repair_fn fn, void *cb_data, + int use_relative_paths) { struct strbuf dotgit = STRBUF_INIT; - struct strbuf realdotgit = STRBUF_INIT; + struct strbuf backlink = STRBUF_INIT; + struct strbuf inferred_backlink = STRBUF_INIT; struct strbuf gitdir = STRBUF_INIT; struct strbuf olddotgit = STRBUF_INIT; - char *backlink = NULL; + char *dotgit_contents = NULL; const char *repair = NULL; int err; @@ -693,112 +804,183 @@ void repair_worktree_at_path(const char *path, goto done; strbuf_addf(&dotgit, "%s/.git", path); - if (!strbuf_realpath(&realdotgit, dotgit.buf, 0)) { + if (!strbuf_realpath(&dotgit, dotgit.buf, 0)) { fn(1, path, _("not a valid path"), cb_data); goto done; } - backlink = xstrdup_or_null(read_gitfile_gently(realdotgit.buf, &err)); - if (err == READ_GITFILE_ERR_NOT_A_FILE) { - fn(1, realdotgit.buf, _("unable to locate repository; .git is not a file"), cb_data); + infer_backlink(dotgit.buf, &inferred_backlink); + strbuf_realpath_forgiving(&inferred_backlink, inferred_backlink.buf, 0); + dotgit_contents = xstrdup_or_null(read_gitfile_gently(dotgit.buf, &err)); + if (dotgit_contents) { + if (is_absolute_path(dotgit_contents)) { + strbuf_addstr(&backlink, dotgit_contents); + } else { + strbuf_addbuf(&backlink, &dotgit); + strbuf_strip_suffix(&backlink, ".git"); + strbuf_addstr(&backlink, dotgit_contents); + strbuf_realpath_forgiving(&backlink, backlink.buf, 0); + } + } else if (err == READ_GITFILE_ERR_NOT_A_FILE) { + fn(1, dotgit.buf, _("unable to locate repository; .git is not a file"), cb_data); goto done; } else if (err == READ_GITFILE_ERR_NOT_A_REPO) { - if (!(backlink = infer_backlink(realdotgit.buf))) { - fn(1, realdotgit.buf, _("unable to locate repository; .git file does not reference a repository"), cb_data); + if (inferred_backlink.len) { + /* + * Worktree's .git file does not point at a repository + * but we found a .git/worktrees/<id> in this + * repository with the same <id> as recorded in the + * worktree's .git file so make the worktree point at + * the discovered .git/worktrees/<id>. + */ + strbuf_swap(&backlink, &inferred_backlink); + } else { + fn(1, dotgit.buf, _("unable to locate repository; .git file does not reference a repository"), cb_data); goto done; } - } else if (err) { - fn(1, realdotgit.buf, _("unable to locate repository; .git file broken"), cb_data); + } else { + fn(1, dotgit.buf, _("unable to locate repository; .git file broken"), cb_data); goto done; } - strbuf_addf(&gitdir, "%s/gitdir", backlink); + /* + * If we got this far, either the worktree's .git file pointed at a + * valid repository (i.e. read_gitfile_gently() returned success) or + * the .git file did not point at a repository but we were able to + * infer a suitable new value for the .git file by locating a + * .git/worktrees/<id> in *this* repository corresponding to the <id> + * recorded in the worktree's .git file. + * + * However, if, at this point, inferred_backlink is non-NULL (i.e. we + * found a suitable .git/worktrees/<id> in *this* repository) *and* the + * worktree's .git file points at a valid repository *and* those two + * paths differ, then that indicates that the user probably *copied* + * the main and linked worktrees to a new location as a unit rather + * than *moving* them. Thus, the copied worktree's .git file actually + * points at the .git/worktrees/<id> in the *original* repository, not + * in the "copy" repository. In this case, point the "copy" worktree's + * .git file at the "copy" repository. + */ + if (inferred_backlink.len && fspathcmp(backlink.buf, inferred_backlink.buf)) + strbuf_swap(&backlink, &inferred_backlink); + + strbuf_addf(&gitdir, "%s/gitdir", backlink.buf); if (strbuf_read_file(&olddotgit, gitdir.buf, 0) < 0) repair = _("gitdir unreadable"); + else if (use_relative_paths == is_absolute_path(olddotgit.buf)) + repair = _("gitdir absolute/relative path mismatch"); else { strbuf_rtrim(&olddotgit); - if (fspathcmp(olddotgit.buf, realdotgit.buf)) + if (!is_absolute_path(olddotgit.buf)) { + strbuf_insertf(&olddotgit, 0, "%s/", backlink.buf); + strbuf_realpath_forgiving(&olddotgit, olddotgit.buf, 0); + } + if (fspathcmp(olddotgit.buf, dotgit.buf)) repair = _("gitdir incorrect"); } if (repair) { fn(0, gitdir.buf, repair, cb_data); - write_file(gitdir.buf, "%s", realdotgit.buf); + write_worktree_linking_files(dotgit, gitdir, use_relative_paths); } done: - free(backlink); + free(dotgit_contents); strbuf_release(&olddotgit); + strbuf_release(&backlink); + strbuf_release(&inferred_backlink); strbuf_release(&gitdir); - strbuf_release(&realdotgit); strbuf_release(&dotgit); } int should_prune_worktree(const char *id, struct strbuf *reason, char **wtpath, timestamp_t expire) { struct stat st; - char *path; + struct strbuf dotgit = STRBUF_INIT; + struct strbuf gitdir = STRBUF_INIT; + struct strbuf repo = STRBUF_INIT; + struct strbuf file = STRBUF_INIT; + char *path = NULL; + int rc = 0; int fd; size_t len; ssize_t read_result; *wtpath = NULL; - if (!is_directory(git_path("worktrees/%s", id))) { + + path = repo_common_path(the_repository, "worktrees/%s", id); + strbuf_realpath(&repo, path, 1); + FREE_AND_NULL(path); + + strbuf_addf(&gitdir, "%s/gitdir", repo.buf); + if (!is_directory(repo.buf)) { strbuf_addstr(reason, _("not a valid directory")); - return 1; + rc = 1; + goto done; } - if (file_exists(git_path("worktrees/%s/locked", id))) - return 0; - if (stat(git_path("worktrees/%s/gitdir", id), &st)) { + strbuf_addf(&file, "%s/locked", repo.buf); + if (file_exists(file.buf)) { + goto done; + } + if (stat(gitdir.buf, &st)) { strbuf_addstr(reason, _("gitdir file does not exist")); - return 1; + rc = 1; + goto done; } - fd = open(git_path("worktrees/%s/gitdir", id), O_RDONLY); + fd = open(gitdir.buf, O_RDONLY); if (fd < 0) { strbuf_addf(reason, _("unable to read gitdir file (%s)"), strerror(errno)); - return 1; + rc = 1; + goto done; } len = xsize_t(st.st_size); path = xmallocz(len); read_result = read_in_full(fd, path, len); + close(fd); if (read_result < 0) { strbuf_addf(reason, _("unable to read gitdir file (%s)"), strerror(errno)); - close(fd); - free(path); - return 1; - } - close(fd); - - if (read_result != len) { + rc = 1; + goto done; + } else if (read_result != len) { strbuf_addf(reason, _("short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"), (uintmax_t)len, (uintmax_t)read_result); - free(path); - return 1; + rc = 1; + goto done; } while (len && (path[len - 1] == '\n' || path[len - 1] == '\r')) len--; if (!len) { strbuf_addstr(reason, _("invalid gitdir file")); - free(path); - return 1; + rc = 1; + goto done; } path[len] = '\0'; - if (!file_exists(path)) { - if (stat(git_path("worktrees/%s/index", id), &st) || - st.st_mtime <= expire) { + if (is_absolute_path(path)) { + strbuf_addstr(&dotgit, path); + } else { + strbuf_addf(&dotgit, "%s/%s", repo.buf, path); + strbuf_realpath_forgiving(&dotgit, dotgit.buf, 0); + } + if (!file_exists(dotgit.buf)) { + strbuf_reset(&file); + strbuf_addf(&file, "%s/index", repo.buf); + if (stat(file.buf, &st) || st.st_mtime <= expire) { strbuf_addstr(reason, _("gitdir file points to non-existent location")); - free(path); - return 1; - } else { - *wtpath = path; - return 0; + rc = 1; + goto done; } } - *wtpath = path; - return 0; + *wtpath = strbuf_detach(&dotgit, NULL); +done: + free(path); + strbuf_release(&dotgit); + strbuf_release(&gitdir); + strbuf_release(&repo); + strbuf_release(&file); + return rc; } static int move_config_setting(const char *key, const char *value, @@ -872,3 +1054,38 @@ int init_worktree_config(struct repository *r) free(main_worktree_file); return res; } + +void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir, + int use_relative_paths) +{ + struct strbuf path = STRBUF_INIT; + struct strbuf repo = STRBUF_INIT; + struct strbuf tmp = STRBUF_INIT; + + strbuf_addbuf(&path, &dotgit); + strbuf_strip_suffix(&path, "/.git"); + strbuf_realpath(&path, path.buf, 1); + strbuf_addbuf(&repo, &gitdir); + strbuf_strip_suffix(&repo, "/gitdir"); + strbuf_realpath(&repo, repo.buf, 1); + + if (use_relative_paths && !the_repository->repository_format_relative_worktrees) { + if (upgrade_repository_format(1) < 0) + die(_("unable to upgrade repository format to support relative worktrees")); + if (git_config_set_gently("extensions.relativeWorktrees", "true")) + die(_("unable to set extensions.relativeWorktrees setting")); + the_repository->repository_format_relative_worktrees = 1; + } + + if (use_relative_paths) { + write_file(gitdir.buf, "%s/.git", relative_path(path.buf, repo.buf, &tmp)); + write_file(dotgit.buf, "gitdir: %s", relative_path(repo.buf, path.buf, &tmp)); + } else { + write_file(gitdir.buf, "%s/.git", path.buf); + write_file(dotgit.buf, "gitdir: %s", repo.buf); + } + + strbuf_release(&path); + strbuf_release(&repo); + strbuf_release(&tmp); +} diff --git a/worktree.h b/worktree.h index 11279d0c8fe249..16368588a0d46b 100644 --- a/worktree.h +++ b/worktree.h @@ -39,7 +39,7 @@ int submodule_uses_worktrees(const char *path); * Return git dir of the worktree. Note that the path may be relative. * If wt is NULL, git dir of current worktree is returned. */ -const char *get_worktree_git_dir(const struct worktree *wt); +char *get_worktree_git_dir(const struct worktree *wt); /* * Search for the worktree identified unambiguously by `arg` -- typically @@ -117,8 +117,8 @@ int validate_worktree(const struct worktree *wt, /* * Update worktrees/xxx/gitdir with the new path. */ -void update_worktree_location(struct worktree *wt, - const char *path_); +void update_worktree_location(struct worktree *wt, const char *path_, + int use_relative_paths); typedef void (* worktree_repair_fn)(int iserr, const char *path, const char *msg, void *cb_data); @@ -129,7 +129,17 @@ typedef void (* worktree_repair_fn)(int iserr, const char *path, * function, if non-NULL, is called with the path of the worktree and a * description of the repair or error, along with the callback user-data. */ -void repair_worktrees(worktree_repair_fn, void *cb_data); +void repair_worktrees(worktree_repair_fn, void *cb_data, int use_relative_paths); + +/* + * Repair the linked worktrees after the gitdir has been moved. + */ +void repair_worktrees_after_gitdir_move(const char *old_path); + +/* + * Repair the linked worktree after the gitdir has been moved. + */ +void repair_worktree_after_gitdir_move(struct worktree *wt, const char *old_path); /* * Repair administrative files corresponding to the worktree at the given path. @@ -141,7 +151,8 @@ void repair_worktrees(worktree_repair_fn, void *cb_data); * worktree and a description of the repair or error, along with the callback * user-data. */ -void repair_worktree_at_path(const char *, worktree_repair_fn, void *cb_data); +void repair_worktree_at_path(const char *, worktree_repair_fn, + void *cb_data, int use_relative_paths); /* * Free up the memory for a worktree. @@ -205,4 +216,17 @@ void strbuf_worktree_ref(const struct worktree *wt, */ int init_worktree_config(struct repository *r); +/** + * Write the .git file and gitdir file that links the worktree to the repository. + * + * The `dotgit` parameter is the path to the worktree's .git file, and `gitdir` + * is the path to the repository's `gitdir` file. + * + * Example + * dotgit: "/path/to/foo/.git" + * gitdir: "/path/to/repo/worktrees/foo/gitdir" + */ +void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir, + int use_relative_paths); + #endif diff --git a/wrap-for-bin.sh b/wrap-for-bin.sh deleted file mode 100644 index 95851b85b6b718..00000000000000 --- a/wrap-for-bin.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh - -# wrap-for-bin.sh: Template for git executable wrapper scripts -# to run test suite against sandbox, but with only bindir-installed -# executables in PATH. The Makefile copies this into various -# files in bin-wrappers, substituting -# @@BUILD_DIR@@ and @@PROG@@. - -GIT_EXEC_PATH='@@BUILD_DIR@@' -if test -n "$NO_SET_GIT_TEMPLATE_DIR" -then - unset GIT_TEMPLATE_DIR -else - GIT_TEMPLATE_DIR='@@BUILD_DIR@@/templates/blt' - export GIT_TEMPLATE_DIR -fi -GITPERLLIB='@@BUILD_DIR@@/perl/build/lib'"${GITPERLLIB:+:$GITPERLLIB}" -GIT_TEXTDOMAINDIR='@@BUILD_DIR@@/po/build/locale' -PATH='@@BUILD_DIR@@/bin-wrappers:'"$PATH" - -export GIT_EXEC_PATH GITPERLLIB PATH GIT_TEXTDOMAINDIR - -case "$GIT_DEBUGGER" in -'') - exec "${GIT_EXEC_PATH}/@@PROG@@" "$@" - ;; -1) - unset GIT_DEBUGGER - exec gdb --args "${GIT_EXEC_PATH}/@@PROG@@" "$@" - ;; -*) - GIT_DEBUGGER_ARGS="$GIT_DEBUGGER" - unset GIT_DEBUGGER - exec ${GIT_DEBUGGER_ARGS} "${GIT_EXEC_PATH}/@@PROG@@" "$@" - ;; -esac diff --git a/wrapper.c b/wrapper.c index f87d90bf5794a5..8b985931490d62 100644 --- a/wrapper.c +++ b/wrapper.c @@ -1,6 +1,9 @@ /* * Various trivial helper wrappers around standard functions */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "abspath.h" #include "parse.h" @@ -476,7 +479,7 @@ int git_mkstemps_mode(char *pattern, int suffix_len, int mode) for (count = 0; count < TMP_MAX; ++count) { int i; uint64_t v; - if (csprng_bytes(&v, sizeof(v)) < 0) + if (csprng_bytes(&v, sizeof(v), 0) < 0) return error_errno("unable to get random bytes for temporary file"); /* Fill in the random bits. */ @@ -747,7 +750,7 @@ int open_nofollow(const char *path, int flags) #endif } -int csprng_bytes(void *buf, size_t len) +int csprng_bytes(void *buf, size_t len, MAYBE_UNUSED unsigned flags) { #if defined(HAVE_ARC4RANDOM) || defined(HAVE_ARC4RANDOM_LIBBSD) /* This function never returns an error. */ @@ -782,14 +785,18 @@ int csprng_bytes(void *buf, size_t len) return -1; return 0; #elif defined(HAVE_OPENSSL_CSPRNG) - int res = RAND_bytes(buf, len); - if (res == 1) + switch (RAND_pseudo_bytes(buf, len)) { + case 1: return 0; - if (res == -1) - errno = ENOTSUP; - else + case 0: + if (flags & CSPRNG_BYTES_INSECURE) + return 0; errno = EIO; - return -1; + return -1; + default: + errno = ENOTSUP; + return -1; + } #else ssize_t res; char *p = buf; @@ -813,11 +820,11 @@ int csprng_bytes(void *buf, size_t len) #endif } -uint32_t git_rand(void) +uint32_t git_rand(unsigned flags) { uint32_t result; - if (csprng_bytes(&result, sizeof(result)) < 0) + if (csprng_bytes(&result, sizeof(result), flags) < 0) die(_("unable to get random bytes")); return result; diff --git a/wrapper.h b/wrapper.h index a6b3e1f09ecdef..7df824e34a906e 100644 --- a/wrapper.h +++ b/wrapper.h @@ -127,18 +127,26 @@ int open_nofollow(const char *path, int flags); void sleep_millisec(int millisec); +enum { + /* + * Accept insecure bytes, which some CSPRNG implementations may return + * in case the entropy pool has been exhausted. + */ + CSPRNG_BYTES_INSECURE = (1 << 0), +}; + /* * Generate len bytes from the system cryptographically secure PRNG. * Returns 0 on success and -1 on error, setting errno. The inability to - * satisfy the full request is an error. + * satisfy the full request is an error. Accepts CSPRNG flags. */ -int csprng_bytes(void *buf, size_t len); +int csprng_bytes(void *buf, size_t len, unsigned flags); /* * Returns a random uint32_t, uniformly distributed across all possible - * values. + * values. Accepts CSPRNG flags. */ -uint32_t git_rand(void); +uint32_t git_rand(unsigned flags); /* Provide log2 of the given `size_t`. */ static inline unsigned log2u(uintmax_t sz) diff --git a/ws.c b/ws.c index 9456e2fdbe3766..70acee3337f241 100644 --- a/ws.c +++ b/ws.c @@ -3,6 +3,9 @@ * * Copyright (c) 2007 Junio C Hamano */ + +#define DISABLE_SIGN_COMPARE_WARNINGS + #include "git-compat-util.h" #include "attr.h" #include "strbuf.h" diff --git a/wt-status.c b/wt-status.c index 6a6397ca8f12ba..1da5732f57b115 100644 --- a/wt-status.c +++ b/wt-status.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "advice.h" @@ -717,6 +718,7 @@ static int add_file_to_list(const struct object_id *oid, static void wt_status_collect_changes_initial(struct wt_status *s) { struct index_state *istate = s->repo->index; + struct strbuf base = STRBUF_INIT; int i; for (i = 0; i < istate->cache_nr; i++) { @@ -735,7 +737,6 @@ static void wt_status_collect_changes_initial(struct wt_status *s) * expanding the trees to find the elements that are new in this * tree and marking them with DIFF_STATUS_ADDED. */ - struct strbuf base = STRBUF_INIT; struct pathspec ps = { 0 }; struct tree *tree = lookup_tree(istate->repo, &ce->oid); @@ -743,9 +744,11 @@ static void wt_status_collect_changes_initial(struct wt_status *s) ps.has_wildcard = 1; ps.max_depth = -1; + strbuf_reset(&base); strbuf_add(&base, ce->name, ce->ce_namelen); read_tree_at(istate->repo, tree, &base, 0, &ps, add_file_to_list, s); + continue; } @@ -772,6 +775,8 @@ static void wt_status_collect_changes_initial(struct wt_status *s) s->committable = 1; } } + + strbuf_release(&base); } static void wt_status_collect_untracked(struct wt_status *s) @@ -1284,7 +1289,8 @@ static void show_am_in_progress(struct wt_status *s, static char *read_line_from_git_path(const char *filename) { struct strbuf buf = STRBUF_INIT; - FILE *fp = fopen_or_warn(git_path("%s", filename), "r"); + FILE *fp = fopen_or_warn(repo_git_path_append(the_repository, &buf, + "%s", filename), "r"); if (!fp) { strbuf_release(&buf); @@ -1378,27 +1384,33 @@ static void abbrev_oid_in_line(struct strbuf *line) static int read_rebase_todolist(const char *fname, struct string_list *lines) { - struct strbuf line = STRBUF_INIT; - FILE *f = fopen(git_path("%s", fname), "r"); + struct strbuf buf = STRBUF_INIT; + FILE *f = fopen(repo_git_path_append(the_repository, &buf, "%s", fname), "r"); + int ret; if (!f) { - if (errno == ENOENT) - return -1; + if (errno == ENOENT) { + ret = -1; + goto out; + } die_errno("Could not open file %s for reading", - git_path("%s", fname)); + repo_git_path_replace(the_repository, &buf, "%s", fname)); } - while (!strbuf_getline_lf(&line, f)) { - if (starts_with(line.buf, comment_line_str)) + while (!strbuf_getline_lf(&buf, f)) { + if (starts_with(buf.buf, comment_line_str)) continue; - strbuf_trim(&line); - if (!line.len) + strbuf_trim(&buf); + if (!buf.len) continue; - abbrev_oid_in_line(&line); - string_list_append(lines, line.buf); + abbrev_oid_in_line(&buf); + string_list_append(lines, buf.buf); } fclose(f); - strbuf_release(&line); - return 0; + + ret = 0; +out: + strbuf_release(&buf); + return ret; } static void show_rebase_information(struct wt_status *s, @@ -1429,9 +1441,12 @@ static void show_rebase_information(struct wt_status *s, i < have_done.nr; i++) status_printf_ln(s, color, " %s", have_done.items[i].string); - if (have_done.nr > nr_lines_to_show && s->hints) + if (have_done.nr > nr_lines_to_show && s->hints) { + char *path = repo_git_path(the_repository, "rebase-merge/done"); status_printf_ln(s, color, - _(" (see more in file %s)"), git_path("rebase-merge/done")); + _(" (see more in file %s)"), path); + free(path); + } } if (yet_to_do.nr == 0) diff --git a/xdiff-interface.c b/xdiff-interface.c index d5dc88661e7207..3bd61f26e9043e 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -1,4 +1,5 @@ #define USE_THE_REPOSITORY_VARIABLE +#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "gettext.h" diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index bb56b23f34c96c..2cecde5afe5da1 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -85,7 +85,7 @@ typedef struct s_xpparam { regex_t **ignore_regex; size_t ignore_regex_nr; - /* See Documentation/diff-options.txt. */ + /* See Documentation/diff-options.adoc. */ char **anchors; size_t anchors_nr; } xpparam_t; diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 344c2dfc3eb443..8889b8b62a1a6e 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -1013,7 +1013,7 @@ static void xdl_mark_ignorable_lines(xdchange_t *xscr, xdfenv_t *xe, long flags) static int record_matches_regex(xrecord_t *rec, xpparam_t const *xpp) { regmatch_t regmatch; - int i; + size_t i; for (i = 0; i < xpp->ignore_regex_nr; i++) if (!regexec_buf(xpp->ignore_regex[i], rec->ptr, rec->size, 1, diff --git a/xdiff/xemit.c b/xdiff/xemit.c index 75f0fe498661c4..f8e3f25b03b7f7 100644 --- a/xdiff/xemit.c +++ b/xdiff/xemit.c @@ -54,7 +54,7 @@ xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg) xdchange_t *xch, *xchp, *lxch; long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen; long max_ignorable = xecfg->ctxlen; - unsigned long ignored = 0; /* number of ignored blank lines */ + long ignored = 0; /* number of ignored blank lines */ /* remove ignorable changes that are too far before other changes */ for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) { diff --git a/xdiff/xhistogram.c b/xdiff/xhistogram.c index 16a8fe2f3f3df3..040d81e0bc9f5c 100644 --- a/xdiff/xhistogram.c +++ b/xdiff/xhistogram.c @@ -106,7 +106,7 @@ static int scanA(struct histindex *index, int line1, int count1) unsigned int chain_len; struct record **rec_chain, *rec; - for (ptr = LINE_END(1); line1 <= ptr; ptr--) { + for (ptr = LINE_END(1); (unsigned int)line1 <= ptr; ptr--) { tbl_idx = TABLE_HASH(index, 1, ptr); rec_chain = index->records + tbl_idx; rec = *rec_chain; @@ -181,14 +181,14 @@ static int try_lcs(struct histindex *index, struct region *lcs, int b_ptr, be = bs; rc = rec->cnt; - while (line1 < as && line2 < bs + while ((unsigned int)line1 < as && (unsigned int)line2 < bs && CMP(index, 1, as - 1, 2, bs - 1)) { as--; bs--; if (1 < rc) rc = XDL_MIN(rc, CNT(index, as)); } - while (ae < LINE_END(1) && be < LINE_END(2) + while (ae < (unsigned int)LINE_END(1) && be < (unsigned int)LINE_END(2) && CMP(index, 1, ae + 1, 2, be + 1)) { ae++; be++; @@ -313,7 +313,7 @@ static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env, if (count1 <= 0 && count2 <= 0) return 0; - if (LINE_END(1) >= MAX_PTR) + if ((unsigned int)LINE_END(1) >= MAX_PTR) return -1; if (!count1) { diff --git a/xdiff/xpatience.c b/xdiff/xpatience.c index a2d8955537f566..77dc411d1937ab 100644 --- a/xdiff/xpatience.c +++ b/xdiff/xpatience.c @@ -19,6 +19,7 @@ * Davide Libenzi <davidel@xmailserver.org> * */ + #include "xinclude.h" /* @@ -63,7 +64,7 @@ struct hashmap { /* * If 1, this entry can serve as an anchor. See - * Documentation/diff-options.txt for more information. + * Documentation/diff-options.adoc for more information. */ unsigned anchor : 1; } *entries, *first, *last; @@ -75,7 +76,7 @@ struct hashmap { static int is_anchor(xpparam_t const *xpp, const char *line) { - int i; + size_t i; for (i = 0; i < xpp->anchors_nr; i++) { if (!strncmp(line, xpp->anchors[i], strlen(xpp->anchors[i]))) return 1; diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 9e36f24875d207..444a108f87c0b6 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -375,7 +375,7 @@ static int xdl_format_hunk_hdr(long s1, long c1, long s2, long c2, nb += 3; if (func && funclen) { buf[nb++] = ' '; - if (funclen > sizeof(buf) - nb - 1) + if ((size_t)funclen > sizeof(buf) - nb - 1) funclen = sizeof(buf) - nb - 1; memcpy(buf + nb, func, funclen); nb += funclen; @@ -437,7 +437,7 @@ void* xdl_alloc_grow_helper(void *p, long nr, long *alloc, size_t size) { void *tmp = NULL; size_t n = ((LONG_MAX - 16) / 2 >= *alloc) ? 2 * *alloc + 16 : LONG_MAX; - if (nr > n) + if ((size_t)nr > n) n = nr; if (SIZE_MAX / size >= n) tmp = xdl_realloc(p, n * size);