diff options
1538 files changed, 32218 insertions, 9977 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 77346a4929..1fbdc2652b 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -9,7 +9,7 @@ freebsd_task: DEFAULT_TEST_TARGET: prove DEVELOPER: 1 freebsd_instance: - image_family: freebsd-13-2 + image_family: freebsd-13-4 memory: 2G install_script: pkg install -y gettext gmake perl5 diff --git a/.clang-format b/.clang-format index 41969eca4b..9547fe1b77 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/.github/workflows/main.yml b/.github/workflows/main.yml index 1ee0433acc..808ddc19b8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -113,13 +113,15 @@ jobs: cancel-in-progress: ${{ needs.ci-config.outputs.skip_concurrent == 'yes' }} steps: - uses: actions/checkout@v4 - - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: setup SDK + shell: powershell + run: ci/install-sdk.ps1 - name: build - shell: bash + shell: powershell env: HOME: ${{runner.workspace}} NO_PERL: 1 - run: . /etc/profile && ci/make-test-artifacts.sh artifacts + run: git-sdk/usr/bin/bash.exe -l -c 'ci/make-test-artifacts.sh artifacts' - name: zip up tracked files run: git archive -o artifacts/tracked.tar.gz HEAD - name: upload tracked files and build artifacts @@ -147,10 +149,12 @@ jobs: - name: extract tracked files and build artifacts shell: bash run: tar xf artifacts.tar.gz && tar xf tracked.tar.gz - - uses: git-for-windows/setup-git-for-windows-sdk@v1 + - name: setup SDK + shell: powershell + run: ci/install-sdk.ps1 - name: test - shell: bash - run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 + shell: powershell + run: git-sdk/usr/bin/bash.exe -l -c 'ci/run-test-slice.sh ${{matrix.nr}} 10' - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' shell: bash @@ -338,39 +342,42 @@ jobs: - jobname: linux-musl image: alpine distro: alpine-latest + # Supported until 2025-04-02. - jobname: linux32 - image: daald/ubuntu32:xenial - distro: ubuntu32-16.04 + image: i386/ubuntu:focal + distro: ubuntu32-20.04 - jobname: pedantic image: fedora distro: fedora-latest + # A RHEL 8 compatible distro. Supported until 2029-05-31. + - jobname: almalinux-8 + image: almalinux:8 + distro: almalinux-8 + # Supported until 2026-08-31. + - jobname: debian-11 + image: debian:11 + distro: debian-11 env: jobname: ${{matrix.vector.jobname}} distro: ${{matrix.vector.distro}} runs-on: ubuntu-latest container: ${{matrix.vector.image}} steps: - - uses: actions/checkout@v4 - if: matrix.vector.jobname != 'linux32' - - uses: actions/checkout@v1 # cannot be upgraded because Node.js Actions aren't supported in this container + - name: prepare libc6 for actions if: matrix.vector.jobname == 'linux32' + 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 - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' run: ci/print-test-failures.sh - name: Upload failed tests' directories - if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname != 'linux32' + if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v4 with: name: failed-tests-${{matrix.vector.jobname}} path: ${{env.FAILED_TEST_ARTIFACTS}} - - name: Upload failed tests' directories - if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname == 'linux32' - uses: actions/upload-artifact@v1 # cannot be upgraded because Node.js Actions aren't supported in this container - with: - name: failed-tests-${{matrix.vector.jobname}} - path: ${{env.FAILED_TEST_ARTIFACTS}} static-analysis: needs: ci-config if: needs.ci-config.outputs.enabled == 'yes' diff --git a/.gitignore b/.gitignore index 8caf3700c2..e82aa19df0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,9 @@ /GIT-PYTHON-VARS /GIT-SCRIPT-DEFINES /GIT-SPATCH-DEFINES +/GIT-TEST-SUITES /GIT-USER-AGENT /GIT-VERSION-FILE -/bin-wrappers/ /git /git-add /git-am @@ -194,9 +194,11 @@ /config-list.h /command-list.h /hook-list.h +/version-def.h *.tar.gz *.dsc *.deb +/git.rc /git.spec *.exe *.[aos] diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2589098eff..a1bc92893f 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,6 +14,10 @@ workflow: test:linux: image: $image + stage: test + needs: [ ] + tags: + - saas-linux-medium-amd64 variables: CUSTOM_PATH: "/custom" before_script: @@ -25,6 +34,9 @@ test:linux: fi parallel: matrix: + - jobname: linux-old + image: ubuntu:20.04 + CC: gcc - jobname: linux-sha256 image: ubuntu:latest CC: clang @@ -62,6 +74,8 @@ test:linux: test:osx: image: $image + stage: test + needs: [ ] tags: - saas-macos-medium-m1 variables: @@ -95,8 +109,42 @@ test:osx: - 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 + test:fuzz-smoke-tests: image: ubuntu:latest + stage: test + needs: [ ] variables: CC: clang before_script: @@ -106,6 +154,8 @@ test:fuzz-smoke-tests: static-analysis: image: ubuntu:22.04 + stage: analyze + needs: [ ] variables: jobname: StaticAnalysis before_script: @@ -116,6 +166,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 @@ -130,6 +182,8 @@ check-whitespace: check-style: image: ubuntu:latest + stage: analyze + needs: [ ] allow_failure: true variables: CC: clang @@ -148,6 +202,8 @@ check-style: documentation: image: ubuntu:latest + stage: analyze + needs: [ ] variables: jobname: Documentation before_script: diff --git a/Documentation/.gitignore b/Documentation/.gitignore index a48448de32..649df89474 100644 --- a/Documentation/.gitignore +++ b/Documentation/.gitignore @@ -15,3 +15,5 @@ tmp-doc-diff/ GIT-ASCIIDOCFLAGS /.build/ /GIT-EXCLUDED-PROGRAMS +/asciidoc.conf +/asciidoctor-extensions.rb diff --git a/Documentation/BreakingChanges.txt b/Documentation/BreakingChanges.txt index 2b64665694..27acff86db 100644 --- a/Documentation/BreakingChanges.txt +++ b/Documentation/BreakingChanges.txt @@ -59,10 +59,29 @@ 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. + +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 may also want to have a CI job +or two 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 -is no planned release date for this breaking version yet. +is no planned release date for this breaking version yet. The early +adopter configuration used for changes for this release is `feature.git3`. Proposed changes and removals only include items which are "ready" to be done. In other words, this is not supposed to be a wishlist of features that should @@ -117,7 +136,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. diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 3263245b03..ba047ed224 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -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 @@ -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.txt index dbb4c1f569..b43c472ae5 100644 --- a/Documentation/DecisionMaking.txt +++ b/Documentation/DecisionMaking.txt @@ -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 0f55baa252..3392e1ce7e 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -1,6 +1,8 @@ # Import tree-wide shared Makefile behavior and libraries include ../shared.mak +.PHONY: FORCE + # Guard against environment variables MAN1_TXT = MAN5_TXT = @@ -111,6 +113,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 @@ -148,16 +151,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) @@ -210,6 +209,14 @@ 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)GIT_USER_AGENT="$(GIT_USER_AGENT)" $(SHELL_PATH) ../GIT-VERSION-GEN "$(shell pwd)/.." $< $@+ + @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi +else +asciidoc.conf: asciidoc.conf.in FORCE + $(QUIET_GEN)GIT_USER_AGENT="$(GIT_USER_AGENT)" $(SHELL_PATH) ../GIT-VERSION-GEN "$(shell pwd)/.." $< $@+ + @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi endif ASCIIDOC_DEPS += docinfo.html @@ -218,6 +225,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)' @@ -275,15 +283,17 @@ ifneq ($(filter-out lint-docs clean,$(MAKECMDGOALS)),) -include ../GIT-VERSION-FILE endif +mergetools_txt = mergetools-diff.txt mergetools-merge.txt + # # 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 @@ -305,22 +315,14 @@ cmds_txt = cmds-ancillaryinterrogators.txt \ $(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-%.txt: generate-mergetool-list.sh ../git-mergetool--lib.sh $(wildcard ../mergetools/*) +mergetools-diff.txt: + $(QUIET_GEN)$(SHELL_PATH) ./generate-mergetool-list.sh .. diff $@ +mergetools-merge.txt: + $(QUIET_GEN)$(SHELL_PATH) ./generate-mergetool-list.sh .. merge $@ TRACK_ASCIIDOCFLAGS = $(subst ','\'',$(ASCIIDOC_COMMON):$(ASCIIDOC_HTML):$(ASCIIDOC_DOCBOOK)) @@ -341,6 +343,7 @@ clean: $(RM) SubmittingPatches.txt $(RM) $(cmds_txt) $(mergetools_txt) *.made $(RM) GIT-ASCIIDOCFLAGS + $(RM) asciidoc.conf asciidoctor-extensions.rb docinfo.html: docinfo-html.in $(QUIET_GEN)$(RM) $@ && cat $< >$@ @@ -364,7 +367,7 @@ manpage-cmd = $(QUIET_XMLTO)$(XMLTO) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< %.xml : %.txt $(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.txt user-manual.conf $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_XML) -d book -o $@ $< technical/api-index.txt: technical/api-index-skel.txt \ @@ -373,7 +376,7 @@ technical/api-index.txt: technical/api-index-skel.txt \ technical/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../ $(patsubst %,%.html,$(API_DOCS) technical/api-index $(TECH_DOCS)): %.html : %.txt \ - asciidoc.conf GIT-ASCIIDOCFLAGS + $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.txt SubmittingPatches.txt: SubmittingPatches @@ -416,13 +419,13 @@ $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml howto-index.txt: howto-index.sh $(HOWTO_TXT) $(QUIET_GEN)'$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(HOWTO_TXT)) >$@ -$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt +$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC)$(TXT_TO_HTML) $*.txt 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 %.txt,%.html,$(HOWTO_TXT)): %.html : %.txt $(ASCIIDOC_DEPS) $(QUIET_ASCIIDOC) \ sed -e '1,/^$$/d' $< | \ $(TXT_TO_HTML) - >$@ diff --git a/Documentation/RelNotes/2.45.0.txt b/Documentation/RelNotes/2.45.0.txt index fec193679f..aa0315259b 100644 --- a/Documentation/RelNotes/2.45.0.txt +++ b/Documentation/RelNotes/2.45.0.txt @@ -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.46.0.txt b/Documentation/RelNotes/2.46.0.txt index b25475918a..c06a04a91b 100644 --- a/Documentation/RelNotes/2.46.0.txt +++ b/Documentation/RelNotes/2.46.0.txt @@ -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.2.txt b/Documentation/RelNotes/2.46.2.txt new file mode 100644 index 0000000000..613386878d --- /dev/null +++ b/Documentation/RelNotes/2.46.2.txt @@ -0,0 +1,23 @@ +Git 2.46.2 Release Notes +======================== + +This release is primarily to merge changes to unbreak the 32-bit +GitHub actions jobs we use for CI testing, so that we can release +real fixes for the 2.46.x track after they pass CI. + +It also reverts the "git patch-id" change that went into 2.46.1, +as it seems to have got a regression reported (I haven't verified, +but it is better to keep a known breakage than adding an unintended +regression). + +Other than that, a handful of minor bugfixes are included. + + * In a few corner cases "git diff --exit-code" failed to report + "changes" (e.g., renamed without any content change), which has + been corrected. + + * Cygwin does have /dev/tty support that is needed by things like + single-key input mode. + + * The interpret-trailers command failed to recognise the end of the + message when the commit log ends in an incomplete line. diff --git a/Documentation/RelNotes/2.47.0.txt b/Documentation/RelNotes/2.47.0.txt index ffc0c5c4a2..b63c3364af 100644 --- a/Documentation/RelNotes/2.47.0.txt +++ b/Documentation/RelNotes/2.47.0.txt @@ -65,6 +65,9 @@ UI, Workflows & Features to discourage its use by interactive users. Add documentation to help tool writers. + * "git apply --3way" learned to take "--ours" and other options. + + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -133,6 +136,37 @@ Performance, Internal Implementation, Development Support etc. * "git cat-file" works well with the sparse-index, and gets marked as such. + * CI started failing completely for linux32 jobs, as the step to + upload failed test directory uses GitHub actions that is deprecated + and is now disabled. + + * Import clar unit tests framework libgit2 folks invented for our + use. + + * The error messages from the test script checker have been improved. + + * The convention to calling into built-in command implementation has + been updated to pass the repository, if known, together with the + prefix value. + + * "git apply" had custom buffer management code that predated before + use of strbuf got widespread, which has been updated to use strbuf, + which also plugged some memory leaks. + + * The reftable backend learned to more efficiently handle exclude + patterns while enumerating the refs. + + * CI updates. FreeBSD image has been updated to 13.4. + (merge 2eeb29702e cb/ci-freebsd-13-4 later to maint). + + * 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 ----------------- @@ -228,16 +262,81 @@ Fixes since v2.46 * In a few corner cases "git diff --exit-code" failed to report "changes" (e.g., renamed without any content change), which has been corrected. - (merge 11591850dd rs/diff-exit-code-fix later to maint). * Cygwin does have /dev/tty support that is needed by things like single-key input mode. - (merge 39ba986b0e rj/cygwin-has-dev-tty later to maint). * The interpret-trailers command failed to recognise the end of the message when the commit log ends in an incomplete line. - (merge c02414a997 bl/trailers-and-incomplete-last-line-fix later to maint). + + * "git rebase --autostash" failed to resurrect the autostashed + changes when the command gets aborted after giving back control + asking for hlep in conflict resolution. + (merge bf6ab087d1 pw/rebase-autostash-fix later to maint). + + * The "imap-send" now allows to be compiled with NO_OPENSSL and + OPENSSL_SHA1 defined together. + (merge 997950a750 jk/no-openssl-with-openssl-sha1 later to maint). + + * The support to customize build options to adjust for older versions + and/or older systems for the interop tests has been improved. + (merge 22ef5f02a8 jk/interop-test-build-options later to maint). + + * Update the character width table for Unicode 16. + (merge 44dc651132 bb/unicode-width-table-16 later to maint). + + * In Git 2.39, Git.pm stopped working in a bare repository, which has + been corrected. + (merge d3edb0bdde jk/git-pm-bare-repo-fix later to maint). + + * When a remote-helper dies before Git writes to it, SIGPIPE killed + Git silently. We now explain the situation a bit better to the end + user in our error message. + (merge 6e7fac9bca jk/diag-unexpected-remote-helper-death later to maint). + + * A few usability fixes to "git jump" (in contrib/). + (merge 083b82544d jk/jump-quickfix-fixes later to maint). + + * "git diff --exit-code" ignored modified binary files, which has + been corrected. + (merge 9a41735af6 rs/diff-exit-code-binary later to maint). + + * When a subprocess to work in a submodule spawned by "git submodule" + fails with SIGPIPE, the parent Git process caught the death of it, + but gave a generic "failed to work in that submodule", which was + misleading. We now behave as if the parent got SIGPIPE and die. + (merge 082caf527e pw/submodule-process-sigpipe later to maint). + + * "git archive" with pathspec magic that uses the attribute + information did not work well, which has been corrected. + (merge 296743a7ca rs/archive-with-attr-pathspec-fix later to maint). + + * Background tasks "git maintenance" runs may need to use credential + information when going over the network, but a credential helper + may work only in an interactive environment, and end up blocking a + scheduled task waiting for UI. Credential helpers can now behave + differently when they are not running interactively. + (merge b9183b0a02 ds/background-maintenance-with-credential later to maint). + + * "git --git-dir=nowhere cmd" failed to properly notice that it + 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 9a36ea37ae jc/doc-skip-fetch-all-and-prefetch later to maint). + (merge 4460e052e0 jc/range-diff-lazy-setup later to maint). + (merge 0627c58e7a ak/typofixes later to maint). + (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.txt b/Documentation/RelNotes/2.47.1.txt new file mode 100644 index 0000000000..39206c09fd --- /dev/null +++ b/Documentation/RelNotes/2.47.1.txt @@ -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.48.0.txt b/Documentation/RelNotes/2.48.0.txt new file mode 100644 index 0000000000..cc752d5466 --- /dev/null +++ b/Documentation/RelNotes/2.48.0.txt @@ -0,0 +1,291 @@ +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". + + +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 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. Turn this linkage to relative paths. + + * 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. + + * Updates the '.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 taken valid but something 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. + + * Isolates 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 for us 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. + + +Fixes since v2.47 +----------------- + + * Doc update to clarify how periodical maintenance are scheduled, + spread across time to avoid thundering hurds. + + * 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. + + * 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 it around 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 + as such a tag will be confusing in the context of 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). + + * 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/SubmittingPatches b/Documentation/SubmittingPatches index d8a8caa791..db17bc7fe2 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]] diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf deleted file mode 100644 index 60f76f43ed..0000000000 --- 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 0000000000..dbe36a52ea --- /dev/null +++ b/Documentation/asciidoc.conf.in @@ -0,0 +1,82 @@ +## 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::backend-docbook[] +[linkgit-inlinemacro] +{0%{target}} +{0#<citerefentry>} +{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>} +{0#</citerefentry>} + +[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 d906a00803..0000000000 --- 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 0000000000..c4c200dace --- /dev/null +++ b/Documentation/asciidoctor-extensions.rb.in @@ -0,0 +1,131 @@ +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' + new_tags = "" \ + "<refmiscinfo class=\"source\">@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/build-docdep.perl b/Documentation/build-docdep.perl index 1b3ac8fdd9..315efaa2fa 100755 --- a/Documentation/build-docdep.perl +++ b/Documentation/build-docdep.perl @@ -1,5 +1,6 @@ #!/usr/bin/perl +my ($build_dir) = @ARGV; my %include = (); my %included = (); @@ -10,6 +11,7 @@ for my $text (<*.txt>) { chomp; s/^include::\s*//; s/\[\]//; + s/{build_dir}/${build_dir}/; $include{$text}{$_} = 1; $included{$_} = 1; } diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl index 755a110bc4..e260a98977 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.txt"; 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.txt"; 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.txt"; } 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/; } @@ -63,17 +64,17 @@ close IN; for my $out (@categories) { my ($cat) = $out =~ /^cmds-(.*)\.txt$/; - open O, '>', "$out+" or die "Cannot open output file $out+"; + 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/add.txt b/Documentation/config/add.txt index 4d753f006e..7497533cbc 100644 --- a/Documentation/config/add.txt +++ b/Documentation/config/add.txt @@ -1,7 +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. 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. +`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/core.txt b/Documentation/config/core.txt index 60ca9f2b68..8f6d8e7754 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -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.txt index 0221c3e620..470482ff4c 100644 --- a/Documentation/config/credential.txt +++ b/Documentation/config/credential.txt @@ -9,6 +9,14 @@ credential.helper:: Note that multiple helpers may be defined. See linkgit:gitcredentials[7] for details and examples. +credential.interactive:: + By default, Git and any configured credential helpers will ask for + user input when new credentials are required. Many of these helpers + will succeed based on stored credentials if those credentials are + still valid. To avoid the possibility of user interactivity from + Git, set `credential.interactive=false`. Some credential helpers + respect this option as well. + credential.useHttpPath:: When acquiring credentials, consider the "path" component of an http or https URL to be important. Defaults to false. See diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt index 190bda17e5..fdae13a212 100644 --- a/Documentation/config/diff.txt +++ b/Documentation/config/diff.txt @@ -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,117 @@ 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[] +include::{build_dir}/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 +242,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 +251,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/extensions.txt b/Documentation/config/extensions.txt index 38dce3df35..5cb4721a0e 100644 --- a/Documentation/config/extensions.txt +++ b/Documentation/config/extensions.txt @@ -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:: +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`). ++ +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: + include::../ref-storage-format.txt[] -+ -It is an error to specify this key unless `core.repositoryFormatVersion` is 1. + + Note that this setting should only be set by linkgit:git-init[1] or linkgit:git-clone[1]. Trying to change it after initialization will not work and will produce hard-to-diagnose issues. -extensions.worktreeConfig:: +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/gc.txt b/Documentation/config/gc.txt index 1d4f9470ea..21d56db279 100644 --- a/Documentation/config/gc.txt +++ b/Documentation/config/gc.txt @@ -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/merge.txt b/Documentation/config/merge.txt index 8851b6cede..82554d65a0 100644 --- a/Documentation/config/merge.txt +++ b/Documentation/config/merge.txt @@ -101,7 +101,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.txt[] merge.verbosity:: Controls the amount of output shown by the recursive merge diff --git a/Documentation/config/reftable.txt b/Documentation/config/reftable.txt index 0515727977..57087803a5 100644 --- a/Documentation/config/reftable.txt +++ b/Documentation/config/reftable.txt @@ -46,3 +46,11 @@ reftable.geometricFactor:: By default, the geometric sequence uses a factor of 2, meaning that for any table, the next-biggest table must at least be twice as big. A maximum factor of 256 is supported. + +reftable.lockTimeout:: + Whenever the reftable backend appends a new table to the stack, it has + to lock the central "tables.list" file before updating it. This config + controls how long the process will wait to acquire the lock in case + another process has already acquired it. Value 0 means not to retry at + all; -1 means to try indefinitely. Default is 100 (i.e., retry for + 100ms). diff --git a/Documentation/config/remote.txt b/Documentation/config/remote.txt index 36e771556c..4118c219c1 100644 --- a/Documentation/config/remote.txt +++ b/Documentation/config/remote.txt @@ -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. + +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, but will not touch an + already existing local reference. Setting to "warn" will print + a message if the remote has a different value, than the local one and + 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 to "always" will silently update it to the value on the remote. + Finally, setting it to "never" will never change or create the local + reference. ++ +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`). diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt index 6a869d67eb..5ffcfc9f2a 100644 --- a/Documentation/config/sendemail.txt +++ b/Documentation/config/sendemail.txt @@ -30,6 +30,21 @@ sendemail.confirm:: in the linkgit:git-send-email[1] documentation for the meaning of these values. +sendemail.mailmap:: + If true, makes linkgit:git-send-email[1] assume `--mailmap`, + otherwise assume `--no-mailmap`. False by default. + +sendemail.mailmap.file:: + The location of a linkgit:git-send-email[1] specific augmenting + mailmap file. The default mailmap and `mailmap.file` are loaded + first. Thus, entries in this file take precedence over entries in + the default mailmap locations. See linkgit:gitmailmap[5]. + +sendemail.mailmap.blob:: + Like `sendemail.mailmap.file`, but consider the value as a reference + to a blob in the repository. Entries in `sendemail.mailmap.file` + take precedence over entries here. See linkgit:gitmailmap[5]. + sendemail.aliasesFile:: To avoid typing long email addresses, point this to one or more email aliases files. You must also supply `sendemail.aliasFileType`. diff --git a/Documentation/config/uploadpack.txt b/Documentation/config/uploadpack.txt index 16264d82a7..0e1dda944a 100644 --- a/Documentation/config/uploadpack.txt +++ b/Documentation/config/uploadpack.txt @@ -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/worktree.txt b/Documentation/config/worktree.txt index 048e349482..5e35c7d018 100644 --- a/Documentation/config/worktree.txt +++ b/Documentation/config/worktree.txt @@ -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/diff-format.txt b/Documentation/diff-format.txt index a3ae8747a2..c72fb37986 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -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: @@ -128,7 +128,7 @@ 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.txt index 4b5aa5c2e0..e5c813c96f 100644 --- a/Documentation/diff-generate-patch.txt +++ b/Documentation/diff-generate-patch.txt @@ -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.txt index cd0b81adbb..640eb6e7db 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -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/fetch-options.txt b/Documentation/fetch-options.txt index 80838fe37e..b01372e4b3 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -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.txt index 68a2801f15..b14bc44ca4 100644 --- a/Documentation/fsck-msgids.txt +++ b/Documentation/fsck-msgids.txt @@ -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 0000000000..6700498b93 --- /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.txt index aceaa025e3..5f2c3592b8 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -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. @@ -439,6 +439,7 @@ CONFIGURATION include::includes/cmd-config-section-all.txt[] +:git-add: 1 include::config/add.txt[] SEE ALSO diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index 9cce68a38b..dd4a61ef28 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -9,7 +9,8 @@ git-apply - Apply a patch to files and/or to the index SYNOPSIS -------- [verse] -'git apply' [--stat] [--numstat] [--summary] [--check] [--index | --intent-to-add] [--3way] +'git apply' [--stat] [--numstat] [--summary] [--check] + [--index | --intent-to-add] [--3way] [--ours | --theirs | --union] [--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse] [--allow-binary-replacement | --binary] [--reject] [-z] [-p<n>] [-C<n>] [--inaccurate-eof] [--recount] [--cached] @@ -92,6 +93,12 @@ OPTIONS When used with the `--cached` option, any conflicts are left at higher stages in the cache. +--ours:: +--theirs:: +--union:: + Instead of leaving conflicts in the file, resolve conflicts favouring + our (or their or both) side of the lines. Requires --3way. + --build-fake-ancestor=<file>:: Newer 'git diff' output has embedded 'index information' for each blob to help identify the original version that diff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt index 3ab42a19ca..03cd36fe8d 100644 --- a/Documentation/git-bundle.txt +++ b/Documentation/git-bundle.txt @@ -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-checkout.txt b/Documentation/git-checkout.txt index 8bdfa54ab0..bf26655764 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -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:: diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 8e925db7e9..de8d8f5893 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -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,11 +214,11 @@ 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. `-u` _<upload-pack>_:: @@ -221,12 +227,12 @@ objects from the source repository into a pack in the cloned repository. 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 +245,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. @@ -279,13 +285,13 @@ 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,23 +301,23 @@ 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: + @@ -334,7 +340,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/*` @@ -381,6 +387,12 @@ $ 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 ------------- diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 7f81fbbea8..3e420177c1 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -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>] diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt index c065f023ec..e19f31e8b9 100644 --- a/Documentation/git-diff.txt +++ b/Documentation/git-diff.txt @@ -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. @@ -125,22 +125,31 @@ 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. +`-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:: +`-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). @@ -225,11 +234,12 @@ CONFIGURATION include::includes/cmd-config-section-all.txt[] +:git-diff: 1 include::config/diff.txt[] SEE ALSO -------- -diff(1), +`diff`(1), linkgit:git-difftool[1], linkgit:git-log[1], linkgit:gitdiffcore[7], diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt index b3467664d3..b5223576a7 100644 --- a/Documentation/git-fetch-pack.txt +++ b/Documentation/git-fetch-pack.txt @@ -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-format-patch.txt b/Documentation/git-format-patch.txt index 8708b31593..5dc7bb4cfc 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -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-index-pack.txt b/Documentation/git-index-pack.txt index 5a20deefd5..58dd5b5f0e 100644 --- a/Documentation/git-index-pack.txt +++ b/Documentation/git-index-pack.txt @@ -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.txt b/Documentation/git-init.txt index daff93bd16..315f7f7530 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -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>__:: - +`--ref-format=<format>`:: Specify the given ref storage _<format>_ for the repository. The valid values are: + include::ref-storage-format.txt[] -++--template=++__<template-directory>__:: - +`--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 diff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt index 76c86c3ce4..d71c4ab3e2 100644 --- a/Documentation/git-ls-remote.txt +++ b/Documentation/git-ls-remote.txt @@ -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-maintenance.txt b/Documentation/git-maintenance.txt index 9d96819133..6e6651309d 100644 --- a/Documentation/git-maintenance.txt +++ b/Documentation/git-maintenance.txt @@ -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 diff --git a/Documentation/git-merge-tree.txt b/Documentation/git-merge-tree.txt index 84cb2edf6d..0b6a8a19b1 100644 --- a/Documentation/git-merge-tree.txt +++ b/Documentation/git-merge-tree.txt @@ -211,9 +211,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 diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index c9221a68cc..84022f99d7 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -9,9 +9,9 @@ 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' 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>] [<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> @@ -67,7 +67,9 @@ add:: 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 the notes for the first object onto the second object (defaults to @@ -93,6 +95,8 @@ append:: 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). diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 2e6f1d63ae..bc3ef45acb 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -414,6 +414,12 @@ exists when 'git send-email' is asked to add it (especially note that Failure to do so may not produce the expected result in the recipient's MUA. +--[no-]mailmap:: + Use the mailmap file (see linkgit:gitmailmap[5]) to map all + addresses to their canonical real name and email address. Additional + mailmap data specific to git-send-email may be provided using the + `sendemail.mailmap.file` or `sendemail.mailmap.blob` configuration + values. Defaults to `sendemail.mailmap`. Administering ~~~~~~~~~~~~~ diff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt index 761b154bcb..33ca381fde 100644 --- a/Documentation/git-symbolic-ref.txt +++ b/Documentation/git-symbolic-ref.txt @@ -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-update-ref.txt b/Documentation/git-update-ref.txt index afcf33cf60..9e6935d38d 100644 --- a/Documentation/git-update-ref.txt +++ b/Documentation/git-update-ref.txt @@ -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-worktree.txt b/Documentation/git-worktree.txt index 2a240f53ba..8340b7f028 100644 --- a/Documentation/git-worktree.txt +++ b/Documentation/git-worktree.txt @@ -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.txt b/Documentation/git.txt index d15a869762..81498393af 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -245,17 +245,17 @@ ancillary user utilities. Main porcelain commands ~~~~~~~~~~~~~~~~~~~~~~~ -include::cmds-mainporcelain.txt[] +include::{build_dir}/cmds-mainporcelain.txt[] Ancillary Commands ~~~~~~~~~~~~~~~~~~ Manipulators: -include::cmds-ancillarymanipulators.txt[] +include::{build_dir}/cmds-ancillarymanipulators.txt[] Interrogators: -include::cmds-ancillaryinterrogators.txt[] +include::{build_dir}/cmds-ancillaryinterrogators.txt[] 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.txt[] Reset, restore and revert ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -313,13 +313,13 @@ repositories. Manipulation commands ~~~~~~~~~~~~~~~~~~~~~ -include::cmds-plumbingmanipulators.txt[] +include::{build_dir}/cmds-plumbingmanipulators.txt[] Interrogation commands ~~~~~~~~~~~~~~~~~~~~~~ -include::cmds-plumbinginterrogators.txt[] +include::{build_dir}/cmds-plumbinginterrogators.txt[] 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.txt[] 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.txt[] 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.txt[] Guides ------ The following documentation pages are guides about Git concepts. -include::cmds-guide.txt[] +include::{build_dir}/cmds-guide.txt[] 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.txt[] 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.txt[] Configuration Mechanism ----------------------- @@ -477,6 +477,14 @@ their values the same way as Boolean valued configuration variables, e.g. 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/gitcli.txt b/Documentation/gitcli.txt index 7c709324ba..bd62cbd043 100644 --- a/Documentation/gitcli.txt +++ b/Documentation/gitcli.txt @@ -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 diff --git a/Documentation/gitcredentials.txt b/Documentation/gitcredentials.txt index 71dd19731a..35a7452c8f 100644 --- a/Documentation/gitcredentials.txt +++ b/Documentation/gitcredentials.txt @@ -242,6 +242,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/gitformat-commit-graph.txt b/Documentation/gitformat-commit-graph.txt index 3e906e8030..14d1631234 100644 --- a/Documentation/gitformat-commit-graph.txt +++ b/Documentation/gitformat-commit-graph.txt @@ -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/gitprotocol-v2.txt b/Documentation/gitprotocol-v2.txt index 414bc625d5..1652fef3ae 100644 --- a/Documentation/gitprotocol-v2.txt +++ b/Documentation/gitprotocol-v2.txt @@ -527,8 +527,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,7 +776,7 @@ 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. diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index 949cd8a31e..fa8b51daf0 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -298,6 +298,7 @@ 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/gitweb.txt b/Documentation/gitweb.txt index 56d24a30a3..5e2b491ec2 100644 --- a/Documentation/gitweb.txt +++ b/Documentation/gitweb.txt @@ -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/glossary-content.txt b/Documentation/glossary-content.txt index 42afe04869..575c18f776 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -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/keep-canonical-history-correct.txt b/Documentation/howto/keep-canonical-history-correct.txt index 5f800fd85a..e98f03275e 100644 --- a/Documentation/howto/keep-canonical-history-correct.txt +++ b/Documentation/howto/keep-canonical-history-correct.txt @@ -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.txt index da31332f11..45e2599c5d 100644 --- a/Documentation/howto/maintain-git.txt +++ b/Documentation/howto/maintain-git.txt @@ -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/meson.build b/Documentation/meson.build new file mode 100644 index 0000000000..f2426ccaa3 --- /dev/null +++ b/Documentation/meson.build @@ -0,0 +1,324 @@ +manpages = { + # Category 1. + 'git-add.txt' : 1, + 'git-am.txt' : 1, + 'git-annotate.txt' : 1, + 'git-apply.txt' : 1, + 'git-archimport.txt' : 1, + 'git-archive.txt' : 1, + 'git-bisect.txt' : 1, + 'git-blame.txt' : 1, + 'git-branch.txt' : 1, + 'git-bugreport.txt' : 1, + 'git-bundle.txt' : 1, + 'git-cat-file.txt' : 1, + 'git-check-attr.txt' : 1, + 'git-check-ignore.txt' : 1, + 'git-check-mailmap.txt' : 1, + 'git-checkout-index.txt' : 1, + 'git-checkout.txt' : 1, + 'git-check-ref-format.txt' : 1, + 'git-cherry-pick.txt' : 1, + 'git-cherry.txt' : 1, + 'git-citool.txt' : 1, + 'git-clean.txt' : 1, + 'git-clone.txt' : 1, + 'git-column.txt' : 1, + 'git-commit-graph.txt' : 1, + 'git-commit-tree.txt' : 1, + 'git-commit.txt' : 1, + 'git-config.txt' : 1, + 'git-count-objects.txt' : 1, + 'git-credential-cache--daemon.txt' : 1, + 'git-credential-cache.txt' : 1, + 'git-credential-store.txt' : 1, + 'git-credential.txt' : 1, + 'git-cvsexportcommit.txt' : 1, + 'git-cvsimport.txt' : 1, + 'git-cvsserver.txt' : 1, + 'git-daemon.txt' : 1, + 'git-describe.txt' : 1, + 'git-diagnose.txt' : 1, + 'git-diff-files.txt' : 1, + 'git-diff-index.txt' : 1, + 'git-difftool.txt' : 1, + 'git-diff-tree.txt' : 1, + 'git-diff.txt' : 1, + 'git-fast-export.txt' : 1, + 'git-fast-import.txt' : 1, + 'git-fetch-pack.txt' : 1, + 'git-fetch.txt' : 1, + 'git-filter-branch.txt' : 1, + 'git-fmt-merge-msg.txt' : 1, + 'git-for-each-ref.txt' : 1, + 'git-for-each-repo.txt' : 1, + 'git-format-patch.txt' : 1, + 'git-fsck-objects.txt' : 1, + 'git-fsck.txt' : 1, + 'git-fsmonitor--daemon.txt' : 1, + 'git-gc.txt' : 1, + 'git-get-tar-commit-id.txt' : 1, + 'git-grep.txt' : 1, + 'git-gui.txt' : 1, + 'git-hash-object.txt' : 1, + 'git-help.txt' : 1, + 'git-hook.txt' : 1, + 'git-http-backend.txt' : 1, + 'git-http-fetch.txt' : 1, + 'git-http-push.txt' : 1, + 'git-imap-send.txt' : 1, + 'git-index-pack.txt' : 1, + 'git-init-db.txt' : 1, + 'git-init.txt' : 1, + 'git-instaweb.txt' : 1, + 'git-interpret-trailers.txt' : 1, + 'git-log.txt' : 1, + 'git-ls-files.txt' : 1, + 'git-ls-remote.txt' : 1, + 'git-ls-tree.txt' : 1, + 'git-mailinfo.txt' : 1, + 'git-mailsplit.txt' : 1, + 'git-maintenance.txt' : 1, + 'git-merge-base.txt' : 1, + 'git-merge-file.txt' : 1, + 'git-merge-index.txt' : 1, + 'git-merge-one-file.txt' : 1, + 'git-mergetool--lib.txt' : 1, + 'git-mergetool.txt' : 1, + 'git-merge-tree.txt' : 1, + 'git-merge.txt' : 1, + 'git-mktag.txt' : 1, + 'git-mktree.txt' : 1, + 'git-multi-pack-index.txt' : 1, + 'git-mv.txt' : 1, + 'git-name-rev.txt' : 1, + 'git-notes.txt' : 1, + 'git-p4.txt' : 1, + 'git-pack-objects.txt' : 1, + 'git-pack-redundant.txt' : 1, + 'git-pack-refs.txt' : 1, + 'git-patch-id.txt' : 1, + 'git-prune-packed.txt' : 1, + 'git-prune.txt' : 1, + 'git-pull.txt' : 1, + 'git-push.txt' : 1, + 'git-quiltimport.txt' : 1, + 'git-range-diff.txt' : 1, + 'git-read-tree.txt' : 1, + 'git-rebase.txt' : 1, + 'git-receive-pack.txt' : 1, + 'git-reflog.txt' : 1, + 'git-refs.txt' : 1, + 'git-remote-ext.txt' : 1, + 'git-remote-fd.txt' : 1, + 'git-remote.txt' : 1, + 'git-repack.txt' : 1, + 'git-replace.txt' : 1, + 'git-replay.txt' : 1, + 'git-request-pull.txt' : 1, + 'git-rerere.txt' : 1, + 'git-reset.txt' : 1, + 'git-restore.txt' : 1, + 'git-revert.txt' : 1, + 'git-rev-list.txt' : 1, + 'git-rev-parse.txt' : 1, + 'git-rm.txt' : 1, + 'git-send-email.txt' : 1, + 'git-send-pack.txt' : 1, + 'git-shell.txt' : 1, + 'git-sh-i18n--envsubst.txt' : 1, + 'git-sh-i18n.txt' : 1, + 'git-shortlog.txt' : 1, + 'git-show-branch.txt' : 1, + 'git-show-index.txt' : 1, + 'git-show-ref.txt' : 1, + 'git-show.txt' : 1, + 'git-sh-setup.txt' : 1, + 'git-sparse-checkout.txt' : 1, + 'git-stage.txt' : 1, + 'git-stash.txt' : 1, + 'git-status.txt' : 1, + 'git-stripspace.txt' : 1, + 'git-submodule.txt' : 1, + 'git-svn.txt' : 1, + 'git-switch.txt' : 1, + 'git-symbolic-ref.txt' : 1, + 'git-tag.txt' : 1, + 'git-unpack-file.txt' : 1, + 'git-unpack-objects.txt' : 1, + 'git-update-index.txt' : 1, + 'git-update-ref.txt' : 1, + 'git-update-server-info.txt' : 1, + 'git-upload-archive.txt' : 1, + 'git-upload-pack.txt' : 1, + 'git-var.txt' : 1, + 'git-verify-commit.txt' : 1, + 'git-verify-pack.txt' : 1, + 'git-verify-tag.txt' : 1, + 'git-version.txt' : 1, + 'git-web--browse.txt' : 1, + 'git-whatchanged.txt' : 1, + 'git-worktree.txt' : 1, + 'git-write-tree.txt' : 1, + 'git.txt' : 1, + 'gitk.txt' : 1, + 'gitweb.txt' : 1, + 'scalar.txt' : 1, + + # Category 5. + 'gitattributes.txt' : 5, + 'gitformat-bundle.txt' : 5, + 'gitformat-chunk.txt' : 5, + 'gitformat-commit-graph.txt' : 5, + 'gitformat-index.txt' : 5, + 'gitformat-pack.txt' : 5, + 'gitformat-signature.txt' : 5, + 'githooks.txt' : 5, + 'gitignore.txt' : 5, + 'gitmailmap.txt' : 5, + 'gitmodules.txt' : 5, + 'gitprotocol-capabilities.txt' : 5, + 'gitprotocol-common.txt' : 5, + 'gitprotocol-http.txt' : 5, + 'gitprotocol-pack.txt' : 5, + 'gitprotocol-v2.txt' : 5, + 'gitrepository-layout.txt' : 5, + 'gitweb.conf.txt' : 5, + + # Category 7. + 'gitcli.txt' : 7, + 'gitcore-tutorial.txt' : 7, + 'gitcredentials.txt' : 7, + 'gitcvs-migration.txt' : 7, + 'gitdiffcore.txt' : 7, + 'giteveryday.txt' : 7, + 'gitfaq.txt' : 7, + 'gitglossary.txt' : 7, + 'gitpacking.txt' : 7, + 'gitnamespaces.txt' : 7, + 'gitremote-helpers.txt' : 7, + 'gitrevisions.txt' : 7, + 'gitsubmodules.txt' : 7, + 'gittutorial-2.txt' : 7, + 'gittutorial.txt' : 7, + 'gitworkflows.txt' : 7, +} + +asciidoc = find_program('asciidoc') +git = find_program('git', required: false) +xmlto = find_program('xmlto') + +asciidoc_conf = custom_target( + command: [ + shell, + meson.project_source_root() / 'GIT-VERSION-GEN', + meson.project_source_root(), + '@INPUT@', + '@OUTPUT@', + ], + input: meson.current_source_dir() / 'asciidoc.conf.in', + output: 'asciidoc.conf', + depends: [git_version_file], +) + +asciidoc_common_options = [ + asciidoc, + '--conf-file=' + asciidoc_conf.full_path(), + '--attribute=build_dir=' + meson.current_build_dir(), +] + +cmd_lists = [ + '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', +] + +documentation_deps = [ + asciidoc_conf, +] + +documentation_deps += custom_target( + command: [ + perl, + meson.current_source_dir() / 'cmd-list.perl', + meson.project_source_root(), + meson.current_build_dir(), + ] + cmd_lists, + output: cmd_lists +) + +foreach mode : [ 'diff', 'merge' ] + documentation_deps += custom_target( + command: [ + shell, + meson.current_source_dir() / 'generate-mergetool-list.sh', + '..', + 'diff', + '@OUTPUT@' + ], + env: [ + 'MERGE_TOOLS_DIR=' + meson.project_source_root() / 'mergetools', + 'TOOL_MODE=' + mode, + ], + output: 'mergetools-' + mode + '.txt', + ) +endforeach + +foreach manpage, category : manpages + if get_option('docs').contains('man') + manpage_xml_target = custom_target( + command: asciidoc_common_options + [ + '--backend=docbook', + '--doctype=manpage', + '--out-file=@OUTPUT@', + meson.current_source_dir() / manpage, + ], + depends: documentation_deps, + output: fs.stem(manpage) + '.xml', + ) + + manpage_path = fs.stem(manpage) + '.' + category.to_string() + manpage_target = custom_target( + command: [ + xmlto, + '-m', + meson.current_source_dir() / 'manpage-normal.xsl', + '-m', + meson.current_source_dir() / 'manpage-bold-literal.xsl', + '--stringparam', + 'man.base.url.for.relative.links=' + get_option('prefix') / get_option('mandir'), + 'man', + manpage_xml_target, + '-o', + meson.current_build_dir(), + ], + output: manpage_path, + install: true, + install_dir: get_option('mandir') / 'man' + category.to_string(), + ) + endif + + if get_option('docs').contains('html') and category == 1 + custom_target( + command: asciidoc_common_options + [ + '--backend=xhtml11', + '--doctype=manpage', + '--out-file=@OUTPUT@', + meson.current_source_dir() / manpage, + ], + depends: documentation_deps, + output: fs.stem(manpage) + '.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) + endif +endforeach diff --git a/Documentation/pull-fetch-param.txt b/Documentation/pull-fetch-param.txt index c718f7946f..d79d2f6065 100644 --- a/Documentation/pull-fetch-param.txt +++ b/Documentation/pull-fetch-param.txt @@ -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/rev-list-options.txt b/Documentation/rev-list-options.txt index 00ccf68744..459e5a02f5 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -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 diff --git a/Documentation/technical/build-systems.txt b/Documentation/technical/build-systems.txt new file mode 100644 index 0000000000..d9dafb407c --- /dev/null +++ b/Documentation/technical/build-systems.txt @@ -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/hash-function-transition.txt b/Documentation/technical/hash-function-transition.txt index ed57481089..7102c7c8f5 100644 --- a/Documentation/technical/hash-function-transition.txt +++ b/Documentation/technical/hash-function-transition.txt @@ -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 diff --git a/Documentation/technical/partial-clone.txt b/Documentation/technical/partial-clone.txt index cd948b0072..bf5ec5c82d 100644 --- a/Documentation/technical/partial-clone.txt +++ b/Documentation/technical/partial-clone.txt @@ -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.txt index a227c363d7..0a2fb28d62 100644 --- a/Documentation/technical/platform-support.txt +++ b/Documentation/technical/platform-support.txt @@ -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/repository-version.txt b/Documentation/technical/repository-version.txt index 47281420fc..b9bb81a81f 100644 --- a/Documentation/technical/repository-version.txt +++ b/Documentation/technical/repository-version.txt @@ -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/sparse-checkout.txt b/Documentation/technical/sparse-checkout.txt index fa0d01cbda..d968659354 100644 --- a/Documentation/technical/sparse-checkout.txt +++ b/Documentation/technical/sparse-checkout.txt @@ -287,7 +287,7 @@ everything behaves like a dense checkout with a few exceptions (e.g. branch checkouts and switches write fewer things, knowing the VFS will lazily write the rest on an as-needed basis). -Since there is no publically available VFS-related code for folks to try, +Since there is no publicly available VFS-related code for folks to try, the number of folks who can test such a usecase is limited. The primary reason to note the Behavior C usecase is that as we fix things diff --git a/Documentation/technical/unit-tests.txt b/Documentation/technical/unit-tests.txt index 206037ffb1..5a432b7b29 100644 --- a/Documentation/technical/unit-tests.txt +++ b/Documentation/technical/unit-tests.txt @@ -203,6 +203,7 @@ GitHub / GitLab stars to estimate this. :criterion: https://github.com/Snaipe/Criterion[Criterion] :c-tap: https://github.com/rra/c-tap-harness/[C TAP] :check: https://libcheck.github.io/check/[Check] +:clar: https://github.com/clar-test/clar[Clar] [format="csv",options="header",width="33%",subs="specialcharacters,attributes,quotes,macros"] |===== @@ -212,6 +213,7 @@ Framework,"<<license,License>>","<<vendorable-or-ubiquitous,Vendorable or ubiqui {criterion},{mit},{false},{partial},{true},{true},{true},{true},{true},{false},{true},19,1800 {c-tap},{expat},{true},{partial},{partial},{true},{false},{true},{false},{false},{false},4,33 {check},{lgpl},{false},{partial},{true},{true},{true},{false},{false},{false},{true},17,973 +{clar},{isc},{false},{partial},{true},{true},{true},{true},{false},{false},{true},1,192 |===== === Additional framework candidates diff --git a/Documentation/urls.txt b/Documentation/urls.txt index 7cec85aef1..9c871e716a 100644 --- a/Documentation/urls.txt +++ b/Documentation/urls.txt @@ -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/GIT-BUILD-OPTIONS.in b/GIT-BUILD-OPTIONS.in new file mode 100644 index 0000000000..f651116102 --- /dev/null +++ b/GIT-BUILD-OPTIONS.in @@ -0,0 +1,47 @@ +SHELL_PATH=@SHELL_PATH@ +TEST_SHELL_PATH=@TEST_SHELL_PATH@ +PERL_PATH=@PERL_PATH@ +PERL_LOCALEDIR=@PERL_LOCALEDIR@ +NO_PERL_CPAN_FALLBACKS=@NO_PERL_CPAN_FALLBACKS@ +DIFF=@DIFF@ +PYTHON_PATH=@PYTHON_PATH@ +TAR=@TAR@ +NO_CURL=@NO_CURL@ +NO_ICONV=@NO_ICONV@ +NO_EXPAT=@NO_EXPAT@ +USE_LIBPCRE2=@USE_LIBPCRE2@ +NO_PERL=@NO_PERL@ +NO_PTHREADS=@NO_PTHREADS@ +NO_PYTHON=@NO_PYTHON@ +NO_REGEX=@NO_REGEX@ +NO_UNIX_SOCKETS=@NO_UNIX_SOCKETS@ +PAGER_ENV=@PAGER_ENV@ +SANITIZE_LEAK=@SANITIZE_LEAK@ +SANITIZE_ADDRESS=@SANITIZE_ADDRESS@ +X=@X@ +FSMONITOR_DAEMON_BACKEND=@FSMONITOR_DAEMON_BACKEND@ +FSMONITOR_OS_SETTINGS=@FSMONITOR_OS_SETTINGS@ +TEST_OUTPUT_DIRECTORY=@TEST_OUTPUT_DIRECTORY@ +GIT_TEST_OPTS=@GIT_TEST_OPTS@ +GIT_TEST_CMP=@GIT_TEST_CMP@ +GIT_TEST_CMP_USE_COPIED_CONTEXT=@GIT_TEST_CMP_USE_COPIED_CONTEXT@ +GIT_TEST_UTF8_LOCALE=@GIT_TEST_UTF8_LOCALE@ +NO_GETTEXT=@NO_GETTEXT@ +GIT_PERF_REPEAT_COUNT=@GIT_PERF_REPEAT_COUNT@ +GIT_PERF_REPO=@GIT_PERF_REPO@ +GIT_PERF_LARGE_REPO=@GIT_PERF_LARGE_REPO@ +GIT_PERF_MAKE_OPTS=@GIT_PERF_MAKE_OPTS@ +GIT_PERF_MAKE_COMMAND=@GIT_PERF_MAKE_COMMAND@ +GIT_INTEROP_MAKE_OPTS=@GIT_INTEROP_MAKE_OPTS@ +GIT_TEST_INDEX_VERSION=@GIT_TEST_INDEX_VERSION@ +GIT_TEST_PERL_FATAL_WARNINGS=@GIT_TEST_PERL_FATAL_WARNINGS@ +GIT_TEST_TEXTDOMAINDIR=@GIT_TEST_TEXTDOMAINDIR@ +GIT_TEST_POPATH=@GIT_TEST_POPATH@ +GIT_TEST_TEMPLATE_DIR=@GIT_TEST_TEMPLATE_DIR@ +GIT_TEST_GITPERLLIB=@GIT_TEST_GITPERLLIB@ +GIT_TEST_MERGE_TOOLS_DIR=@GIT_TEST_MERGE_TOOLS_DIR@ +RUNTIME_PREFIX=@RUNTIME_PREFIX@ +GITWEBDIR=@GITWEBDIR@ +USE_GETTEXT_SCHEME=@USE_GETTEXT_SCHEME@ +LOCALEDIR=@LOCALEDIR@ +BROKEN_PATH_FIX=@BROKEN_PATH_FIX@ diff --git a/GIT-VERSION-FILE.in b/GIT-VERSION-FILE.in new file mode 100644 index 0000000000..3789a48a34 --- /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 ee71e9d8aa..de0e63bdfb 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,23 +1,48 @@ #!/bin/sh -GVF=GIT-VERSION-FILE -DEF_VER=v2.46.GIT +DEF_VER=v2.48.0-rc0 LF=' ' +if test "$#" -ne 3 +then + echo >&2 "USAGE: $0 <SOURCE_DIR> <INPUT> <OUTPUT>" + exit 1 +fi + +SOURCE_DIR="$1" +INPUT="$2" +OUTPUT="$3" + +if ! test -f "$INPUT" +then + echo >&2 "Input is not a file: $INPUT" + exit 1 +fi + +# 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 + # First see if there is a version file (included in release tarballs), # then try git-describe, then default. -if test -f version +if test -f "$SOURCE_DIR"/version 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) && + 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 --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 --)" || + git -C "$SOURCE_DIR" update-index -q --refresh + test -z "$(git -C "$SOURCE_DIR" diff-index --name-only HEAD --)" || VN="$VN-dirty" ;; esac then @@ -26,15 +51,34 @@ else VN="$DEF_VER" fi -VN=$(expr "$VN" : v*'\(.*\)') +GIT_VERSION=$(expr "$VN" : v*'\(.*\)') +GIT_BUILT_FROM_COMMIT=$(git -C "$SOURCE_DIR" rev-parse -q --verify HEAD 2>/dev/null) +GIT_DATE=$(git -C "$SOURCE_DIR" show --quiet --format='%as' 2>/dev/null) +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 + +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|" \ + "$INPUT" >"$OUTPUT"+ -if test -r $GVF +if ! test -f "$OUTPUT" || ! cmp "$OUTPUT"+ "$OUTPUT" >/dev/null then - VC=$(sed -e 's/^GIT_VERSION = //' <$GVF) + mv "$OUTPUT"+ "$OUTPUT" else - VC=unset + rm "$OUTPUT"+ fi -test "$VN" = "$VC" || { - echo >&2 "GIT_VERSION = $VN" - echo "GIT_VERSION = $VN" >$GVF -} @@ -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. @@ -521,6 +521,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 @@ -588,7 +592,10 @@ include shared.mak # Disable -pedantic compilation. GIT-VERSION-FILE: FORCE - @$(SHELL_PATH) ./GIT-VERSION-GEN + @OLD=$$(cat $@ 2>/dev/null || :) && \ + $(SHELL_PATH) ./GIT-VERSION-GEN "$(shell pwd)" GIT-VERSION-FILE.in $@ && \ + NEW=$$(cat $@ 2>/dev/null || :) && \ + if test "$$OLD" != "$$NEW"; then echo "$$NEW" >&2; fi -include GIT-VERSION-FILE # Set our default configuration. @@ -915,6 +922,8 @@ REFTABLE_LIB = reftable/libreftable.a GENERATED_H += command-list.h GENERATED_H += config-list.h GENERATED_H += hook-list.h +GENERATED_H += $(UNIT_TEST_DIR)/clar-decls.h +GENERATED_H += $(UNIT_TEST_DIR)/clar.suite .PHONY: generated-hdrs generated-hdrs: $(GENERATED_H) @@ -1332,8 +1341,16 @@ THIRD_PARTY_SOURCES += compat/poll/% THIRD_PARTY_SOURCES += compat/regex/% THIRD_PARTY_SOURCES += sha1collisiondetection/% 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_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 -UNIT_TEST_PROGRAMS += t-ctype UNIT_TEST_PROGRAMS += t-example-decorate UNIT_TEST_PROGRAMS += t-hash UNIT_TEST_PROGRAMS += t-hashmap @@ -1353,7 +1370,6 @@ 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-strvec UNIT_TEST_PROGRAMS += t-trailer UNIT_TEST_PROGRAMS += t-urlmatch-normalization UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS)) @@ -1542,10 +1558,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)) @@ -1988,6 +2004,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 @@ -2388,9 +2425,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) @@ -2471,13 +2511,11 @@ 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)GIT_USER_AGENT="$(GIT_USER_AGENT)" $(SHELL_PATH) ./GIT-VERSION-GEN "$(shell pwd)" $< $@+ + @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi + +version.sp version.s version.o: version-def.h $(BUILT_INS): git$X $(QUIET_BUILT_IN)$(RM) $@ && \ @@ -2488,17 +2526,17 @@ $(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 >$@ + $(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh . $@ command-list.h: generate-cmdlist.sh command-list.txt command-list.h: $(wildcard Documentation/git*.txt) $(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 >$@ + $(QUIET_GEN)$(SHELL_PATH) ./generate-hooklist.sh . $@ SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):\ $(localedir_SQ):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\ @@ -2511,33 +2549,16 @@ 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)$(SHELL_PATH) ./GIT-VERSION-GEN "$(shell pwd)" $< $@+ + @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi -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 @@ -2570,16 +2591,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)) @@ -2595,11 +2608,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 $@+ $@ @@ -2607,15 +2620,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 $@+ $@ @@ -2625,24 +2638,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+ @@ -2688,6 +2697,7 @@ 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 @@ -2715,6 +2725,7 @@ OBJECTS += $(XDIFF_OBJS) OBJECTS += $(FUZZ_OBJS) OBJECTS += $(REFTABLE_OBJS) $(REFTABLE_TEST_OBJS) OBJECTS += $(UNIT_TEST_OBJS) +OBJECTS += $(CLAR_TEST_OBJS) OBJECTS += $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS)) ifndef NO_CURL @@ -3066,13 +3077,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) @@ -3125,79 +3132,66 @@ 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|@SHELL_PATH@|\'$(SHELL_PATH_SQ)\'|" \ + -e "s|@TEST_SHELL_PATH@|\'$(TEST_SHELL_PATH_SQ)\'|" \ + -e "s|@PERL_PATH@|\'$(PERL_PATH_SQ)\'|" \ + -e "s|@PERL_LOCALEDIR@|\'$(perl_localedir_SQ)\'|" \ + -e "s|@NO_PERL_CPAN_FALLBACKS@|\'$(NO_PERL_CPAN_FALLBACKS_SQ)\'|" \ + -e "s|@DIFF@|\'$(DIFF)\'|" \ + -e "s|@PYTHON_PATH@|\'$(PYTHON_PATH_SQ)\'|" \ + -e "s|@TAR@|\'$(TAR)\'|" \ + -e "s|@NO_CURL@|\'$(NO_CURL)\'|" \ + -e "s|@NO_ICONV@|\'$(NO_ICONV)\'|" \ + -e "s|@NO_EXPAT@|\'$(NO_EXPAT)\'|" \ + -e "s|@USE_LIBPCRE2@|\'$(USE_LIBPCRE2)\'|" \ + -e "s|@NO_PERL@|\'$(NO_PERL)\'|" \ + -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|@SANITIZE_LEAK@|\'$(SANITIZE_LEAK)\'|" \ + -e "s|@SANITIZE_ADDRESS@|\'$(SANITIZE_ADDRESS)\'|" \ + -e "s|@X@|\'$(X)\'|" \ + -e "s|@FSMONITOR_DAEMON_BACKEND@|\'$(FSMONITOR_DAEMON_BACKEND)\'|" \ + -e "s|@FSMONITOR_OS_SETTINGS@|\'$(FSMONITOR_OS_SETTINGS)\'|" \ + -e "s|@TEST_OUTPUT_DIRECTORY@|\'$(TEST_OUTPUT_DIRECTORY)\'|" \ + -e "s|@GIT_TEST_OPTS@|\'$(GIT_TEST_OPTS)\'|" \ + -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_UTF8_LOCALE@|\'$(GIT_TEST_UTF8_LOCALE)\'|" \ + -e "s|@NO_GETTEXT@|\'$(NO_GETTEXT)\'|" \ + -e "s|@GIT_PERF_REPEAT_COUNT@|\'$(GIT_PERF_REPEAT_COUNT)\'|" \ + -e "s|@GIT_PERF_REPO@|\'$(GIT_PERF_REPO)\'|" \ + -e "s|@GIT_PERF_LARGE_REPO@|\'$(GIT_PERF_LARGE_REPO)\'|" \ + -e "s|@GIT_PERF_MAKE_OPTS@|\'$(GIT_PERF_MAKE_OPTS)\'|" \ + -e "s|@GIT_PERF_MAKE_COMMAND@|\'$(GIT_PERF_MAKE_COMMAND)\'|" \ + -e "s|@GIT_INTEROP_MAKE_OPTS@|\'$(GIT_INTEROP_MAKE_OPTS)\'|" \ + -e "s|@GIT_TEST_INDEX_VERSION@|\'$(GIT_TEST_INDEX_VERSION)\'|" \ + -e "s|@GIT_TEST_PERL_FATAL_WARNINGS@|\'$(GIT_TEST_PERL_FATAL_WARNINGS)\'|" \ + -e "s|@GIT_TEST_TEXTDOMAINDIR@|\'$(shell pwd)/po/build/locale\'|" \ + -e "s|@GIT_TEST_POPATH@|\'$(shell pwd)/po\'|" \ + -e "s|@GIT_TEST_TEMPLATE_DIR@|\'$(shell pwd)/templates/blt\'|" \ + -e "s|@GIT_TEST_GITPERLLIB@|\'$(shell pwd)/perl/build/lib\'|" \ + -e "s|@GIT_TEST_MERGE_TOOLS_DIR@|\'$(shell pwd)/mergetools\'|" \ + -e "s|@RUNTIME_PREFIX@|\'$(RUNTIME_PREFIX_OPTION)\'|" \ + -e "s|@GITWEBDIR@|\'$(gitwebdir_SQ)\'|" \ + -e "s|@USE_GETTEXT_SCHEME@|\'$(USE_GETTEXT_SCHEME)\'|" \ + -e "s|@LOCALEDIR@|\'$(localedir_SQ)\'|" \ + -e "s!@BROKEN_PATH_FIX@!\'$(BROKEN_PATH_FIX)\'!" \ + 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 @@ -3215,13 +3209,16 @@ endif test_bindir_programs := $(patsubst %,bin-wrappers/%,$(BINDIR_PROGRAMS_NEED_X) $(BINDIR_PROGRAMS_NO_X) $(TEST_PROGRAMS_NEED_X)) -all:: $(TEST_PROGRAMS) $(test_bindir_programs) $(UNIT_TEST_PROGS) +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. @@ -3251,9 +3248,10 @@ t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) check-sha1:: t/helper/test-tool$X t/helper/test-sha1.sh -SP_OBJ = $(patsubst %.o,%.sp,$(OBJECTS)) +SP_SRC = $(filter-out $(THIRD_PARTY_SOURCES),$(patsubst %.o,%.c,$(OBJECTS))) +SP_OBJ = $(patsubst %.c,%.sp,$(SP_SRC)) -$(SP_OBJ): %.sp: %.c %.o +$(SP_OBJ): %.sp: %.c %.o $(GENERATED_H) $(QUIET_SP)cgcc -no-compile $(ALL_CFLAGS) $(EXTRA_CPPFLAGS) \ -Wsparse-error \ $(SPARSE_FLAGS) $(SP_EXTRA_FLAGS) $< && \ @@ -3262,7 +3260,7 @@ $(SP_OBJ): %.sp: %.c %.o .PHONY: sparse sparse: $(SP_OBJ) -EXCEPT_HDRS := $(GENERATED_H) unicode-width.h compat/% xdiff/% +EXCEPT_HDRS := $(GENERATED_H) unicode-width.h compat/% xdiff/% $(UNIT_TEST_DIR)/clar/% $(UNIT_TEST_DIR)/clar/clar/% ifndef OPENSSL_SHA1 EXCEPT_HDRS += sha1/openssl.h endif @@ -3283,7 +3281,7 @@ HCC = $(HCO:hco=hcc) @echo '#include "git-compat-util.h"' >$@ @echo '#include "$<"' >>$@ -$(HCO): %.hco: %.hcc FORCE +$(HCO): %.hco: %.hcc $(GENERATED_H) FORCE $(QUIET_HDR)$(CC) $(ALL_CFLAGS) -o /dev/null -c -xc $< .PHONY: hdr-check $(HCO) @@ -3294,7 +3292,7 @@ style: git clang-format --style file --diff --extensions c,h .PHONY: check -check: $(GENERATED_H) +check: @if sparse; \ then \ echo >&2 "Use 'make sparse' instead"; \ @@ -3646,7 +3644,7 @@ endif artifacts-tar:: $(ALL_COMMANDS_TO_INSTALL) $(SCRIPT_LIB) $(OTHER_PROGRAMS) \ GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \ - $(UNIT_TEST_PROGS) $(MOFILES) + $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) $(MOFILES) $(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) \ SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)' test -n "$(ARTIFACTS_DIRECTORY)" @@ -3702,8 +3700,9 @@ cocciclean: 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) @@ -3712,7 +3711,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 @@ -3859,7 +3860,25 @@ $(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_OBJS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \ $(filter %.o,$^) $(filter %.a,$^) $(LIBS) +GIT-TEST-SUITES: FORCE + @FLAGS='$(CLAR_TEST_SUITES)'; \ + if test x"$$FLAGS" != x"`cat GIT-TEST-SUITES 2>/dev/null`" ; then \ + echo >&2 " * new test suites"; \ + echo "$$FLAGS" >GIT-TEST-SUITES; \ + fi + +$(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 + $(call mkdir_p_parent_template) + $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) + .PHONY: build-unit-tests unit-tests -build-unit-tests: $(UNIT_TEST_PROGS) -unit-tests: $(UNIT_TEST_PROGS) t/helper/test-tool$X +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 @@ -1 +1 @@ -Documentation/RelNotes/2.47.0.txt
\ No newline at end of file +Documentation/RelNotes/2.48.0.txt
\ No newline at end of file @@ -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) @@ -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, @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "alias.h" #include "config.h" @@ -37,7 +39,7 @@ char *alias_lookup(const char *alias) { struct config_alias_data data = { alias, NULL }; - read_early_config(config_alias_cb, &data); + read_early_config(the_repository, config_alias_cb, &data); return data.v; } @@ -46,7 +48,7 @@ void list_aliases(struct string_list *list) { struct config_alias_data data = { NULL, NULL, list }; - read_early_config(config_alias_cb, &data); + read_early_config(the_repository, config_alias_cb, &data); } void quote_cmdline(struct strbuf *buf, const char **argv) @@ -30,6 +30,7 @@ #include "path.h" #include "quote.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "apply.h" #include "entry.h" @@ -277,13 +278,26 @@ struct line { * This represents a "file", which is an array of "lines". */ struct image { - char *buf; - size_t len; - size_t nr; - size_t alloc; - struct line *line_allocated; + struct strbuf buf; struct line *line; + size_t line_nr, line_alloc; }; +#define IMAGE_INIT { \ + .buf = STRBUF_INIT, \ +} + +static void image_init(struct image *image) +{ + struct image empty = IMAGE_INIT; + memcpy(image, &empty, sizeof(*image)); +} + +static void image_clear(struct image *image) +{ + strbuf_release(&image->buf); + free(image->line); + image_init(image); +} static uint32_t hash_line(const char *cp, size_t len) { @@ -297,49 +311,13 @@ static uint32_t hash_line(const char *cp, size_t len) return h; } -/* - * Compare lines s1 of length n1 and s2 of length n2, ignoring - * whitespace difference. Returns 1 if they match, 0 otherwise - */ -static int fuzzy_matchlines(const char *s1, size_t n1, - const char *s2, size_t n2) -{ - const char *end1 = s1 + n1; - const char *end2 = s2 + n2; - - /* ignore line endings */ - while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n')) - end1--; - while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n')) - end2--; - - while (s1 < end1 && s2 < end2) { - if (isspace(*s1)) { - /* - * Skip whitespace. We check on both buffers - * because we don't want "a b" to match "ab". - */ - if (!isspace(*s2)) - return 0; - while (s1 < end1 && isspace(*s1)) - s1++; - while (s2 < end2 && isspace(*s2)) - s2++; - } else if (*s1++ != *s2++) - return 0; - } - - /* If we reached the end on one side only, lines don't match. */ - return s1 == end1 && s2 == end2; -} - -static void add_line_info(struct image *img, const char *bol, size_t len, unsigned flag) +static void image_add_line(struct image *img, const char *bol, size_t len, unsigned flag) { - ALLOC_GROW(img->line_allocated, img->nr + 1, img->alloc); - img->line_allocated[img->nr].len = len; - img->line_allocated[img->nr].hash = hash_line(bol, len); - img->line_allocated[img->nr].flag = flag; - img->nr++; + ALLOC_GROW(img->line, img->line_nr + 1, img->line_alloc); + img->line[img->line_nr].len = len; + img->line[img->line_nr].hash = hash_line(bol, len); + img->line[img->line_nr].flag = flag; + img->line_nr++; } /* @@ -347,37 +325,43 @@ static void add_line_info(struct image *img, const char *bol, size_t len, unsign * attach it to "image" and add line-based index to it. * "image" now owns the "buf". */ -static void prepare_image(struct image *image, char *buf, size_t len, +static void image_prepare(struct image *image, char *buf, size_t len, int prepare_linetable) { const char *cp, *ep; - memset(image, 0, sizeof(*image)); - image->buf = buf; - image->len = len; + image_clear(image); + strbuf_attach(&image->buf, buf, len, len + 1); if (!prepare_linetable) return; - ep = image->buf + image->len; - cp = image->buf; + ep = image->buf.buf + image->buf.len; + cp = image->buf.buf; while (cp < ep) { const char *next; for (next = cp; next < ep && *next != '\n'; next++) ; if (next < ep) next++; - add_line_info(image, cp, next - cp, 0); + image_add_line(image, cp, next - cp, 0); cp = next; } - image->line = image->line_allocated; } -static void clear_image(struct image *image) +static void image_remove_first_line(struct image *img) +{ + strbuf_remove(&img->buf, 0, img->line[0].len); + img->line_nr--; + if (img->line_nr) + MOVE_ARRAY(img->line, img->line + 1, img->line_nr); +} + +static void image_remove_last_line(struct image *img) { - free(image->buf); - free(image->line_allocated); - memset(image, 0, sizeof(*image)); + size_t last_line_len = img->line[img->line_nr - 1].len; + strbuf_setlen(&img->buf, img->buf.len - last_line_len); + img->line_nr--; } /* fmt must contain _one_ %s and no other substitution */ @@ -2326,65 +2310,43 @@ static int read_old_data(struct stat *st, struct patch *patch, /* * Update the preimage, and the common lines in postimage, - * from buffer buf of length len. If postlen is 0 the postimage - * is updated in place, otherwise it's updated on a new buffer - * of length postlen + * from buffer buf of length len. */ - static void update_pre_post_images(struct image *preimage, struct image *postimage, - char *buf, - size_t len, size_t postlen) + char *buf, size_t len) { + struct image fixed_preimage = IMAGE_INIT; + size_t insert_pos = 0; int i, ctx, reduced; - char *new_buf, *old_buf, *fixed; - struct image fixed_preimage; + const char *fixed; /* * Update the preimage with whitespace fixes. Note that we * are not losing preimage->buf -- apply_one_fragment() will * free "oldlines". */ - prepare_image(&fixed_preimage, buf, len, 1); - assert(postlen - ? fixed_preimage.nr == preimage->nr - : fixed_preimage.nr <= preimage->nr); - for (i = 0; i < fixed_preimage.nr; i++) + image_prepare(&fixed_preimage, buf, len, 1); + for (i = 0; i < fixed_preimage.line_nr; i++) fixed_preimage.line[i].flag = preimage->line[i].flag; - free(preimage->line_allocated); + image_clear(preimage); *preimage = fixed_preimage; + fixed = preimage->buf.buf; /* - * Adjust the common context lines in postimage. This can be - * done in-place when we are shrinking it with whitespace - * fixing, but needs a new buffer when ignoring whitespace or - * expanding leading tabs to spaces. - * - * We trust the caller to tell us if the update can be done - * in place (postlen==0) or not. + * Adjust the common context lines in postimage. */ - old_buf = postimage->buf; - if (postlen) - new_buf = postimage->buf = xmalloc(postlen); - else - new_buf = old_buf; - fixed = preimage->buf; - - for (i = reduced = ctx = 0; i < postimage->nr; i++) { + for (i = reduced = ctx = 0; i < postimage->line_nr; i++) { size_t l_len = postimage->line[i].len; + if (!(postimage->line[i].flag & LINE_COMMON)) { /* an added line -- no counterparts in preimage */ - memmove(new_buf, old_buf, l_len); - old_buf += l_len; - new_buf += l_len; + insert_pos += l_len; continue; } - /* a common context -- skip it in the original postimage */ - old_buf += l_len; - /* and find the corresponding one in the fixed preimage */ - while (ctx < preimage->nr && + while (ctx < preimage->line_nr && !(preimage->line[ctx].flag & LINE_COMMON)) { fixed += preimage->line[ctx].len; ctx++; @@ -2394,29 +2356,59 @@ static void update_pre_post_images(struct image *preimage, * preimage is expected to run out, if the caller * fixed addition of trailing blank lines. */ - if (preimage->nr <= ctx) { + if (preimage->line_nr <= ctx) { reduced++; continue; } /* and copy it in, while fixing the line length */ l_len = preimage->line[ctx].len; - memcpy(new_buf, fixed, l_len); - new_buf += l_len; + strbuf_splice(&postimage->buf, insert_pos, postimage->line[i].len, + fixed, l_len); + insert_pos += l_len; fixed += l_len; postimage->line[i].len = l_len; ctx++; } - if (postlen - ? postlen < new_buf - postimage->buf - : postimage->len < new_buf - postimage->buf) - BUG("caller miscounted postlen: asked %d, orig = %d, used = %d", - (int)postlen, (int) postimage->len, (int)(new_buf - postimage->buf)); - /* Fix the length of the whole thing */ - postimage->len = new_buf - postimage->buf; - postimage->nr -= reduced; + postimage->line_nr -= reduced; +} + +/* + * Compare lines s1 of length n1 and s2 of length n2, ignoring + * whitespace difference. Returns 1 if they match, 0 otherwise + */ +static int fuzzy_matchlines(const char *s1, size_t n1, + const char *s2, size_t n2) +{ + const char *end1 = s1 + n1; + const char *end2 = s2 + n2; + + /* ignore line endings */ + while (s1 < end1 && (end1[-1] == '\r' || end1[-1] == '\n')) + end1--; + while (s2 < end2 && (end2[-1] == '\r' || end2[-1] == '\n')) + end2--; + + while (s1 < end1 && s2 < end2) { + if (isspace(*s1)) { + /* + * Skip whitespace. We check on both buffers + * because we don't want "a b" to match "ab". + */ + if (!isspace(*s2)) + return 0; + while (s1 < end1 && isspace(*s1)) + s1++; + while (s2 < end2 && isspace(*s2)) + s2++; + } else if (*s1++ != *s2++) + return 0; + } + + /* If we reached the end on one side only, lines don't match. */ + return s1 == end1 && s2 == end2; } static int line_by_line_fuzzy_match(struct image *img, @@ -2429,7 +2421,6 @@ static int line_by_line_fuzzy_match(struct image *img, int i; size_t imgoff = 0; size_t preoff = 0; - size_t postlen = postimage->len; size_t extra_chars; char *buf; char *preimage_eof; @@ -2442,11 +2433,9 @@ static int line_by_line_fuzzy_match(struct image *img, size_t prelen = preimage->line[i].len; size_t imglen = img->line[current_lno+i].len; - if (!fuzzy_matchlines(img->buf + current + imgoff, imglen, - preimage->buf + preoff, prelen)) + if (!fuzzy_matchlines(img->buf.buf + current + imgoff, imglen, + preimage->buf.buf + preoff, prelen)) return 0; - if (preimage->line[i].flag & LINE_COMMON) - postlen += imglen - prelen; imgoff += imglen; preoff += prelen; } @@ -2462,10 +2451,10 @@ static int line_by_line_fuzzy_match(struct image *img, * are whitespace characters. (This can only happen if * we are removing blank lines at the end of the file.) */ - buf = preimage_eof = preimage->buf + preoff; - for ( ; i < preimage->nr; i++) + buf = preimage_eof = preimage->buf.buf + preoff; + for ( ; i < preimage->line_nr; i++) preoff += preimage->line[i].len; - preimage_end = preimage->buf + preoff; + preimage_end = preimage->buf.buf + preoff; for ( ; buf < preimage_end; buf++) if (!isspace(*buf)) return 0; @@ -2479,11 +2468,11 @@ static int line_by_line_fuzzy_match(struct image *img, */ extra_chars = preimage_end - preimage_eof; strbuf_init(&fixed, imgoff + extra_chars); - strbuf_add(&fixed, img->buf + current, imgoff); + strbuf_add(&fixed, img->buf.buf + current, imgoff); strbuf_add(&fixed, preimage_eof, extra_chars); fixed_buf = strbuf_detach(&fixed, &fixed_len); update_pre_post_images(preimage, postimage, - fixed_buf, fixed_len, postlen); + fixed_buf, fixed_len); return 1; } @@ -2499,16 +2488,17 @@ static int match_fragment(struct apply_state *state, int i; const char *orig, *target; struct strbuf fixed = STRBUF_INIT; - size_t postlen; + char *fixed_buf; + size_t fixed_len; int preimage_limit; int ret; - if (preimage->nr + current_lno <= img->nr) { + if (preimage->line_nr + current_lno <= img->line_nr) { /* * The hunk falls within the boundaries of img. */ - preimage_limit = preimage->nr; - if (match_end && (preimage->nr + current_lno != img->nr)) { + preimage_limit = preimage->line_nr; + if (match_end && (preimage->line_nr + current_lno != img->line_nr)) { ret = 0; goto out; } @@ -2521,7 +2511,7 @@ static int match_fragment(struct apply_state *state, * match with img, and the remainder of the preimage * must be blank. */ - preimage_limit = img->nr - current_lno; + preimage_limit = img->line_nr - current_lno; } else { /* * The hunk extends beyond the end of the img and @@ -2546,7 +2536,7 @@ static int match_fragment(struct apply_state *state, } } - if (preimage_limit == preimage->nr) { + if (preimage_limit == preimage->line_nr) { /* * Do we have an exact match? If we were told to match * at the end, size must be exactly at current+fragsize, @@ -2555,9 +2545,9 @@ static int match_fragment(struct apply_state *state, * exactly. */ if ((match_end - ? (current + preimage->len == img->len) - : (current + preimage->len <= img->len)) && - !memcmp(img->buf + current, preimage->buf, preimage->len)) { + ? (current + preimage->buf.len == img->buf.len) + : (current + preimage->buf.len <= img->buf.len)) && + !memcmp(img->buf.buf + current, preimage->buf.buf, preimage->buf.len)) { ret = 1; goto out; } @@ -2571,7 +2561,7 @@ static int match_fragment(struct apply_state *state, */ const char *buf, *buf_end; - buf = preimage->buf; + buf = preimage->buf.buf; buf_end = buf; for (i = 0; i < preimage_limit; i++) buf_end += preimage->line[i].len; @@ -2616,21 +2606,14 @@ static int match_fragment(struct apply_state *state, * fixed. */ - /* First count added lines in postimage */ - postlen = 0; - for (i = 0; i < postimage->nr; i++) { - if (!(postimage->line[i].flag & LINE_COMMON)) - postlen += postimage->line[i].len; - } - /* * The preimage may extend beyond the end of the file, * but in this loop we will only handle the part of the * preimage that falls within the file. */ - strbuf_grow(&fixed, preimage->len + 1); - orig = preimage->buf; - target = img->buf + current; + strbuf_grow(&fixed, preimage->buf.len + 1); + orig = preimage->buf.buf; + target = img->buf.buf + current; for (i = 0; i < preimage_limit; i++) { size_t oldlen = preimage->line[i].len; size_t tgtlen = img->line[current_lno + i].len; @@ -2659,10 +2642,6 @@ static int match_fragment(struct apply_state *state, !memcmp(tgtfix.buf, fixed.buf + fixstart, fixed.len - fixstart)); - /* Add the length if this is common with the postimage */ - if (preimage->line[i].flag & LINE_COMMON) - postlen += tgtfix.len; - strbuf_release(&tgtfix); if (!match) { ret = 0; @@ -2680,7 +2659,7 @@ static int match_fragment(struct apply_state *state, * empty or only contain whitespace (if WS_BLANK_AT_EOL is * false). */ - for ( ; i < preimage->nr; i++) { + for ( ; i < preimage->line_nr; i++) { size_t fixstart = fixed.len; /* start of the fixed preimage */ size_t oldlen = preimage->line[i].len; int j; @@ -2704,10 +2683,9 @@ static int match_fragment(struct apply_state *state, * has whitespace breakages unfixed, and fixing them makes the * hunk match. Update the context lines in the postimage. */ - if (postlen < postimage->len) - postlen = 0; + fixed_buf = strbuf_detach(&fixed, &fixed_len); update_pre_post_images(preimage, postimage, - fixed.buf, fixed.len, postlen); + fixed_buf, fixed_len); ret = 1; @@ -2735,7 +2713,7 @@ static int find_pos(struct apply_state *state, * than `match_beginning`. */ if (state->allow_overlap && match_beginning && match_end && - img->nr - preimage->nr != 0) + img->line_nr - preimage->line_nr != 0) match_beginning = 0; /* @@ -2746,15 +2724,15 @@ static int find_pos(struct apply_state *state, if (match_beginning) line = 0; else if (match_end) - line = img->nr - preimage->nr; + line = img->line_nr - preimage->line_nr; /* * Because the comparison is unsigned, the following test * will also take care of a negative line number that can * result when match_end and preimage is larger than the target. */ - if ((size_t) line > img->nr) - line = img->nr; + if ((size_t) line > img->line_nr) + line = img->line_nr; current = 0; for (i = 0; i < line; i++) @@ -2777,7 +2755,7 @@ static int find_pos(struct apply_state *state, return current_lno; again: - if (backwards_lno == 0 && forwards_lno == img->nr) + if (backwards_lno == 0 && forwards_lno == img->line_nr) break; if (i & 1) { @@ -2790,7 +2768,7 @@ static int find_pos(struct apply_state *state, current = backwards; current_lno = backwards_lno; } else { - if (forwards_lno == img->nr) { + if (forwards_lno == img->line_nr) { i++; goto again; } @@ -2804,19 +2782,6 @@ static int find_pos(struct apply_state *state, return -1; } -static void remove_first_line(struct image *img) -{ - img->buf += img->line[0].len; - img->len -= img->line[0].len; - img->line++; - img->nr--; -} - -static void remove_last_line(struct image *img) -{ - img->len -= img->line[--img->nr].len; -} - /* * The change from "preimage" and "postimage" has been found to * apply at applied_pos (counts in line numbers) in "img". @@ -2834,6 +2799,7 @@ static void update_image(struct apply_state *state, */ int i, nr; size_t remove_count, insert_count, applied_at = 0; + size_t result_alloc; char *result; int preimage_limit; @@ -2846,9 +2812,9 @@ static void update_image(struct apply_state *state, * to the number of lines in the preimage that falls * within the boundaries. */ - preimage_limit = preimage->nr; - if (preimage_limit > img->nr - applied_pos) - preimage_limit = img->nr - applied_pos; + preimage_limit = preimage->line_nr; + if (preimage_limit > img->line_nr - applied_pos) + preimage_limit = img->line_nr - applied_pos; for (i = 0; i < applied_pos; i++) applied_at += img->line[i].len; @@ -2856,39 +2822,36 @@ static void update_image(struct apply_state *state, remove_count = 0; for (i = 0; i < preimage_limit; i++) remove_count += img->line[applied_pos + i].len; - insert_count = postimage->len; + insert_count = postimage->buf.len; /* Adjust the contents */ - result = xmalloc(st_add3(st_sub(img->len, remove_count), insert_count, 1)); - memcpy(result, img->buf, applied_at); - memcpy(result + applied_at, postimage->buf, postimage->len); - memcpy(result + applied_at + postimage->len, - img->buf + (applied_at + remove_count), - img->len - (applied_at + remove_count)); - free(img->buf); - img->buf = result; - img->len += insert_count - remove_count; - result[img->len] = '\0'; + result_alloc = st_add3(st_sub(img->buf.len, remove_count), insert_count, 1); + result = xmalloc(result_alloc); + memcpy(result, img->buf.buf, applied_at); + memcpy(result + applied_at, postimage->buf.buf, postimage->buf.len); + memcpy(result + applied_at + postimage->buf.len, + img->buf.buf + (applied_at + remove_count), + img->buf.len - (applied_at + remove_count)); + strbuf_attach(&img->buf, result, postimage->buf.len + img->buf.len - remove_count, + result_alloc); /* Adjust the line table */ - nr = img->nr + postimage->nr - preimage_limit; - if (preimage_limit < postimage->nr) { + nr = img->line_nr + postimage->line_nr - preimage_limit; + if (preimage_limit < postimage->line_nr) /* - * NOTE: this knows that we never call remove_first_line() + * NOTE: this knows that we never call image_remove_first_line() * on anything other than pre/post image. */ REALLOC_ARRAY(img->line, nr); - img->line_allocated = img->line; - } - if (preimage_limit != postimage->nr) - MOVE_ARRAY(img->line + applied_pos + postimage->nr, + if (preimage_limit != postimage->line_nr) + MOVE_ARRAY(img->line + applied_pos + postimage->line_nr, img->line + applied_pos + preimage_limit, - img->nr - (applied_pos + preimage_limit)); - COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->nr); + img->line_nr - (applied_pos + preimage_limit)); + COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->line_nr); if (!state->allow_overlap) - for (i = 0; i < postimage->nr; i++) + for (i = 0; i < postimage->line_nr; i++) img->line[applied_pos + i].flag |= LINE_PATCHED; - img->nr = nr; + img->line_nr = nr; } /* @@ -2911,11 +2874,9 @@ static int apply_one_fragment(struct apply_state *state, int hunk_linenr = frag->linenr; unsigned long leading, trailing; int pos, applied_pos; - struct image preimage; - struct image postimage; + struct image preimage = IMAGE_INIT; + struct image postimage = IMAGE_INIT; - memset(&preimage, 0, sizeof(preimage)); - memset(&postimage, 0, sizeof(postimage)); oldlines = xmalloc(size); strbuf_init(&newlines, size); @@ -2957,8 +2918,8 @@ static int apply_one_fragment(struct apply_state *state, break; *old++ = '\n'; strbuf_addch(&newlines, '\n'); - add_line_info(&preimage, "\n", 1, LINE_COMMON); - add_line_info(&postimage, "\n", 1, LINE_COMMON); + image_add_line(&preimage, "\n", 1, LINE_COMMON); + image_add_line(&postimage, "\n", 1, LINE_COMMON); is_blank_context = 1; break; case ' ': @@ -2968,7 +2929,7 @@ static int apply_one_fragment(struct apply_state *state, /* fallthrough */ case '-': memcpy(old, patch + 1, plen); - add_line_info(&preimage, old, plen, + image_add_line(&preimage, old, plen, (first == ' ' ? LINE_COMMON : 0)); old += plen; if (first == '-') @@ -2988,7 +2949,7 @@ static int apply_one_fragment(struct apply_state *state, else { ws_fix_copy(&newlines, patch + 1, plen, ws_rule, &state->applied_after_fixing_ws); } - add_line_info(&postimage, newlines.buf + start, newlines.len - start, + image_add_line(&postimage, newlines.buf + start, newlines.len - start, (first == '+' ? 0 : LINE_COMMON)); if (first == '+' && (ws_rule & WS_BLANK_AT_EOF) && @@ -3022,8 +2983,8 @@ static int apply_one_fragment(struct apply_state *state, newlines.len > 0 && newlines.buf[newlines.len - 1] == '\n') { old--; strbuf_setlen(&newlines, newlines.len - 1); - preimage.line_allocated[preimage.nr - 1].len--; - postimage.line_allocated[postimage.nr - 1].len--; + preimage.line[preimage.line_nr - 1].len--; + postimage.line[postimage.line_nr - 1].len--; } leading = frag->leading; @@ -3053,12 +3014,8 @@ static int apply_one_fragment(struct apply_state *state, match_end = !state->unidiff_zero && !trailing; pos = frag->newpos ? (frag->newpos - 1) : 0; - preimage.buf = oldlines; - preimage.len = old - oldlines; - postimage.buf = newlines.buf; - postimage.len = newlines.len; - preimage.line = preimage.line_allocated; - postimage.line = postimage.line_allocated; + strbuf_add(&preimage.buf, oldlines, old - oldlines); + strbuf_swap(&postimage.buf, &newlines); for (;;) { @@ -3082,28 +3039,28 @@ static int apply_one_fragment(struct apply_state *state, * just reduce the larger context. */ if (leading >= trailing) { - remove_first_line(&preimage); - remove_first_line(&postimage); + image_remove_first_line(&preimage); + image_remove_first_line(&postimage); pos--; leading--; } if (trailing > leading) { - remove_last_line(&preimage); - remove_last_line(&postimage); + image_remove_last_line(&preimage); + image_remove_last_line(&postimage); trailing--; } } if (applied_pos >= 0) { if (new_blank_lines_at_end && - preimage.nr + applied_pos >= img->nr && + preimage.line_nr + applied_pos >= img->line_nr && (ws_rule & WS_BLANK_AT_EOF) && state->ws_error_action != nowarn_ws_error) { record_ws_error(state, WS_BLANK_AT_EOF, "+", 1, found_new_blank_lines_at_end); if (state->ws_error_action == correct_ws_error) { while (new_blank_lines_at_end--) - remove_last_line(&postimage); + image_remove_last_line(&postimage); } /* * We would want to prevent write_out_results() @@ -3146,8 +3103,8 @@ static int apply_one_fragment(struct apply_state *state, out: free(oldlines); strbuf_release(&newlines); - free(preimage.line_allocated); - free(postimage.line_allocated); + image_clear(&preimage); + image_clear(&postimage); return (applied_pos < 0); } @@ -3177,18 +3134,16 @@ static int apply_binary_fragment(struct apply_state *state, } switch (fragment->binary_patch_method) { case BINARY_DELTA_DEFLATED: - dst = patch_delta(img->buf, img->len, fragment->patch, + dst = patch_delta(img->buf.buf, img->buf.len, fragment->patch, fragment->size, &len); if (!dst) return -1; - clear_image(img); - img->buf = dst; - img->len = len; + image_clear(img); + strbuf_attach(&img->buf, dst, len, len + 1); return 0; case BINARY_LITERAL_DEFLATED: - clear_image(img); - img->len = fragment->size; - img->buf = xmemdupz(fragment->patch, img->len); + image_clear(img); + strbuf_add(&img->buf, fragment->patch, fragment->size); return 0; } return -1; @@ -3224,8 +3179,8 @@ static int apply_binary(struct apply_state *state, * See if the old one matches what the patch * applies to. */ - hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB, - &oid); + hash_object_file(the_hash_algo, img->buf.buf, img->buf.len, + OBJ_BLOB, &oid); if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix)) return error(_("the patch applies to '%s' (%s), " "which does not match the " @@ -3234,14 +3189,14 @@ static int apply_binary(struct apply_state *state, } else { /* Otherwise, the old one must be empty. */ - if (img->len) + if (img->buf.len) return error(_("the patch applies to an empty " "'%s' but it is not empty"), name); } get_oid_hex(patch->new_oid_prefix, &oid); if (is_null_oid(&oid)) { - clear_image(img); + image_clear(img); return 0; /* deletion patch */ } @@ -3257,9 +3212,8 @@ static int apply_binary(struct apply_state *state, return error(_("the necessary postimage %s for " "'%s' cannot be read"), patch->new_oid_prefix, name); - clear_image(img); - img->buf = result; - img->len = size; + image_clear(img); + strbuf_attach(&img->buf, result, size, size + 1); } else { /* * We have verified buf matches the preimage; @@ -3271,7 +3225,7 @@ static int apply_binary(struct apply_state *state, name); /* verify that the result matches */ - hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB, + hash_object_file(the_hash_algo, img->buf.buf, img->buf.len, OBJ_BLOB, &oid); if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix)) return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"), @@ -3533,7 +3487,7 @@ static int load_preimage(struct apply_state *state, } img = strbuf_detach(&buf, &len); - prepare_image(image, img, len, !patch->is_binary); + image_prepare(image, img, len, !patch->is_binary); return 0; } @@ -3541,14 +3495,14 @@ static int resolve_to(struct image *image, const struct object_id *result_id) { unsigned long size; enum object_type type; + char *data; - clear_image(image); + image_clear(image); - image->buf = repo_read_object_file(the_repository, result_id, &type, - &size); - if (!image->buf || type != OBJ_BLOB) + data = repo_read_object_file(the_repository, result_id, &type, &size); + if (!data || type != OBJ_BLOB) die("unable to read blob object %s", oid_to_hex(result_id)); - image->len = size; + strbuf_attach(&image->buf, data, size, size + 1); return 0; } @@ -3561,6 +3515,7 @@ static int three_way_merge(struct apply_state *state, const struct object_id *theirs) { mmfile_t base_file, our_file, their_file; + struct ll_merge_options merge_opts = LL_MERGE_OPTIONS_INIT; mmbuffer_t result = { NULL }; enum ll_merge_result status; @@ -3573,12 +3528,13 @@ static int three_way_merge(struct apply_state *state, read_mmblob(&base_file, base); read_mmblob(&our_file, ours); read_mmblob(&their_file, theirs); + merge_opts.variant = state->merge_variant; status = ll_merge(&result, path, &base_file, "base", &our_file, "ours", &their_file, "theirs", state->repo->index, - NULL); + &merge_opts); if (status == LL_MERGE_BINARY_CONFLICT) warning("Cannot merge binary files: %s (%s vs. %s)", path, "ours", "theirs"); @@ -3589,9 +3545,8 @@ static int three_way_merge(struct apply_state *state, free(result.ptr); return -1; } - clear_image(image); - image->buf = result.ptr; - image->len = result.size; + image_clear(image); + strbuf_attach(&image->buf, result.ptr, result.size, result.size); return status; } @@ -3636,7 +3591,7 @@ static int load_current(struct apply_state *state, else if (status) return -1; img = strbuf_detach(&buf, &len); - prepare_image(image, img, len, !patch->is_binary); + image_prepare(image, img, len, !patch->is_binary); return 0; } @@ -3651,7 +3606,7 @@ static int try_threeway(struct apply_state *state, size_t len; int status; char *img; - struct image tmp_image; + struct image tmp_image = IMAGE_INIT; /* No point falling back to 3-way merge in these cases */ if (patch->is_delete || @@ -3671,15 +3626,15 @@ static int try_threeway(struct apply_state *state, fprintf(stderr, _("Performing three-way merge...\n")); img = strbuf_detach(&buf, &len); - prepare_image(&tmp_image, img, len, 1); + image_prepare(&tmp_image, img, len, 1); /* Apply the patch to get the post image */ if (apply_fragments(state, &tmp_image, patch) < 0) { - clear_image(&tmp_image); + image_clear(&tmp_image); return -1; } /* post_oid is theirs */ - write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &post_oid); - clear_image(&tmp_image); + write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &post_oid); + image_clear(&tmp_image); /* our_oid is ours */ if (patch->is_new) { @@ -3691,8 +3646,8 @@ static int try_threeway(struct apply_state *state, return error(_("cannot read the current contents of '%s'"), patch->old_name); } - write_object_file(tmp_image.buf, tmp_image.len, OBJ_BLOB, &our_oid); - clear_image(&tmp_image); + write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &our_oid); + image_clear(&tmp_image); /* in-core three-way merge between post and our using pre as base */ status = three_way_merge(state, image, patch->new_name, @@ -3728,7 +3683,7 @@ static int try_threeway(struct apply_state *state, static int apply_data(struct apply_state *state, struct patch *patch, struct stat *st, const struct cache_entry *ce) { - struct image image; + struct image image = IMAGE_INIT; if (load_preimage(state, &image, patch, st, ce) < 0) return -1; @@ -3740,14 +3695,13 @@ static int apply_data(struct apply_state *state, struct patch *patch, /* Note: with --reject, apply_fragments() returns 0 */ if (patch->direct_to_threeway || apply_fragments(state, &image, patch) < 0) { - clear_image(&image); + image_clear(&image); return -1; } } - patch->result = image.buf; - patch->resultsize = image.len; + patch->result = strbuf_detach(&image.buf, &patch->resultsize); add_to_fn_table(state, patch); - free(image.line_allocated); + free(image.line); if (0 < patch->is_delete && patch->resultsize) return error(_("removal patch leaves file contents")); @@ -4111,7 +4065,7 @@ static int read_apply_cache(struct apply_state *state) { if (state->index_file) return read_index_from(state->repo->index, state->index_file, - get_git_dir()); + repo_get_git_dir(the_repository)); else return repo_read_index(state->repo); } @@ -5151,6 +5105,15 @@ int apply_parse_options(int argc, const char **argv, N_("also apply the patch (use with --stat/--summary/--check)")), OPT_BOOL('3', "3way", &state->threeway, N_( "attempt three-way merge, fall back on normal patch if that fails")), + OPT_SET_INT_F(0, "ours", &state->merge_variant, + N_("for conflicts, use our version"), + XDL_MERGE_FAVOR_OURS, PARSE_OPT_NONEG), + OPT_SET_INT_F(0, "theirs", &state->merge_variant, + N_("for conflicts, use their version"), + XDL_MERGE_FAVOR_THEIRS, PARSE_OPT_NONEG), + OPT_SET_INT_F(0, "union", &state->merge_variant, + N_("for conflicts, use a union version"), + XDL_MERGE_FAVOR_UNION, PARSE_OPT_NONEG), OPT_FILENAME(0, "build-fake-ancestor", &state->fake_ancestor, N_("build a temporary index based on embedded index information")), /* Think twice before adding "--nul" synonym to this */ @@ -5190,5 +5153,10 @@ int apply_parse_options(int argc, const char **argv, OPT_END() }; - return parse_options(argc, argv, state->prefix, builtin_apply_options, apply_usage, 0); + argc = parse_options(argc, argv, state->prefix, builtin_apply_options, apply_usage, 0); + + if (state->merge_variant && !state->threeway) + die(_("--ours, --theirs, and --union require --3way")); + + return argc; } @@ -59,6 +59,7 @@ struct apply_state { struct repository *repo; const char *index_file; enum apply_verbosity apply_verbosity; + int merge_variant; char *fake_ancestor; const char *patch_input_file; int line_termination; @@ -304,8 +304,6 @@ int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry) { struct archiver_context context; - struct unpack_trees_options opts; - struct tree_desc t; int err; struct strbuf path_in_archive = STRBUF_INIT; struct strbuf content = STRBUF_INIT; @@ -331,23 +329,6 @@ int write_archive_entries(struct archiver_args *args, context.args = args; context.write_entry = write_entry; - /* - * Setup index and instruct attr to read index only - */ - if (!args->worktree_attributes) { - memset(&opts, 0, sizeof(opts)); - opts.index_only = 1; - opts.head_idx = -1; - opts.src_index = args->repo->index; - opts.dst_index = args->repo->index; - opts.fn = oneway_merge; - init_tree_desc(&t, &args->tree->object.oid, - args->tree->buffer, args->tree->size); - if (unpack_trees(1, &t, &opts)) - return -1; - git_attr_set_direction(GIT_ATTR_INDEX); - } - err = read_tree(args->repo, args->tree, &args->pathspec, queue_or_write_archive_entry, @@ -540,6 +521,27 @@ static void parse_treeish_arg(const char **argv, if (!tree) die(_("not a tree object: %s"), oid_to_hex(&oid)); + /* + * Setup index and instruct attr to read index only + */ + if (!ar_args->worktree_attributes) { + struct unpack_trees_options opts; + struct tree_desc t; + + memset(&opts, 0, sizeof(opts)); + opts.index_only = 1; + opts.head_idx = -1; + opts.src_index = ar_args->repo->index; + opts.dst_index = ar_args->repo->index; + opts.fn = oneway_merge; + init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size); + if (unpack_trees(1, &t, &opts)) + die(_("failed to unpack tree object %s"), + oid_to_hex(&tree->object.oid)); + + git_attr_set_direction(GIT_ATTR_INDEX); + } + ar_args->refname = ref; ar_args->tree = tree; ar_args->commit_oid = commit_oid; @@ -187,7 +187,7 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check) } /* - * Atribute name cannot begin with "builtin_" which + * Attribute name cannot begin with "builtin_" which * is a reserved namespace for built in attributes values. */ static int attr_name_reserved(const char *name) @@ -259,42 +259,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 +317,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; @@ -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/bin-wrappers/.gitignore b/bin-wrappers/.gitignore new file mode 100644 index 0000000000..1c6c90458b --- /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 0000000000..8a4e910c9b --- /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 0000000000..4b658ffd2d --- /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 @@ -28,8 +28,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 +443,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 +457,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 +558,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 +618,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 +630,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, @@ -801,6 +814,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; } @@ -848,8 +863,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; @@ -985,7 +1000,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 +1008,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 +1043,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 +1110,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 +1144,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; @@ -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); @@ -2931,6 +2931,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); @@ -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 9fb0441b98..47bb916636 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 @@ -476,8 +476,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 +506,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 +515,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; } @@ -18,7 +18,7 @@ struct bloom_filter_settings { /* * The number of times a path is hashed, i.e. the - * number of bit positions tht cumulatively + * number of bit positions that cumulatively * determine whether a path is present in the * Bloom filter. */ @@ -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`")); @@ -601,6 +601,7 @@ void create_branch(struct repository *r, int forcing = 0; struct ref_transaction *transaction; struct strbuf err = STRBUF_INIT; + int flags = 0; char *msg; if (track == BRANCH_TRACK_OVERRIDE) @@ -619,18 +620,18 @@ void create_branch(struct repository *r, goto cleanup; if (reflog) - log_all_ref_updates = LOG_REFS_NORMAL; + flags |= REF_FORCE_CREATE_REFLOG; if (forcing) msg = xstrfmt("branch: Reset to %s", start_name); 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(), - NULL, NULL, 0, msg, &err) || + NULL, NULL, flags, msg, &err) || ref_transaction_commit(transaction, &err)) die("%s", err.buf); ref_transaction_free(transaction); @@ -737,6 +738,7 @@ static int submodule_create_branch(struct repository *r, strbuf_release(&child_err); strbuf_release(&out_buf); + free(out_prefix); return ret; } @@ -793,7 +795,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 @@ -814,8 +816,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) @@ -1,15 +1,8 @@ #ifndef BUILTIN_H #define BUILTIN_H -/* - * TODO: Almost all of our builtins access `the_repository` by necessity - * because they do not get passed a pointer to it. We should adapt the function - * signature of those main functions to accept a `struct repository *` and then - * remove the macro here. - */ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" +#include "repository.h" /* * builtin API @@ -122,143 +115,143 @@ int is_builtin(const char *s); BUG("unexpected prefix in builtin: %s", (prefix)); \ } while (0) -int cmd_add(int argc, const char **argv, const char *prefix); -int cmd_am(int argc, const char **argv, const char *prefix); -int cmd_annotate(int argc, const char **argv, const char *prefix); -int cmd_apply(int argc, const char **argv, const char *prefix); -int cmd_archive(int argc, const char **argv, const char *prefix); -int cmd_bisect(int argc, const char **argv, const char *prefix); -int cmd_blame(int argc, const char **argv, const char *prefix); -int cmd_branch(int argc, const char **argv, const char *prefix); -int cmd_bugreport(int argc, const char **argv, const char *prefix); -int cmd_bundle(int argc, const char **argv, const char *prefix); -int cmd_cat_file(int argc, const char **argv, const char *prefix); -int cmd_checkout(int argc, const char **argv, const char *prefix); -int cmd_checkout__worker(int argc, const char **argv, const char *prefix); -int cmd_checkout_index(int argc, const char **argv, const char *prefix); -int cmd_check_attr(int argc, const char **argv, const char *prefix); -int cmd_check_ignore(int argc, const char **argv, const char *prefix); -int cmd_check_mailmap(int argc, const char **argv, const char *prefix); -int cmd_check_ref_format(int argc, const char **argv, const char *prefix); -int cmd_cherry(int argc, const char **argv, const char *prefix); -int cmd_cherry_pick(int argc, const char **argv, const char *prefix); -int cmd_clone(int argc, const char **argv, const char *prefix); -int cmd_clean(int argc, const char **argv, const char *prefix); -int cmd_column(int argc, const char **argv, const char *prefix); -int cmd_commit(int argc, const char **argv, const char *prefix); -int cmd_commit_graph(int argc, const char **argv, const char *prefix); -int cmd_commit_tree(int argc, const char **argv, const char *prefix); -int cmd_config(int argc, const char **argv, const char *prefix); -int cmd_count_objects(int argc, const char **argv, const char *prefix); -int cmd_credential(int argc, const char **argv, const char *prefix); -int cmd_credential_cache(int argc, const char **argv, const char *prefix); -int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix); -int cmd_credential_store(int argc, const char **argv, const char *prefix); -int cmd_describe(int argc, const char **argv, const char *prefix); -int cmd_diagnose(int argc, const char **argv, const char *prefix); -int cmd_diff_files(int argc, const char **argv, const char *prefix); -int cmd_diff_index(int argc, const char **argv, const char *prefix); -int cmd_diff(int argc, const char **argv, const char *prefix); -int cmd_diff_tree(int argc, const char **argv, const char *prefix); -int cmd_difftool(int argc, const char **argv, const char *prefix); -int cmd_env__helper(int argc, const char **argv, const char *prefix); -int cmd_fast_export(int argc, const char **argv, const char *prefix); -int cmd_fast_import(int argc, const char **argv, const char *prefix); -int cmd_fetch(int argc, const char **argv, const char *prefix); -int cmd_fetch_pack(int argc, const char **argv, const char *prefix); -int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix); -int cmd_for_each_ref(int argc, const char **argv, const char *prefix); -int cmd_for_each_repo(int argc, const char **argv, const char *prefix); -int cmd_format_patch(int argc, const char **argv, const char *prefix); -int cmd_fsck(int argc, const char **argv, const char *prefix); -int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix); -int cmd_gc(int argc, const char **argv, const char *prefix); -int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix); -int cmd_grep(int argc, const char **argv, const char *prefix); -int cmd_hash_object(int argc, const char **argv, const char *prefix); -int cmd_help(int argc, const char **argv, const char *prefix); -int cmd_hook(int argc, const char **argv, const char *prefix); -int cmd_index_pack(int argc, const char **argv, const char *prefix); -int cmd_init_db(int argc, const char **argv, const char *prefix); -int cmd_interpret_trailers(int argc, const char **argv, const char *prefix); -int cmd_log(int argc, const char **argv, const char *prefix); -int cmd_log_reflog(int argc, const char **argv, const char *prefix); -int cmd_ls_files(int argc, const char **argv, const char *prefix); -int cmd_ls_tree(int argc, const char **argv, const char *prefix); -int cmd_ls_remote(int argc, const char **argv, const char *prefix); -int cmd_mailinfo(int argc, const char **argv, const char *prefix); -int cmd_mailsplit(int argc, const char **argv, const char *prefix); -int cmd_maintenance(int argc, const char **argv, const char *prefix); -int cmd_merge(int argc, const char **argv, const char *prefix); -int cmd_merge_base(int argc, const char **argv, const char *prefix); -int cmd_merge_index(int argc, const char **argv, const char *prefix); -int cmd_merge_ours(int argc, const char **argv, const char *prefix); -int cmd_merge_file(int argc, const char **argv, const char *prefix); -int cmd_merge_recursive(int argc, const char **argv, const char *prefix); -int cmd_merge_tree(int argc, const char **argv, const char *prefix); -int cmd_mktag(int argc, const char **argv, const char *prefix); -int cmd_mktree(int argc, const char **argv, const char *prefix); -int cmd_multi_pack_index(int argc, const char **argv, const char *prefix); -int cmd_mv(int argc, const char **argv, const char *prefix); -int cmd_name_rev(int argc, const char **argv, const char *prefix); -int cmd_notes(int argc, const char **argv, const char *prefix); -int cmd_pack_objects(int argc, const char **argv, const char *prefix); -int cmd_pack_redundant(int argc, const char **argv, const char *prefix); -int cmd_patch_id(int argc, const char **argv, const char *prefix); -int cmd_prune(int argc, const char **argv, const char *prefix); -int cmd_prune_packed(int argc, const char **argv, const char *prefix); -int cmd_pull(int argc, const char **argv, const char *prefix); -int cmd_push(int argc, const char **argv, const char *prefix); -int cmd_range_diff(int argc, const char **argv, const char *prefix); -int cmd_read_tree(int argc, const char **argv, const char *prefix); -int cmd_rebase(int argc, const char **argv, const char *prefix); -int cmd_rebase__interactive(int argc, const char **argv, const char *prefix); -int cmd_receive_pack(int argc, const char **argv, const char *prefix); -int cmd_reflog(int argc, const char **argv, const char *prefix); -int cmd_refs(int argc, const char **argv, const char *prefix); -int cmd_remote(int argc, const char **argv, const char *prefix); -int cmd_remote_ext(int argc, const char **argv, const char *prefix); -int cmd_remote_fd(int argc, const char **argv, const char *prefix); -int cmd_repack(int argc, const char **argv, const char *prefix); -int cmd_replay(int argc, const char **argv, const char *prefix); -int cmd_rerere(int argc, const char **argv, const char *prefix); -int cmd_reset(int argc, const char **argv, const char *prefix); -int cmd_restore(int argc, const char **argv, const char *prefix); -int cmd_rev_list(int argc, const char **argv, const char *prefix); -int cmd_rev_parse(int argc, const char **argv, const char *prefix); -int cmd_revert(int argc, const char **argv, const char *prefix); -int cmd_rm(int argc, const char **argv, const char *prefix); -int cmd_send_pack(int argc, const char **argv, const char *prefix); -int cmd_shortlog(int argc, const char **argv, const char *prefix); -int cmd_show(int argc, const char **argv, const char *prefix); -int cmd_show_branch(int argc, const char **argv, const char *prefix); -int cmd_show_index(int argc, const char **argv, const char *prefix); -int cmd_sparse_checkout(int argc, const char **argv, const char *prefix); -int cmd_status(int argc, const char **argv, const char *prefix); -int cmd_stash(int argc, const char **argv, const char *prefix); -int cmd_stripspace(int argc, const char **argv, const char *prefix); -int cmd_submodule__helper(int argc, const char **argv, const char *prefix); -int cmd_switch(int argc, const char **argv, const char *prefix); -int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); -int cmd_tag(int argc, const char **argv, const char *prefix); -int cmd_unpack_file(int argc, const char **argv, const char *prefix); -int cmd_unpack_objects(int argc, const char **argv, const char *prefix); -int cmd_update_index(int argc, const char **argv, const char *prefix); -int cmd_update_ref(int argc, const char **argv, const char *prefix); -int cmd_update_server_info(int argc, const char **argv, const char *prefix); -int cmd_upload_archive(int argc, const char **argv, const char *prefix); -int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix); -int cmd_upload_pack(int argc, const char **argv, const char *prefix); -int cmd_var(int argc, const char **argv, const char *prefix); -int cmd_verify_commit(int argc, const char **argv, const char *prefix); -int cmd_verify_tag(int argc, const char **argv, const char *prefix); -int cmd_version(int argc, const char **argv, const char *prefix); -int cmd_whatchanged(int argc, const char **argv, const char *prefix); -int cmd_worktree(int argc, const char **argv, const char *prefix); -int cmd_write_tree(int argc, const char **argv, const char *prefix); -int cmd_verify_pack(int argc, const char **argv, const char *prefix); -int cmd_show_ref(int argc, const char **argv, const char *prefix); -int cmd_pack_refs(int argc, const char **argv, const char *prefix); -int cmd_replace(int argc, const char **argv, const char *prefix); +int cmd_add(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_am(int argc, const char **argv, const char *prefix, struct repository *repo); +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_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); +int cmd_bugreport(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_bundle(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_cat_file(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_checkout(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_checkout__worker(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_checkout_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_attr(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_ignore(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_mailmap(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_check_ref_format(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_cherry(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_cherry_pick(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_clone(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_clean(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_column(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_commit(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_commit_graph(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_commit_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_config(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_count_objects(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential_cache(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_credential_store(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_describe(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diagnose(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff_files(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_diff_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_difftool(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_env__helper(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fast_export(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fast_import(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fetch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fetch_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_for_each_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_for_each_repo(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_format_patch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fsck(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_gc(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_grep(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_hash_object(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_help(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_hook(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_index_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_init_db(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_interpret_trailers(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_log_reflog(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_log(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_ls_files(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_ls_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_ls_remote(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mailinfo(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mailsplit(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_maintenance(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_base(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_ours(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_file(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_recursive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_merge_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mktag(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mktree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_multi_pack_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_mv(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_name_rev(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_notes(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pack_objects(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pack_redundant(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_patch_id(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_prune(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_prune_packed(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pull(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_push(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_range_diff(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_read_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rebase(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rebase__interactive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_receive_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_reflog(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_refs(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_remote(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_remote_ext(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_remote_fd(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_repack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_replay(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rerere(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_reset(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_restore(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rev_list(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rev_parse(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_revert(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_rm(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_send_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_shortlog(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show_branch(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_sparse_checkout(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_status(int argc, const char **argv, const char *prefix, struct repository *repo); +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_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); +int cmd_unpack_file(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_unpack_objects(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_update_index(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_update_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_update_server_info(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_upload_archive(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_upload_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_var(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_verify_commit(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_verify_tag(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_version(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_whatchanged(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_worktree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_write_tree(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_verify_pack(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_show_ref(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_pack_refs(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_replace(int argc, const char **argv, const char *prefix, struct repository *repo); #endif diff --git a/builtin/add.c b/builtin/add.c index 40b61ef90d..7d35307792 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -3,7 +3,6 @@ * * Copyright (C) 2006 Linus Torvalds */ - #include "builtin.h" #include "advice.h" #include "config.h" @@ -18,7 +17,6 @@ #include "preload-index.h" #include "diff.h" #include "read-cache.h" -#include "repository.h" #include "revision.h" #include "bulk-checkin.h" #include "strvec.h" @@ -36,24 +34,27 @@ static int pathspec_file_nul; static int include_sparse; static const char *pathspec_from_file; -static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only) +static int chmod_pathspec(struct repository *repo, + struct pathspec *pathspec, + char flip, + int show_only) { int i, ret = 0; - for (i = 0; i < the_repository->index->cache_nr; i++) { - struct cache_entry *ce = the_repository->index->cache[i]; + for (i = 0; i < repo->index->cache_nr; i++) { + struct cache_entry *ce = repo->index->cache[i]; int err; if (!include_sparse && (ce_skip_worktree(ce) || - !path_in_sparse_checkout(ce->name, the_repository->index))) + !path_in_sparse_checkout(ce->name, repo->index))) continue; - if (pathspec && !ce_path_match(the_repository->index, ce, pathspec, NULL)) + if (pathspec && !ce_path_match(repo->index, ce, pathspec, NULL)) continue; if (!show_only) - err = chmod_index_entry(the_repository->index, ce, flip); + err = chmod_index_entry(repo->index, ce, flip); else err = S_ISREG(ce->ce_mode) ? 0 : -1; @@ -64,31 +65,36 @@ static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only) return ret; } -static int renormalize_tracked_files(const struct pathspec *pathspec, int flags) +static int renormalize_tracked_files(struct repository *repo, + const struct pathspec *pathspec, + int flags) { int i, retval = 0; - for (i = 0; i < the_repository->index->cache_nr; i++) { - struct cache_entry *ce = the_repository->index->cache[i]; + for (i = 0; i < repo->index->cache_nr; i++) { + struct cache_entry *ce = repo->index->cache[i]; if (!include_sparse && (ce_skip_worktree(ce) || - !path_in_sparse_checkout(ce->name, the_repository->index))) + !path_in_sparse_checkout(ce->name, repo->index))) continue; if (ce_stage(ce)) continue; /* do not touch unmerged paths */ if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode)) continue; /* do not touch non blobs */ - if (pathspec && !ce_path_match(the_repository->index, ce, pathspec, NULL)) + if (pathspec && !ce_path_match(repo->index, ce, pathspec, NULL)) continue; - retval |= add_file_to_index(the_repository->index, ce->name, + retval |= add_file_to_index(repo->index, ce->name, flags | ADD_CACHE_RENORMALIZE); } return retval; } -static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, int prefix) +static char *prune_directory(struct repository *repo, + struct dir_struct *dir, + struct pathspec *pathspec, + int prefix) { char *seen; int i; @@ -100,16 +106,16 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec, i = dir->nr; while (--i >= 0) { struct dir_entry *entry = *src++; - if (dir_path_match(the_repository->index, entry, pathspec, prefix, seen)) + if (dir_path_match(repo->index, entry, pathspec, prefix, seen)) *dst++ = entry; } dir->nr = dst - dir->entries; - add_pathspec_matches_against_index(pathspec, the_repository->index, seen, + add_pathspec_matches_against_index(pathspec, repo->index, seen, PS_IGNORE_SKIP_WORKTREE); return seen; } -static int refresh(int verbose, const struct pathspec *pathspec) +static int refresh(struct repository *repo, int verbose, const struct pathspec *pathspec) { char *seen; int i, ret = 0; @@ -119,14 +125,14 @@ static int refresh(int verbose, const struct pathspec *pathspec) (verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET); seen = xcalloc(pathspec->nr, 1); - refresh_index(the_repository->index, flags, pathspec, seen, + refresh_index(repo->index, flags, pathspec, seen, _("Unstaged changes after refreshing the index:")); for (i = 0; i < pathspec->nr; i++) { if (!seen[i]) { const char *path = pathspec->items[i].original; if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) || - !path_in_sparse_checkout(path, the_repository->index)) { + !path_in_sparse_checkout(path, repo->index)) { string_list_append(&only_match_skip_worktree, pathspec->items[i].original); } else { @@ -147,7 +153,10 @@ static int refresh(int verbose, const struct pathspec *pathspec) return ret; } -int interactive_add(const char **argv, const char *prefix, int patch) +int interactive_add(struct repository *repo, + const char **argv, + const char *prefix, + int patch) { struct pathspec pathspec; int ret; @@ -159,28 +168,31 @@ int interactive_add(const char **argv, const char *prefix, int patch) prefix, argv); if (patch) - ret = !!run_add_p(the_repository, ADD_P_ADD, NULL, &pathspec); + ret = !!run_add_p(repo, ADD_P_ADD, NULL, &pathspec); else - ret = !!run_add_i(the_repository, &pathspec); + ret = !!run_add_i(repo, &pathspec); clear_pathspec(&pathspec); return ret; } -static int edit_patch(int argc, const char **argv, const char *prefix) +static int edit_patch(struct repository *repo, + int argc, + const char **argv, + const char *prefix) { - char *file = git_pathdup("ADD_EDIT.patch"); + char *file = repo_git_path(repo, "ADD_EDIT.patch"); struct child_process child = CHILD_PROCESS_INIT; struct rev_info rev; int out; struct stat st; - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(repo, git_diff_basic_config, NULL); - if (repo_read_index(the_repository) < 0) + if (repo_read_index(repo) < 0) die(_("could not read the index")); - repo_init_revisions(the_repository, &rev, prefix); + repo_init_revisions(repo, &rev, prefix); rev.diffopt.context = 7; argc = setup_revisions(argc, argv, &rev, NULL); @@ -318,7 +330,7 @@ static void check_embedded_repo(const char *path) strbuf_release(&name); } -static int add_files(struct dir_struct *dir, int flags) +static int add_files(struct repository *repo, struct dir_struct *dir, int flags) { int i, exit_status = 0; struct string_list matched_sparse_paths = STRING_LIST_INIT_NODUP; @@ -334,12 +346,12 @@ static int add_files(struct dir_struct *dir, int flags) for (i = 0; i < dir->nr; i++) { if (!include_sparse && - !path_in_sparse_checkout(dir->entries[i]->name, the_repository->index)) { + !path_in_sparse_checkout(dir->entries[i]->name, repo->index)) { string_list_append(&matched_sparse_paths, dir->entries[i]->name); continue; } - if (add_file_to_index(the_repository->index, dir->entries[i]->name, flags)) { + if (add_file_to_index(repo->index, dir->entries[i]->name, flags)) { if (!ignore_add_errors) die(_("adding files failed")); exit_status = 1; @@ -358,7 +370,10 @@ static int add_files(struct dir_struct *dir, int flags) return exit_status; } -int cmd_add(int argc, const char **argv, const char *prefix) +int cmd_add(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { int exit_status = 0; struct pathspec pathspec; @@ -370,7 +385,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) char *ps_matched = NULL; struct lock_file lock_file = LOCK_INIT; - git_config(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); @@ -381,13 +397,13 @@ int cmd_add(int argc, const char **argv, const char *prefix) die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch"); if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch"); - exit(interactive_add(argv + 1, prefix, patch_interactive)); + exit(interactive_add(repo, argv + 1, prefix, patch_interactive)); } if (edit_interactive) { if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--edit"); - return(edit_patch(argc, argv, prefix)); + return(edit_patch(repo, argc, argv, prefix)); } argc--; argv++; @@ -410,10 +426,10 @@ int cmd_add(int argc, const char **argv, const char *prefix) add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize; require_pathspec = !(take_worktree_changes || (0 < addremove_explicit)); - prepare_repo_settings(the_repository); - the_repository->settings.command_requires_full_index = 0; + prepare_repo_settings(repo); + repo->settings.command_requires_full_index = 0; - repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR); + repo_hold_locked_index(repo, &lock_file, LOCK_DIE_ON_ERROR); /* * Check the "pathspec '%s' did not match any files" block @@ -454,11 +470,11 @@ int cmd_add(int argc, const char **argv, const char *prefix) (!(addremove || take_worktree_changes) ? ADD_CACHE_IGNORE_REMOVAL : 0)); - if (repo_read_index_preload(the_repository, &pathspec, 0) < 0) + if (repo_read_index_preload(repo, &pathspec, 0) < 0) die(_("index file corrupt")); - die_in_unpopulated_submodule(the_repository->index, prefix); - die_path_inside_submodule(the_repository->index, &pathspec); + die_in_unpopulated_submodule(repo->index, prefix); + die_path_inside_submodule(repo->index, &pathspec); if (add_new_files) { int baselen; @@ -470,13 +486,13 @@ int cmd_add(int argc, const char **argv, const char *prefix) } /* This picks up the paths that are not tracked */ - baselen = fill_directory(&dir, the_repository->index, &pathspec); + baselen = fill_directory(&dir, repo->index, &pathspec); if (pathspec.nr) - seen = prune_directory(&dir, &pathspec, baselen); + seen = prune_directory(repo, &dir, &pathspec, baselen); } if (refresh_only) { - exit_status |= refresh(verbose, &pathspec); + exit_status |= refresh(repo, verbose, &pathspec); goto finish; } @@ -487,7 +503,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (!seen) seen = find_pathspecs_matching_against_index(&pathspec, - the_repository->index, PS_IGNORE_SKIP_WORKTREE); + repo->index, PS_IGNORE_SKIP_WORKTREE); /* * file_exists() assumes exact match @@ -523,8 +539,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) !file_exists(path)) { if (ignore_missing) { int dtype = DT_UNKNOWN; - if (is_excluded(&dir, the_repository->index, path, &dtype)) - dir_add_ignored(&dir, the_repository->index, + if (is_excluded(&dir, repo->index, path, &dtype)) + dir_add_ignored(&dir, repo->index, path, pathspec.items[i].len); } else die(_("pathspec '%s' did not match any files"), @@ -547,9 +563,9 @@ int cmd_add(int argc, const char **argv, const char *prefix) ps_matched = xcalloc(pathspec.nr, 1); if (add_renormalize) - exit_status |= renormalize_tracked_files(&pathspec, flags); + exit_status |= renormalize_tracked_files(repo, &pathspec, flags); else - exit_status |= add_files_to_cache(the_repository, prefix, + exit_status |= add_files_to_cache(repo, prefix, &pathspec, ps_matched, include_sparse, flags); @@ -558,14 +574,14 @@ int cmd_add(int argc, const char **argv, const char *prefix) exit(128); if (add_new_files) - exit_status |= add_files(&dir, flags); + exit_status |= add_files(repo, &dir, flags); if (chmod_arg && pathspec.nr) - exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only); + exit_status |= chmod_pathspec(repo, &pathspec, chmod_arg[0], show_only); end_odb_transaction(); finish: - if (write_locked_index(the_repository->index, &lock_file, + if (write_locked_index(repo->index, &lock_file, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write new index file")); diff --git a/builtin/am.c b/builtin/am.c index d8875ad402..bfa95147cf 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -4,6 +4,7 @@ * Based on git-am.sh by Junio C Hamano. */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "advice.h" @@ -38,7 +39,6 @@ #include "string-list.h" #include "pager.h" #include "path.h" -#include "repository.h" #include "pretty.h" /** @@ -1544,7 +1544,8 @@ static int run_apply(const struct am_state *state, const char *index_file) if (index_file) { /* Reload index as apply_all_patches() will have modified it. */ discard_index(the_repository->index); - read_index_from(the_repository->index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, + repo_get_git_dir(the_repository)); } return 0; @@ -1587,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa return error("could not build fake ancestor"); discard_index(the_repository->index); - read_index_from(the_repository->index, index_path, get_git_dir()); + read_index_from(the_repository->index, index_path, repo_get_git_dir(the_repository)); if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL)) return error(_("Repository lacks necessary blobs to fall back on 3-way merge.")); @@ -1667,7 +1668,9 @@ static void do_commit(const struct am_state *state) if (!state->no_verify && run_hooks(the_repository, "pre-applypatch")) exit(1); - if (write_index_as_tree(&tree, the_repository->index, get_index_file(), 0, NULL)) + if (write_index_as_tree(&tree, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) die(_("git write-tree failed to write a tree")); if (!repo_get_oid_commit(the_repository, "HEAD", &parent)) { @@ -2077,7 +2080,9 @@ static int clean_index(const struct object_id *head, const struct object_id *rem if (fast_forward_to(head_tree, head_tree, 1)) return -1; - if (write_index_as_tree(&index, the_repository->index, get_index_file(), 0, NULL)) + if (write_index_as_tree(&index, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) return -1; index_tree = parse_tree_indirect(&index); @@ -2298,7 +2303,10 @@ static int parse_opt_show_current_patch(const struct option *opt, const char *ar return 0; } -int cmd_am(int argc, const char **argv, const char *prefix) +int cmd_am(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct am_state state; int binary = -1; diff --git a/builtin/annotate.c b/builtin/annotate.c index 58ff977a23..7f754f2309 100644 --- a/builtin/annotate.c +++ b/builtin/annotate.c @@ -3,20 +3,34 @@ * * Copyright (C) 2006 Ryan Anderson */ + #include "git-compat-util.h" #include "builtin.h" #include "strvec.h" -int cmd_annotate(int argc, const char **argv, const char *prefix) +int cmd_annotate(int argc, + const char **argv, + const char *prefix, + 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); + /* + * `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/apply.c b/builtin/apply.c index d623c52f78..84f1863d3a 100644 --- a/builtin/apply.c +++ b/builtin/apply.c @@ -1,6 +1,6 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" -#include "repository.h" #include "hash.h" #include "apply.h" @@ -9,7 +9,10 @@ static const char * const apply_usage[] = { NULL }; -int cmd_apply(int argc, const char **argv, const char *prefix) +int cmd_apply(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int force_apply = 0; int options = 0; diff --git a/builtin/archive.c b/builtin/archive.c index 63f02990d1..13ea7308c8 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -8,7 +8,6 @@ #include "transport.h" #include "parse-options.h" #include "pkt-line.h" -#include "repository.h" static void create_output_file(const char *output_file) { @@ -76,7 +75,10 @@ static int run_remote_archiver(int argc, const char **argv, PARSE_OPT_KEEP_UNKNOWN_OPT | \ PARSE_OPT_NO_INTERNAL_HELP ) -int cmd_archive(int argc, const char **argv, const char *prefix) +int cmd_archive(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { const char *exec = "git-upload-archive"; char *output = NULL; @@ -107,7 +109,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix) 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/bisect.c b/builtin/bisect.c index c8aa92b19d..8166d4abf5 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "copy.h" #include "environment.h" @@ -1311,7 +1312,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"), @@ -1319,7 +1321,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 }; @@ -1332,7 +1335,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 }; @@ -1343,7 +1347,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 }; @@ -1357,12 +1362,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 }; @@ -1375,7 +1383,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 }; @@ -1387,7 +1396,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 }; @@ -1398,7 +1408,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 }; @@ -1411,7 +1422,10 @@ static int cmd_bisect__run(int argc, const char **argv, const char *prefix UNUSE return res; } -int cmd_bisect(int argc, const char **argv, const char *prefix) +int cmd_bisect(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { int res = 0; parse_opt_subcommand_fn *fn = NULL; @@ -1447,7 +1461,7 @@ int cmd_bisect(int argc, const char **argv, const char *prefix) } 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 35e975fb13..6a7bb3b072 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -4,7 +4,7 @@ * 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" @@ -12,7 +12,6 @@ #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "commit.h" #include "diff.h" #include "revision.h" @@ -864,7 +863,10 @@ static void build_ignorelist(struct blame_scoreboard *sb, } } -int cmd_blame(int argc, const char **argv, const char *prefix) +int cmd_blame(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; char *path = NULL; @@ -1081,7 +1083,7 @@ parse_done: path = add_prefix(prefix, argv[1]); argv[1] = argv[2]; } else { /* (2a) */ - if (argc == 2 && is_a_rev(argv[1]) && !get_git_work_tree()) + if (argc == 2 && is_a_rev(argv[1]) && !repo_get_work_tree(the_repository)) die("missing <path> to blame"); path = add_prefix(prefix, argv[argc - 1]); } @@ -1214,12 +1216,6 @@ parse_done: 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); @@ -1228,6 +1224,12 @@ parse_done: } 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 3f870741bf..200909c23e 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -4,7 +4,7 @@ * 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 +257,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); @@ -579,7 +579,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. @@ -704,7 +704,10 @@ static int edit_branch_description(const char *branch_name) return 0; } -int cmd_branch(int argc, const char **argv, const char *prefix) +int cmd_branch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { /* possible actions */ int delete = 0, rename = 0, copy = 0, list = 0, @@ -719,6 +722,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) 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")), @@ -848,15 +852,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix) 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) @@ -878,37 +882,43 @@ int cmd_branch(int argc, const char **argv, const char *prefix) string_list_clear(&output, 0); ref_sorting_release(sorting); ref_filter_clear(&filter); - return 0; + ref_format_clear(&format); + + 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")); @@ -929,7 +939,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) 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")); @@ -959,7 +969,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) 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")); @@ -996,12 +1006,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix) 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 bdfed3d8f1..7c2df035c9 100644 --- a/builtin/bugreport.c +++ b/builtin/bugreport.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "editor.h" @@ -98,7 +99,10 @@ static void get_header(struct strbuf *buf, const char *title) strbuf_addf(buf, "\n\n[%s]\n", title); } -int cmd_bugreport(int argc, const char **argv, const char *prefix) +int cmd_bugreport(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf buffer = STRBUF_INIT; struct strbuf report_path = STRBUF_INIT; diff --git a/builtin/bundle.c b/builtin/bundle.c index b858552ee6..1e170e9278 100644 --- a/builtin/bundle.c +++ b/builtin/bundle.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -5,7 +6,6 @@ #include "strvec.h" #include "parse-options.h" #include "pkt-line.h" -#include "repository.h" #include "bundle.h" /* @@ -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 @@ cleanup: 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 @@ cleanup: 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); @@ -228,7 +232,10 @@ cleanup: return ret; } -int cmd_bundle(int argc, const char **argv, const char *prefix) +int cmd_bundle(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -244,5 +251,5 @@ int cmd_bundle(int argc, const char **argv, const char *prefix) 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 1afdfb5cba..d67b101c20 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "convert.h" @@ -191,7 +191,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, const char *ls_args[3] = { NULL }; ls_args[0] = "ls-tree"; ls_args[1] = obj_name; - ret = cmd_ls_tree(2, ls_args, NULL); + ret = cmd_ls_tree(2, ls_args, NULL, the_repository); goto cleanup; } @@ -827,15 +827,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); @@ -923,7 +924,10 @@ static int batch_option_callback(const struct option *opt, return 0; } -int cmd_cat_file(int argc, const char **argv, const char *prefix) +int cmd_cat_file(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int opt = 0; int opt_cw = 0; diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 9376810710..7cf275b893 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "attr.h" @@ -5,7 +6,6 @@ #include "gettext.h" #include "object-name.h" #include "quote.h" -#include "repository.h" #include "setup.h" #include "parse-options.h" #include "write-or-die.h" @@ -107,7 +107,10 @@ static NORETURN void error_with_usage(const char *msg) usage_with_options(check_attr_usage, check_attr_options); } -int cmd_check_attr(int argc, const char **argv, const char *prefix) +int cmd_check_attr(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct attr_check *check; struct object_id initialized_oid; diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 2bda6a1d46..7b7831d13a 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" @@ -5,7 +6,6 @@ #include "quote.h" #include "pathspec.h" #include "parse-options.h" -#include "repository.h" #include "submodule.h" #include "write-or-die.h" @@ -151,7 +151,10 @@ static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) return num_ignored; } -int cmd_check_ignore(int argc, const char **argv, const char *prefix) +int cmd_check_ignore(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int num_ignored; struct dir_struct dir = DIR_INIT; diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index 2334b57222..df00b5ee13 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -47,7 +48,10 @@ static void check_mailmap(struct string_list *mailmap, const char *contact) printf("<%.*s>\n", (int)maillen, mail); } -int cmd_check_mailmap(int argc, const char **argv, const char *prefix) +int cmd_check_mailmap(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct string_list mailmap = STRING_LIST_INIT_NODUP; diff --git a/builtin/check-ref-format.c b/builtin/check-ref-format.c index 5eb6bdc3f6..cef1ffe3ce 100644 --- a/builtin/check-ref-format.c +++ b/builtin/check-ref-format.c @@ -1,7 +1,6 @@ /* * GIT - The information manager from hell */ - #include "builtin.h" #include "refs.h" #include "setup.h" @@ -43,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); @@ -51,7 +50,10 @@ static int check_ref_format_branch(const char *arg) return 0; } -int cmd_check_ref_format(int argc, const char **argv, const char *prefix) +int cmd_check_ref_format(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; int normalize = 0; diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index 6b62b5375b..ff6cdccc21 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "entry.h" @@ -113,7 +114,10 @@ static const char * const checkout_worker_usage[] = { NULL }; -int cmd_checkout__worker(int argc, const char **argv, const char *prefix) +int cmd_checkout__worker(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout state = CHECKOUT_INIT; struct option checkout_worker_options[] = { diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 29e744d11b..6dd38eb05d 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -4,13 +4,12 @@ * Copyright (C) 2005 Linus Torvalds * */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "lockfile.h" #include "quote.h" -#include "repository.h" #include "cache-tree.h" #include "parse-options.h" #include "entry.h" @@ -208,7 +207,10 @@ static int option_parse_stage(const struct option *opt, return 0; } -int cmd_checkout_index(int argc, const char **argv, const char *prefix) +int cmd_checkout_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct lock_file lock_file = LOCK_INIT; diff --git a/builtin/checkout.c b/builtin/checkout.c index 4cfe6fab50..5e5afa0f26 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "branch.h" @@ -23,6 +24,7 @@ #include "read-cache.h" #include "refs.h" #include "remote.h" +#include "repo-settings.h" #include "resolve-undo.h" #include "revision.h" #include "setup.h" @@ -740,7 +742,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); @@ -950,11 +952,13 @@ static void update_refs_for_switch(const struct checkout_opts *opts, const char *old_desc, *reflog_msg; if (opts->new_branch) { if (opts->new_orphan_branch) { + enum log_refs_config log_all_ref_updates = + repo_settings_get_log_all_ref_updates(the_repository); char *refname; refname = mkpathdup("refs/heads/%s", opts->new_orphan_branch); if (opts->new_branch_log && - !should_autocreate_reflog(refname)) { + !should_autocreate_reflog(log_all_ref_updates, refname)) { int ret; struct strbuf err = STRBUF_INIT; @@ -1712,7 +1716,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); @@ -1953,7 +1957,10 @@ static int checkout_main(int argc, const char **argv, const char *prefix, return ret; } -int cmd_checkout(int argc, const char **argv, const char *prefix) +int cmd_checkout(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout_opts opts = CHECKOUT_OPTS_INIT; struct option *options; @@ -2000,7 +2007,10 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) checkout_usage); } -int cmd_switch(int argc, const char **argv, const char *prefix) +int cmd_switch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout_opts opts = CHECKOUT_OPTS_INIT; struct option *options = NULL; @@ -2036,7 +2046,10 @@ int cmd_switch(int argc, const char **argv, const char *prefix) switch_branch_usage); } -int cmd_restore(int argc, const char **argv, const char *prefix) +int cmd_restore(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct checkout_opts opts = CHECKOUT_OPTS_INIT; struct option *options; diff --git a/builtin/clean.c b/builtin/clean.c index ded5a91534..9c48dd0271 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -5,7 +5,7 @@ * * Based on git-clean.sh by Pavel Roskin */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -14,7 +14,6 @@ #include "parse-options.h" #include "path.h" #include "read-cache-ll.h" -#include "repository.h" #include "setup.h" #include "string-list.h" #include "quote.h" @@ -915,7 +914,10 @@ static void correct_untracked_entries(struct dir_struct *dir) dir->nr = dst; } -int cmd_clean(int argc, const char **argv, const char *prefix) +int cmd_clean(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, res; int dry_run = 0, remove_directories = 0, quiet = 0, ignored = 0; diff --git a/builtin/clone.c b/builtin/clone.c index 269b6e18a4..21721db28a 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -7,8 +7,9 @@ * * Clone a repository into a different directory that does not yet exist. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "advice.h" #include "config.h" @@ -146,8 +147,8 @@ static struct option builtin_clone_options[] = { 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_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, "no-tags", &option_no_tags, @@ -573,7 +574,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); @@ -585,7 +586,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); @@ -956,7 +957,10 @@ static int path_exists(const char *path) return !stat(path, &sb); } -int cmd_clone(int argc, const char **argv, const char *prefix) +int cmd_clone(int argc, + const char **argv, + const char *prefix, + struct repository *repository UNUSED) { int is_bundle = 0, is_local; int reject_shallow = 0; @@ -1399,8 +1403,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix) * 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")); @@ -1409,6 +1422,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix) bundle_uri); else if (has_heuristic) git_config_set_gently("fetch.bundleuri", bundle_uri); + + 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 @@ -1418,12 +1435,26 @@ int cmd_clone(int argc, const char **argv, const char *prefix) 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); @@ -1555,7 +1586,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) 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/column.c b/builtin/column.c index 10ff7e0166..50314cc255 100644 --- a/builtin/column.c +++ b/builtin/column.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -18,7 +19,10 @@ static int column_config(const char *var, const char *value, return git_column_config(var, value, cb, &colopts); } -int cmd_column(int argc, const char **argv, const char *prefix) +int cmd_column(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct string_list list = STRING_LIST_INIT_DUP; struct strbuf sb = STRBUF_INIT; diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 7102ee90a0..bd70d052e7 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -1,11 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "commit.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "parse-options.h" -#include "repository.h" #include "commit-graph.h" #include "object-store-ll.h" #include "progress.h" @@ -63,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; @@ -95,7 +95,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix) usage_with_options(builtin_commit_graph_verify_usage, options); if (!opts.obj_dir) - opts.obj_dir = get_object_directory(); + opts.obj_dir = repo_get_object_directory(the_repository); if (opts.shallow) flags |= COMMIT_GRAPH_VERIFY_SHALLOW; if (opts.progress) @@ -215,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; @@ -275,7 +276,7 @@ static int graph_write(int argc, const char **argv, const char *prefix) if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1) die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs")); if (!opts.obj_dir) - opts.obj_dir = get_object_directory(); + opts.obj_dir = repo_get_object_directory(the_repository); if (opts.append) flags |= COMMIT_GRAPH_WRITE_APPEND; if (opts.split) @@ -331,7 +332,10 @@ cleanup: return result; } -int cmd_commit_graph(int argc, const char **argv, const char *prefix) +int cmd_commit_graph(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_commit_graph_options[] = { @@ -350,5 +354,5 @@ int cmd_commit_graph(int argc, const char **argv, const char *prefix) 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 84bb450222..2ca1a57ebb 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -3,13 +3,14 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "hex.h" #include "object-name.h" #include "object-store-ll.h" -#include "repository.h" + #include "commit.h" #include "parse-options.h" @@ -90,7 +91,10 @@ static int parse_file_arg_callback(const struct option *opt, return 0; } -int cmd_commit_tree(int argc, const char **argv, const char *prefix) +int cmd_commit_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static struct strbuf buffer = STRBUF_INIT; struct commit_list *parents = NULL; diff --git a/builtin/commit.c b/builtin/commit.c index b2033c4887..71d674138c 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -4,7 +4,7 @@ * 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 #include "builtin.h" #include "advice.h" #include "config.h" @@ -26,6 +26,7 @@ #include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "string-list.h" #include "rerere.h" #include "unpack-trees.h" @@ -134,7 +135,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; @@ -395,7 +396,7 @@ static const char *prepare_index(const char **argv, const char *prefix, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - if (interactive_add(argv, prefix, patch_interactive) != 0) + if (interactive_add(the_repository, argv, prefix, patch_interactive) != 0) die(_("interactive add failed")); the_repository->index_file = old_repo_index_file; @@ -407,7 +408,7 @@ static const char *prepare_index(const char **argv, const char *prefix, discard_index(the_repository->index); read_index_from(the_repository->index, get_lock_file_path(&index_lock), - get_git_dir()); + repo_get_git_dir(the_repository)); if (cache_tree_update(the_repository->index, WRITE_TREE_SILENT) == 0) { if (reopen_lock_file(&index_lock) < 0) die(_("unable to write index file")); @@ -472,7 +473,7 @@ static const char *prepare_index(const char **argv, const char *prefix, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write new index file")); commit_style = COMMIT_AS_IS; - ret = get_index_file(); + ret = repo_get_index_file(the_repository); goto out; } @@ -534,7 +535,7 @@ static const char *prepare_index(const char **argv, const char *prefix, discard_index(the_repository->index); ret = get_lock_file_path(&false_lock); - read_index_from(the_repository->index, ret, get_git_dir()); + read_index_from(the_repository->index, ret, repo_get_git_dir(the_repository)); out: string_list_clear(&partial, 0); clear_pathspec(&pathspec); @@ -727,6 +728,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, @@ -990,7 +998,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"; @@ -1072,7 +1080,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, */ discard_index(the_repository->index); } - read_index_from(the_repository->index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, repo_get_git_dir(the_repository)); if (cache_tree_update(the_repository->index, 0)) { error(_("Error building trees")); @@ -1379,8 +1387,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) @@ -1502,7 +1508,10 @@ static int git_status_config(const char *k, const char *v, return git_diff_ui_config(k, v, ctx, NULL); } -int cmd_status(int argc, const char **argv, const char *prefix) +int cmd_status(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { static int no_renames = -1; static const char *rename_score_arg = (const char *)-1; @@ -1625,8 +1634,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; @@ -1641,9 +1652,13 @@ static int git_commit_config(const char *k, const char *v, return git_status_config(k, v, ctx, s); } -int cmd_commit(int argc, const char **argv, const char *prefix) +int cmd_commit(int argc, + const char **argv, + const char *prefix, + 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")), @@ -1743,6 +1758,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix) 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); @@ -1873,8 +1894,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) repo_rerere(the_repository, 0); run_auto_maintenance(quiet); - run_commit_hook(use_editor, get_index_file(), NULL, "post-commit", - NULL); + run_commit_hook(use_editor, repo_get_index_file(the_repository), + NULL, "post-commit", NULL); if (amend && !no_post_rewrite) { commit_post_rewrite(the_repository, current_head, &oid); } diff --git a/builtin/config.c b/builtin/config.c index 95c8a00915..16e6e30555 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -1,10 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" #include "color.h" #include "editor.h" #include "environment.h" -#include "repository.h" #include "gettext.h" #include "ident.h" #include "parse-options.h" @@ -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 }; @@ -807,8 +807,8 @@ static void location_options_init(struct config_location_options *opts, else opts->options.respect_includes = opts->respect_includes_opt; if (startup_info->have_repository) { - opts->options.commondir = get_git_common_dir(); - opts->options.git_dir = get_git_dir(); + opts->options.commondir = repo_get_common_dir(the_repository); + opts->options.git_dir = repo_get_git_dir(the_repository); } } @@ -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 @@ out: 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[] = { @@ -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[] = { @@ -1392,7 +1399,10 @@ out: return ret; } -int cmd_config(int argc, const char **argv, const char *prefix) +int cmd_config(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *subcommand = NULL; struct option subcommand_opts[] = { @@ -1419,7 +1429,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) 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 ec6098a149..1e89148ed7 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -3,14 +3,12 @@ * * Copyright (c) 2006 Junio C Hamano */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "path.h" -#include "repository.h" #include "parse-options.h" #include "quote.h" #include "packfile.h" @@ -69,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; @@ -95,7 +93,10 @@ static char const * const count_objects_usage[] = { NULL }; -int cmd_count_objects(int argc, const char **argv, const char *prefix) +int cmd_count_objects(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int human_readable = 0; struct option opts[] = { @@ -116,7 +117,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) report_linked_checkout_garbage(the_repository); } - for_each_loose_file_in_objdir(get_object_directory(), + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), count_loose, count_cruft, NULL, NULL); if (verbose) { diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 4952b22547..bc22f5c6d2 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "gettext.h" @@ -287,7 +288,10 @@ static void init_socket_directory(const char *path) free(path_copy); } -int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) +int cmd_credential_cache_daemon(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct tempfile *socket_file; const char *socket_path; @@ -330,7 +334,10 @@ int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) #else -int cmd_credential_cache_daemon(int argc, const char **argv, const char *prefix) +int cmd_credential_cache_daemon(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { const char * const usage[] = { "git credential-cache--daemon [--debug] <socket-path>", diff --git a/builtin/credential-cache.c b/builtin/credential-cache.c index aaf2f8438b..7f733cb756 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) @@ -137,7 +137,10 @@ static void announce_capabilities(void) credential_announce_capabilities(&c, stdout); } -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 *socket_path_arg = NULL; char *socket_path; @@ -186,7 +189,8 @@ int cmd_credential_cache(int argc, const char **argv, const char *prefix) #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-store.c b/builtin/credential-store.c index 97968bfa1c..e669e99dbf 100644 --- a/builtin/credential-store.c +++ b/builtin/credential-store.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -170,7 +171,10 @@ static void lookup_credential(const struct string_list *fns, struct credential * return; /* Found credential */ } -int cmd_credential_store(int argc, const char **argv, const char *prefix) +int cmd_credential_store(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char * const usage[] = { "git credential-store [<options>] <action>", diff --git a/builtin/credential.c b/builtin/credential.c index b72e76dd9a..14c8c6608b 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "credential.h" #include "builtin.h" @@ -6,7 +8,10 @@ static const char usage_msg[] = "git credential (fill|approve|reject)"; -int cmd_credential(int argc, const char **argv, const char *prefix UNUSED) +int cmd_credential(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { const char *op; struct credential c = CREDENTIAL_INIT; diff --git a/builtin/describe.c b/builtin/describe.c index b43093c099..a6ef8af32a 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "environment.h" @@ -365,6 +366,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) { @@ -380,10 +388,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]; @@ -469,9 +473,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)); } } @@ -571,7 +574,10 @@ static int option_parse_exact_match(const struct option *opt, const char *arg, return 0; } -int cmd_describe(int argc, const char **argv, const char *prefix) +int cmd_describe(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED ) { int contains = 0; struct option options[] = { @@ -650,7 +656,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) argv_copy[i] = args.v[i]; argv_copy[args.nr] = NULL; - ret = cmd_name_rev(args.nr, argv_copy, prefix); + ret = cmd_name_rev(args.nr, argv_copy, prefix, the_repository); strvec_clear(&args); free(argv_copy); @@ -716,7 +722,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) BUG("malformed internal diff-index command line"); run_diff_index(&revs, 0); - if (!diff_result_code(&revs.diffopt)) + if (!diff_result_code(&revs)) suffix = NULL; else suffix = dirty; diff --git a/builtin/diagnose.c b/builtin/diagnose.c index 4857a4395b..66a22d918e 100644 --- a/builtin/diagnose.c +++ b/builtin/diagnose.c @@ -11,7 +11,10 @@ static const char * const diagnose_usage[] = { NULL }; -int cmd_diagnose(int argc, const char **argv, const char *prefix) +int cmd_diagnose(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf zip_path = STRBUF_INIT; time_t now = time(NULL); diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 018011f29e..e0e0ccec23 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -3,13 +3,13 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" #include "diff-merges.h" #include "commit.h" #include "preload-index.h" -#include "repository.h" #include "revision.h" static const char diff_files_usage[] = @@ -17,7 +17,10 @@ static const char diff_files_usage[] = "\n" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_files(int argc, const char **argv, const char *prefix) +int cmd_diff_files(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info rev; int result; @@ -82,7 +85,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) if (repo_read_index_preload(the_repository, &rev.diffopt.pathspec, 0) < 0) die_errno("repo_read_index_preload"); run_diff_files(&rev, options); - result = diff_result_code(&rev.diffopt); + result = diff_result_code(&rev); release_revisions(&rev); return result; } diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 685b60284f..ad503624c0 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -1,10 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" #include "diff-merges.h" #include "commit.h" #include "preload-index.h" -#include "repository.h" #include "revision.h" #include "setup.h" @@ -14,7 +14,10 @@ static const char diff_cache_usage[] = "\n" COMMON_DIFF_OPTIONS_HELP; -int cmd_diff_index(int argc, const char **argv, const char *prefix) +int cmd_diff_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info rev; unsigned int option = 0; @@ -75,7 +78,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) return -1; } run_diff_index(&rev, option); - result = diff_result_code(&rev.diffopt); + result = diff_result_code(&rev); release_revisions(&rev); return result; } diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index b8df1d4b79..4b6656bb9f 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" @@ -6,7 +7,6 @@ #include "hex.h" #include "log-tree.h" #include "read-cache-ll.h" -#include "repository.h" #include "revision.h" #include "tmp-objdir.h" #include "tree.h" @@ -108,7 +108,10 @@ static void diff_tree_tweak_rev(struct rev_info *rev) } } -int cmd_diff_tree(int argc, const char **argv, const char *prefix) +int cmd_diff_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { char line[1000]; struct object *tree1, *tree2; @@ -167,13 +170,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) opt->diffopt.rotate_to_strict = 1; - if (opt->remerge_diff) { - opt->remerge_objdir = tmp_objdir_create("remerge-diff"); - if (!opt->remerge_objdir) - die(_("unable to create temporary object directory")); - tmp_objdir_replace_primary_odb(opt->remerge_objdir, 1); - } - /* * NOTE! We expect "a..b" to expand to "^a b" but it is * perfectly valid for revision range parser to yield "b ^a", @@ -238,10 +234,5 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) diff_free(&opt->diffopt); } - if (opt->remerge_diff) { - tmp_objdir_destroy(opt->remerge_objdir); - opt->remerge_objdir = NULL; - } - - return diff_result_code(&opt->diffopt); + return diff_result_code(opt); } diff --git a/builtin/diff.c b/builtin/diff.c index 6eac445579..2fe92f373e 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -3,7 +3,7 @@ * * Copyright (c) 2006 Junio C Hamano */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "ewah/ewok.h" @@ -393,7 +393,10 @@ static void symdiff_release(struct symdiff *sdiff) bitmap_free(sdiff->skip); } -int cmd_diff(int argc, const char **argv, const char *prefix) +int cmd_diff(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct rev_info rev; @@ -619,12 +622,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix) builtin_diff_combined(&rev, argc, argv, ent.objects, ent.nr, first_non_parent); - result = diff_result_code(&rev.diffopt); + result = diff_result_code(&rev); if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); 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 dcc68e190c..40e971e225 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -11,8 +11,9 @@ * * Copyright (C) 2016 Johannes Schindelin */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "config.h" #include "copy.h" @@ -22,6 +23,7 @@ #include "hex.h" #include "parse-options.h" #include "read-cache-ll.h" +#include "repository.h" #include "sparse-index.h" #include "strvec.h" #include "strbuf.h" @@ -214,7 +216,7 @@ static void changed_files(struct hashmap *result, const char *index_path, 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(get_git_dir()); + const char *git_dir = absolute_path(repo_get_git_dir(the_repository)); FILE *fp; strvec_pushl(&update_index.args, @@ -338,7 +340,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, @@ -374,10 +376,11 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix, 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 = get_git_work_tree(); + workdir = repo_get_work_tree(the_repository); /* Setup temp directories */ tmp = getenv("TMPDIR"); @@ -599,9 +602,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; @@ -660,6 +660,12 @@ finish: 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); @@ -690,7 +696,10 @@ static int run_file_diff(int prompt, const char *prefix, return run_command(child); } -int cmd_difftool(int argc, const char **argv, const char *prefix) +int cmd_difftool(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int use_gui_tool = -1, dir_diff = 0, prompt = -1, symlinks = 0, tool_help = 0, no_index = 0; @@ -737,8 +746,8 @@ int cmd_difftool(int argc, const char **argv, const char *prefix) if (!no_index){ setup_work_tree(); - setenv(GIT_DIR_ENVIRONMENT, absolute_path(get_git_dir()), 1); - setenv(GIT_WORK_TREE_ENVIRONMENT, absolute_path(get_git_work_tree()), 1); + 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); } else if (dir_diff) die(_("options '%s' and '%s' cannot be used together"), "--dir-diff", "--no-index"); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index f253b79322..e17f262e8e 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007 Johannes E. Schindelin */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -1180,7 +1181,10 @@ static int parse_opt_anonymize_map(const struct option *opt, return 0; } -int cmd_fast_export(int argc, const char **argv, const char *prefix) +int cmd_fast_export(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; struct commit *commit; diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 2214c105f1..a67c1c4416 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "lockfile.h" #include "object.h" @@ -13,6 +13,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 +180,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; @@ -765,6 +767,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; @@ -805,7 +808,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 +816,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 +834,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); @@ -888,7 +891,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; @@ -966,8 +969,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! */ @@ -1167,8 +1169,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 +1605,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 +1649,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 +1684,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 +2427,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 +2467,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, @@ -3390,6 +3408,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")) { @@ -3537,7 +3556,10 @@ static void parse_argv(void) build_mark_map(&sub_marks_from, &sub_marks_to); } -int cmd_fast_import(int argc, const char **argv, const char *prefix) +int cmd_fast_import(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { unsigned int i; @@ -3658,7 +3680,7 @@ int cmd_fast_import(int argc, const char **argv, const char *prefix) 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 fe404d1305..62e8c3aa6b 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -43,12 +44,16 @@ static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, (*sought)[*nr - 1] = ref; } -int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED) +int cmd_fetch_pack(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { int i, ret; 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; @@ -239,6 +244,13 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED) 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); @@ -276,9 +288,13 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix UNUSED) 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 55f97134aa..872ad49834 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1,13 +1,13 @@ /* * "git fetch" */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" #include "gettext.h" #include "environment.h" #include "hex.h" -#include "repository.h" #include "refs.h" #include "refspec.h" #include "object-name.h" @@ -454,13 +454,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 +665,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 +1574,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 %s' will disable the warning\n" + "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, int follow_remote_head, + const char *no_warn_branch) +{ + int result = 0, create_only, is_bare, was_detached; + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, + b_local_head = STRBUF_INIT; + const char *remote = gtransport->remote->name; + 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; + is_bare = is_bare_repository(); + create_only = follow_remote_head == FOLLOW_REMOTE_ALWAYS ? 0 : !is_bare; + if (is_bare) { + 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); + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name); + } + /* make sure it's valid */ + if (!is_bare && !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, 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 +1772,11 @@ static int do_fetch(struct transport *transport, "refs/tags/"); } + if (uses_remote_tracking(transport, rs)) { + must_list_refs = 1; + 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 +1801,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 +1921,13 @@ 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->follow_remote_head, + transport->remote->no_warn_branch)) + ; + /* + * Way too many cases where this can go wrong + * so let's just fail silently for now. + */ cleanup: if (retcode) { @@ -1980,6 +2118,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) { @@ -2138,7 +2278,10 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, return exit_code; } -int cmd_fetch(int argc, const char **argv, const char *prefix) +int cmd_fetch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct fetch_config config = { .display_format = DISPLAY_FORMAT_FULL, @@ -2210,8 +2353,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) 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/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 957786d1b3..189cd1096a 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "fmt-merge-msg.h" @@ -9,7 +10,10 @@ static const char * const fmt_merge_msg_usage[] = { NULL }; -int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) +int cmd_fmt_merge_msg(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { char *inpath = NULL; const char *message = NULL; @@ -67,6 +71,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) return ret; write_in_full(STDOUT_FILENO, output.buf, output.len); + strbuf_release(&input); + strbuf_release(&output); free(inpath); return 0; } diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 5517a4a1c0..715745a262 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "commit.h" #include "config.h" @@ -16,7 +17,10 @@ static char const * const for_each_ref_usage[] = { NULL }; -int cmd_for_each_ref(int argc, const char **argv, const char *prefix) +int cmd_for_each_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; @@ -104,6 +108,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) 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 c4fa41fda9..fae7f91cf1 100644 --- a/builtin/for-each-repo.c +++ b/builtin/for-each-repo.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" #include "path.h" -#include "repository.h" #include "run-command.h" #include "string-list.h" @@ -29,7 +29,10 @@ static int run_command_on_repo(const char *path, int argc, const char ** argv) return run_command(&child); } -int cmd_for_each_repo(int argc, const char **argv, const char *prefix) +int cmd_for_each_repo(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static const char *config_key = NULL; int keep_going = 0; diff --git a/builtin/fsck.c b/builtin/fsck.c index 60f4e6fad9..0196c54eb6 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "commit.h" #include "tree.h" @@ -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 @@ -270,9 +270,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), @@ -391,7 +391,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 +491,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 +534,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. @@ -925,7 +928,10 @@ static struct option fsck_opts[] = { OPT_END(), }; -int cmd_fsck(int argc, const char **argv, const char *prefix) +int cmd_fsck(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; struct object_directory *odb; @@ -963,7 +969,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) 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) @@ -1008,7 +1015,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) &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; diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 1593713f4c..f3f6bd330b 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -1,8 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" #include "dir.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h" @@ -11,7 +11,7 @@ #include "compat/fsmonitor/fsm-health.h" #include "compat/fsmonitor/fsm-listen.h" #include "fsmonitor--daemon.h" -#include "repository.h" + #include "simple-ipc.h" #include "khash.h" #include "run-command.h" @@ -1208,9 +1208,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); @@ -1291,7 +1291,8 @@ static int fsmonitor_run_daemon(void) /* Prepare to (recursively) watch the <worktree-root> directory. */ strbuf_init(&state.path_worktree_watch, 0); - strbuf_addstr(&state.path_worktree_watch, absolute_path(get_git_work_tree())); + strbuf_addstr(&state.path_worktree_watch, + absolute_path(repo_get_work_tree(the_repository))); state.nr_paths_watching = 1; strbuf_init(&state.alias.alias, 0); @@ -1311,7 +1312,9 @@ static int fsmonitor_run_daemon(void) strbuf_addstr(&state.path_gitdir_watch, "/.git"); if (!is_directory(state.path_gitdir_watch.buf)) { strbuf_reset(&state.path_gitdir_watch); - strbuf_addstr(&state.path_gitdir_watch, absolute_path(get_git_dir())); + 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; } @@ -1521,7 +1524,10 @@ static int try_to_start_background_daemon(void) } } -int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix) +int cmd_fsmonitor__daemon(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *subcmd; enum fsmonitor_reason reason; @@ -1584,7 +1590,7 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix) } #else -int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED) +int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) { struct option options[] = { OPT_END() diff --git a/builtin/gc.c b/builtin/gc.c index 7dac971405..4ae5196aed 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -9,13 +9,12 @@ * * Copyright (c) 2006 Shawn O. Pearce */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "date.h" #include "environment.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "tempfile.h" #include "lockfile.h" @@ -139,6 +138,11 @@ struct gc_config { char *repack_filter_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 { \ @@ -154,6 +158,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) @@ -169,6 +174,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")) @@ -207,6 +213,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; @@ -417,7 +426,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; @@ -657,7 +666,10 @@ static void gc_before_repack(struct maintenance_run_opts *opts, } } -int cmd_gc(int argc, const char **argv, const char *prefix) +int cmd_gc(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { int aggressive = 0; int quiet = 0; @@ -1476,9 +1488,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")) { @@ -1559,7 +1571,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; @@ -1621,7 +1634,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[] = { @@ -1685,7 +1699,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; @@ -1766,6 +1781,42 @@ static const char *get_frequency(enum schedule_priority schedule) } } +static const char *extraconfig[] = { + "credential.interactive=false", + "core.askPass=true", /* 'true' returns success, but no output. */ + NULL +}; + +static const char *get_extra_config_parameters(void) { + static const char *result = NULL; + struct strbuf builder = STRBUF_INIT; + + if (result) + return result; + + for (const char **s = extraconfig; s && *s; s++) + strbuf_addf(&builder, "-c %s ", *s); + + result = strbuf_detach(&builder, NULL); + return result; +} + +static const char *get_extra_launchctl_strings(void) { + static const char *result = NULL; + struct strbuf builder = STRBUF_INIT; + + if (result) + return result; + + for (const char **s = extraconfig; s && *s; s++) { + strbuf_addstr(&builder, "<string>-c</string>\n"); + strbuf_addf(&builder, "<string>%s</string>\n", *s); + } + + result = strbuf_detach(&builder, NULL); + return result; +} + /* * get_schedule_cmd` reads the GIT_TEST_MAINT_SCHEDULER environment variable * to mock the schedulers that `git maintenance start` rely on. @@ -1780,39 +1831,43 @@ static const char *get_frequency(enum schedule_priority schedule) * * 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; @@ -1824,16 +1879,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; @@ -1850,9 +1911,8 @@ static int get_random_minute(void) 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__ @@ -1890,12 +1950,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); @@ -1908,6 +1968,7 @@ static int launchctl_boot_plist(int enable, const char *filename) result = finish_command(&child); + free(cmd); free(uid); return result; } @@ -1959,10 +2020,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\">" @@ -1972,6 +2033,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit "<array>\n" "<string>%s/git</string>\n" "<string>--exec-path=%s</string>\n" + "%s" /* For extra config parameters. */ "<string>for-each-repo</string>\n" "<string>--keep-going</string>\n" "<string>--config=maintenance.repo</string>\n" @@ -1981,7 +2043,8 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit "</array>\n" "<key>StartCalendarInterval</key>\n" "<array>\n"; - strbuf_addf(&plist, preamble, name, exec_path, exec_path, frequency); + strbuf_addf(&plist, preamble, name, exec_path, exec_path, + get_extra_launchctl_strings(), frequency); switch (schedule) { case SCHEDULE_HOURLY: @@ -2052,6 +2115,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; @@ -2076,9 +2140,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 @@ -2097,15 +2160,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); } @@ -2119,7 +2183,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; @@ -2129,10 +2193,10 @@ 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", - get_git_common_dir(), frequency); + repo_get_common_dir(the_repository), frequency); tfile = xmks_tempfile(tfilename.buf); strbuf_release(&tfilename); @@ -2216,11 +2280,12 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority "<Actions Context=\"Author\">\n" "<Exec>\n" "<Command>\"%s\\headless-git.exe\"</Command>\n" - "<Arguments>--exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n" + "<Arguments>--exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%s</Arguments>\n" "</Exec>\n" "</Actions>\n" "</Task>\n"; - fprintf(tfile->fp, xml, exec_path, exec_path, frequency); + fprintf(tfile->fp, xml, exec_path, exec_path, + get_extra_config_parameters(), frequency); strvec_split(&child.args, cmd); strvec_pushl(&child.args, "/create", "/tn", name, "/f", "/xml", get_tempfile_path(tfile), NULL); @@ -2235,6 +2300,7 @@ static int schtasks_schedule_task(const char *exec_path, enum schedule_priority delete_tempfile(&tfile); free(name); + free(cmd); return result; } @@ -2276,21 +2342,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" @@ -2298,7 +2371,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; @@ -2308,15 +2381,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); @@ -2361,8 +2436,8 @@ static int crontab_update_schedule(int run_maintenance, int fd) "# replaced in the future by a Git command.\n\n"); strbuf_addf(&line_format, - "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n", - exec_path, exec_path); + "%%d %%s * * %%s \"%s/git\" --exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%s\n", + exec_path, exec_path, get_extra_config_parameters()); fprintf(cron_in, line_format.buf, minute, "1-23", "*", "hourly"); fprintf(cron_in, line_format.buf, minute, "0", "1-6", "daily"); fprintf(cron_in, line_format.buf, minute, "0", "0", "weekly"); @@ -2386,8 +2461,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; } @@ -2410,10 +2487,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(); @@ -2562,7 +2638,7 @@ static int systemd_timer_write_service_template(const char *exec_path) "\n" "[Service]\n" "Type=oneshot\n" - "ExecStart=\"%s/git\" --exec-path=\"%s\" for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n" + "ExecStart=\"%s/git\" --exec-path=\"%s\" %s for-each-repo --keep-going --config=maintenance.repo maintenance run --schedule=%%i\n" "LockPersonality=yes\n" "MemoryDenyWriteExecute=yes\n" "NoNewPrivileges=yes\n" @@ -2572,7 +2648,7 @@ static int systemd_timer_write_service_template(const char *exec_path) "RestrictSUIDSGID=yes\n" "SystemCallArchitectures=native\n" "SystemCallFilter=@system-service\n"; - if (fprintf(file, unit, exec_path, exec_path) < 0) { + if (fprintf(file, unit, exec_path, exec_path, get_extra_config_parameters()) < 0) { error(_("failed to write to '%s'"), filename); fclose(file); goto error; @@ -2594,9 +2670,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 @@ -2607,20 +2684,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. @@ -2628,9 +2710,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; } /* @@ -2813,8 +2903,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++) { @@ -2840,7 +2939,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[] = { @@ -2863,7 +2963,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; } @@ -2873,7 +2973,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() @@ -2890,7 +2991,10 @@ static const char * const builtin_maintenance_usage[] = { NULL, }; -int cmd_maintenance(int argc, const char **argv, const char *prefix) +int cmd_maintenance(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_maintenance_options[] = { @@ -2904,5 +3008,5 @@ int cmd_maintenance(int argc, const char **argv, const char *prefix) 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 7195a072ed..6bec0d1854 100644 --- a/builtin/get-tar-commit-id.c +++ b/builtin/get-tar-commit-id.c @@ -12,7 +12,10 @@ static const char builtin_get_tar_commit_id_usage[] = #define RECORDSIZE (512) #define HEADERSIZE (2 * RECORDSIZE) -int cmd_get_tar_commit_id(int argc, const char **argv UNUSED, const char *prefix) +int cmd_get_tar_commit_id(int argc, + const char **argv UNUSED, + const char *prefix, + struct repository *repo UNUSED) { char buffer[HEADERSIZE]; struct ustar_header *header = (struct ustar_header *)buffer; diff --git a/builtin/grep.c b/builtin/grep.c index dfc3c3e8bd..98b85c7fca 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -3,11 +3,11 @@ * * Copyright (c) 2006 Junio C Hamano */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "tag.h" #include "tree-walk.h" @@ -888,7 +888,10 @@ static int pattern_callback(const struct option *opt, const char *arg, return 0; } -int cmd_grep(int argc, const char **argv, const char *prefix) +int cmd_grep(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int hit = 0; int cached = 0, untracked = 0, opt_exclude = -1; @@ -903,6 +906,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) int dummy; int use_index = 1; int allow_revs; + int ret; struct option options[] = { OPT_BOOL(0, "cached", &cached, @@ -1133,6 +1137,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) &oid, &oc)) { if (seen_dashdash) die(_("unable to resolve revision: %s"), arg); + object_context_release(&oc); break; } @@ -1168,8 +1173,10 @@ int cmd_grep(int argc, const char **argv, const char *prefix) * 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) @@ -1263,10 +1270,14 @@ int cmd_grep(int argc, const char **argv, const char *prefix) 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/hash-object.c b/builtin/hash-object.c index c767414a0c..a25f0403f4 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -4,6 +4,7 @@ * Copyright (C) Linus Torvalds, 2005 * Copyright (C) Junio C Hamano, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -84,7 +85,10 @@ static void hash_stdin_paths(const char *type, int no_filters, unsigned flags, strbuf_release(&unquoted); } -int cmd_hash_object(int argc, const char **argv, const char *prefix) +int cmd_hash_object(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static const char * const hash_object_usage[] = { N_("git hash-object [-t <type>] [-w] [--path=<file> | --no-filters]\n" diff --git a/builtin/help.c b/builtin/help.c index dc1fbe2b98..6a72d991a8 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -1,6 +1,8 @@ + /* * Builtin help command */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "exec-cmd.h" @@ -52,7 +54,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; @@ -409,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; } @@ -513,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); } @@ -540,19 +544,19 @@ static void open_html(const char *path) static void show_html_page(const char *page) { - struct strbuf page_path; /* it leaks but we exec bellow */ + struct strbuf page_path; /* it leaks but we exec below */ get_html_page_path(&page_path, 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) { @@ -585,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) @@ -631,10 +634,14 @@ static void opt_mode_usage(int argc, const char *opt_mode, no_help_format(opt_mode, fmt); } -int cmd_help(int argc, const char **argv, const char *prefix) +int cmd_help(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int nongit; enum help_format parsed_help_format; + char *command = NULL; const char *page; argc = parse_options(argc, argv, prefix, builtin_help_options, @@ -706,9 +713,9 @@ int cmd_help(int argc, const char **argv, const char *prefix) 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: @@ -722,5 +729,6 @@ int cmd_help(int argc, const char **argv, const char *prefix) break; } + free(command); return 0; } diff --git a/builtin/hook.c b/builtin/hook.c index cc37438fde..672d2e37e8 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -18,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; @@ -66,7 +68,10 @@ usage: usage_with_options(builtin_hook_run_usage, run_options); } -int cmd_hook(int argc, const char **argv, const char *prefix) +int cmd_hook(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_hook_options[] = { @@ -77,5 +82,5 @@ int cmd_hook(int argc, const char **argv, const char *prefix) 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 763b01372a..cde49e0b4d 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "delta.h" @@ -8,6 +9,7 @@ #include "csum-file.h" #include "blob.h" #include "commit.h" +#include "tag.h" #include "tree.h" #include "progress.h" #include "fsck.h" @@ -19,9 +21,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>])"; @@ -93,7 +100,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; }; @@ -116,7 +123,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; @@ -147,7 +154,14 @@ 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; @@ -389,7 +403,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) @@ -400,7 +414,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); @@ -798,6 +812,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) @@ -844,7 +920,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); @@ -876,6 +952,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; @@ -1237,7 +1315,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; @@ -1253,7 +1331,7 @@ static void resolve_deltas(void) 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(); @@ -1478,7 +1556,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) { @@ -1504,9 +1582,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); @@ -1551,7 +1629,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); } @@ -1602,6 +1681,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); } @@ -1649,7 +1732,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); @@ -1718,11 +1802,81 @@ static void show_pack_info(int stat_only) free(chain_histogram); } -int cmd_index_pack(int argc, const char **argv, const char *prefix) +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, + struct repository *repo UNUSED) { 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; @@ -1790,7 +1944,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) } 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); @@ -1861,6 +2015,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) 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) @@ -1924,7 +2080,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) 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); @@ -1964,8 +2120,9 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) 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 582dcf20f8..096f96b9c4 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -3,6 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" @@ -11,7 +12,6 @@ #include "parse-options.h" #include "path.h" #include "refs.h" -#include "repository.h" #include "setup.h" #include "strbuf.h" @@ -70,12 +70,17 @@ static const char *const init_db_usage[] = { * On the other hand, it might just make lookup slower and messier. You * be the judge. The default case is to have one DB per managed directory. */ -int cmd_init_db(int argc, const char **argv, const char *prefix) +int cmd_init_db(int argc, + const char **argv, + 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; @@ -103,6 +108,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) N_("specify the reference format to use")), OPT_END() }; + int ret; argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); @@ -110,12 +116,10 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) 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; @@ -189,7 +193,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) * 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 @@ -210,6 +214,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) 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); @@ -231,9 +236,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) set_git_work_tree(work_tree); else set_git_work_tree(git_work_tree_cfg); - if (access(get_git_work_tree(), X_OK)) + if (access(repo_get_work_tree(the_repository), X_OK)) die_errno (_("Cannot access work tree '%s'"), - get_git_work_tree()); + repo_get_work_tree(the_repository)); } else { if (real_git_dir) @@ -242,12 +247,14 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) 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 e6f22459f1..44d8ccddc9 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -4,7 +4,7 @@ * Copyright (c) 2013, 2014 Christian Couder <chriscool@tuxfamily.org> * */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "parse-options.h" @@ -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)) @@ -189,7 +190,10 @@ static void interpret_trailers(const struct process_trailer_options *opts, strbuf_release(&sb); } -int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) +int cmd_interpret_trailers(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; LIST_HEAD(trailers); diff --git a/builtin/log.c b/builtin/log.c index 36769bab3b..923e4e6069 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -4,6 +4,7 @@ * (C) Copyright 2006 Linus Torvalds * 2006 Junio Hamano */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -37,7 +38,7 @@ #include "mailmap.h" #include "progress.h" #include "commit-slab.h" -#include "repository.h" + #include "commit-reach.h" #include "range-diff.h" #include "tmp-objdir.h" @@ -504,13 +505,7 @@ static int cmd_log_walk_no_free(struct rev_info *rev) struct commit *commit; int saved_nrl = 0; int saved_dcctc = 0; - - if (rev->remerge_diff) { - rev->remerge_objdir = tmp_objdir_create("remerge-diff"); - if (!rev->remerge_objdir) - die(_("unable to create temporary object directory")); - tmp_objdir_replace_primary_odb(rev->remerge_objdir, 1); - } + int result; if (rev->early_output) setup_early_output(); @@ -533,10 +528,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); @@ -551,16 +550,12 @@ static int cmd_log_walk_no_free(struct rev_info *rev) rev->diffopt.degraded_cc_to_c = saved_dcctc; rev->diffopt.needed_rename_limit = saved_nrl; - if (rev->remerge_diff) { - tmp_objdir_destroy(rev->remerge_objdir); - rev->remerge_objdir = NULL; - } - + result = diff_result_code(rev); if (rev->diffopt.output_format & DIFF_FORMAT_CHECKDIFF && rev->diffopt.flags.check_failed) { - return 02; + result = 02; } - return diff_result_code(&rev->diffopt); + return result; } static int cmd_log_walk(struct rev_info *rev) @@ -637,7 +632,10 @@ static int git_log_config(const char *var, const char *value, return git_diff_ui_config(var, value, ctx, cb); } -int cmd_whatchanged(int argc, const char **argv, const char *prefix) +int cmd_whatchanged(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -758,7 +756,10 @@ static void show_setup_revisions_tweak(struct rev_info *rev) rev->diffopt.output_format = DIFF_FORMAT_PATCH; } -int cmd_show(int argc, const char **argv, const char *prefix) +int cmd_show(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -874,7 +875,10 @@ int cmd_show(int argc, const char **argv, const char *prefix) /* * This is equivalent to "git log -g --abbrev-commit --pretty=oneline" */ -int cmd_log_reflog(int argc, const char **argv, const char *prefix) +int cmd_log_reflog(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -916,7 +920,10 @@ static void log_setup_revisions_tweak(struct rev_info *rev) diff_merges_default_to_first_parent(rev); } -int cmd_log(int argc, const char **argv, const char *prefix) +int cmd_log(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct log_config cfg; struct rev_info rev; @@ -1986,7 +1993,10 @@ static void infer_range_diff_ranges(struct strbuf *r1, } } -int cmd_format_patch(int argc, const char **argv, const char *prefix) +int cmd_format_patch(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct format_config cfg; struct commit *commit; @@ -2619,7 +2629,10 @@ static void print_commit(char sign, struct commit *commit, int verbose, } } -int cmd_cherry(int argc, const char **argv, const char *prefix) +int cmd_cherry(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; struct patch_ids ids; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 6eeb5cba78..e016b0415d 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -5,8 +5,8 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" -#include "repository.h" #include "config.h" #include "convert.h" #include "quote.h" @@ -507,7 +507,7 @@ static int get_common_prefix_len(const char *common_prefix) common_prefix_len = strlen(common_prefix); /* - * If the prefix has a trailing slash, strip it so that submodules wont + * If the prefix has a trailing slash, strip it so that submodules won't * be pruned from the index. */ if (common_prefix[common_prefix_len - 1] == '/') @@ -561,7 +561,10 @@ static int option_parse_exclude_standard(const struct option *opt, return 0; } -int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) +int cmd_ls_files(int argc, + const char **argv, + const char *cmd_prefix, + struct repository *repo UNUSED) { int require_work_tree = 0, show_tag = 0, i; char *max_prefix; diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index 0a491595ca..42f34e1236 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -37,7 +38,10 @@ static int tail_match(const struct strvec *pattern, const char *path) return 0; } -int cmd_ls_remote(int argc, const char **argv, const char *prefix) +int cmd_ls_remote(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *dest = NULL; unsigned flags = 0; @@ -162,6 +166,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) status = 0; /* we found something */ } + string_list_clear(&server_options, 0); ref_sorting_release(sorting); ref_array_clear(&ref_array); if (transport_disconnect(transport)) @@ -169,5 +174,6 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) transport_ls_refs_options_release(&transport_options); strvec_clear(&pattern); + string_list_clear(&server_options, 0); return status; } diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index bf372c67d7..8542b5d53e 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -3,7 +3,9 @@ * * Copyright (C) Linus Torvalds, 2005 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "config.h" #include "gettext.h" #include "hex.h" @@ -329,7 +331,10 @@ static struct ls_tree_cmdmode_to_fmt ls_tree_cmdmode_format[] = { }, }; -int cmd_ls_tree(int argc, const char **argv, const char *prefix) +int cmd_ls_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct object_id oid; struct tree *tree; diff --git a/builtin/mailinfo.c b/builtin/mailinfo.c index 53a22645da..e17dec27b1 100644 --- a/builtin/mailinfo.c +++ b/builtin/mailinfo.c @@ -2,6 +2,7 @@ * Another stupid program, this one parsing the headers of an * email to figure out authorship and subject */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" @@ -48,7 +49,10 @@ static int parse_opt_quoted_cr(const struct option *opt, const char *arg, int un return 0; } -int cmd_mailinfo(int argc, const char **argv, const char *prefix) +int cmd_mailinfo(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct metainfo_charset meta_charset; struct mailinfo mi; diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c index fe6dbc5d05..b8f7150ce9 100644 --- a/builtin/mailsplit.c +++ b/builtin/mailsplit.c @@ -269,7 +269,10 @@ out: return ret; } -int cmd_mailsplit(int argc, const char **argv, const char *prefix) +int cmd_mailsplit(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int nr = 0, nr_prec = 4, num = 0; int allow_bare = 0; diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 5a8e729502..a20c93b11a 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "commit.h" @@ -5,7 +6,6 @@ #include "hex.h" #include "object-name.h" #include "parse-options.h" -#include "repository.h" #include "commit-reach.h" static int show_merge_base(struct commit **rev, int rev_nr, int show_all) @@ -143,7 +143,10 @@ static int handle_fork_point(int argc, const char **argv) return 0; } -int cmd_merge_base(int argc, const char **argv, const char *prefix) +int cmd_merge_base(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct commit **rev; int rev_nr = 0; diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 1f987334a3..cb42865eb5 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "diff.h" @@ -53,7 +54,10 @@ static int diff_algorithm_cb(const struct option *opt, return 0; } -int cmd_merge_file(int argc, const char **argv, const char *prefix) +int cmd_merge_file(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *names[3] = { 0 }; mmfile_t mmfs[3] = { 0 }; diff --git a/builtin/merge-index.c b/builtin/merge-index.c index 0fabe3f6bb..a5b87ee3c5 100644 --- a/builtin/merge-index.c +++ b/builtin/merge-index.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "hex.h" #include "read-cache-ll.h" -#include "repository.h" #include "run-command.h" #include "sparse-index.h" @@ -73,7 +73,10 @@ static void merge_all(void) } } -int cmd_merge_index(int argc, const char **argv, const char *prefix UNUSED) +int cmd_merge_index(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { int i, force_file = 0; diff --git a/builtin/merge-ours.c b/builtin/merge-ours.c index 932924e5d0..1fcf53f005 100644 --- a/builtin/merge-ours.c +++ b/builtin/merge-ours.c @@ -7,15 +7,19 @@ * * 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" -#include "repository.h" + static const char builtin_merge_ours_usage[] = "git merge-ours <base>... -- HEAD <remote>..."; -int cmd_merge_ours(int argc, const char **argv, const char *prefix UNUSED) +int cmd_merge_ours(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { if (argc == 2 && !strcmp(argv[1], "-h")) usage(builtin_merge_ours_usage); diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index e951b09805..1dd295558b 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -1,10 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "gettext.h" #include "hash.h" #include "merge-recursive.h" #include "object-name.h" -#include "repository.h" static const char builtin_merge_recursive_usage[] = "git %s <base>... -- <head> <remote> ..."; @@ -21,7 +21,10 @@ static char *better_branch_name(const char *branch) return xstrdup(name ? name : branch); } -int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED) +int cmd_merge_recursive(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { struct object_id bases[21]; unsigned bases_count = 0; diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index c00469ed3d..c5ed472967 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "tree-walk.h" #include "xdiff-interface.h" @@ -10,7 +11,6 @@ #include "object-name.h" #include "object-store-ll.h" #include "parse-options.h" -#include "repository.h" #include "blob.h" #include "merge-blobs.h" #include "quote.h" @@ -526,7 +526,10 @@ static int real_merge(struct merge_tree_options *o, return !result.clean; /* result.clean < 0 handled above */ } -int cmd_merge_tree(int argc, const char **argv, const char *prefix) +int cmd_merge_tree(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct merge_tree_options o = { .show_messages = -1 }; struct strvec xopts = STRVEC_INIT; diff --git a/builtin/merge.c b/builtin/merge.c index 662a49a0e8..e32c99087f 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -5,8 +5,9 @@ * * Based on git-merge.sh by Junio C Hamano. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "advice.h" #include "config.h" @@ -17,6 +18,7 @@ #include "object-name.h" #include "parse-options.h" #include "lockfile.h" +#include "repository.h" #include "run-command.h" #include "hook.h" #include "diff.h" @@ -496,7 +498,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); @@ -695,7 +697,9 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head, static void write_tree_trivial(struct object_id *oid) { - if (write_index_as_tree(oid, the_repository->index, get_index_file(), 0, NULL)) + if (write_index_as_tree(oid, the_repository->index, + repo_get_index_file(the_repository), + 0, NULL)) die(_("git write-tree failed to write a tree")); } @@ -750,6 +754,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); @@ -757,7 +762,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common, } if (write_locked_index(the_repository->index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) - die(_("unable to write %s"), get_index_file()); + die(_("unable to write %s"), repo_get_index_file(the_repository)); return clean ? 0 : 1; } else { return try_merge_command(the_repository, @@ -839,7 +844,7 @@ static void write_merge_heads(struct commit_list *); static void prepare_to_commit(struct commit_list *remoteheads) { struct strbuf msg = STRBUF_INIT; - const char *index_file = get_index_file(); + const char *index_file = repo_get_index_file(the_repository); if (!no_verify) { int invoked_hook; @@ -855,7 +860,8 @@ static void prepare_to_commit(struct commit_list *remoteheads) if (invoked_hook) discard_index(the_repository->index); } - read_index_from(the_repository->index, index_file, get_git_dir()); + read_index_from(the_repository->index, index_file, + repo_get_git_dir(the_repository)); strbuf_addbuf(&msg, &merge_msg); if (squash) BUG("the control must not reach here under --squash"); @@ -878,8 +884,8 @@ static void prepare_to_commit(struct commit_list *remoteheads) append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0); write_merge_heads(remoteheads); write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len); - if (run_commit_hook(0 < option_edit, get_index_file(), NULL, - "prepare-commit-msg", + if (run_commit_hook(0 < option_edit, repo_get_index_file(the_repository), + NULL, "prepare-commit-msg", git_path_merge_msg(the_repository), "merge", NULL)) abort_commit(remoteheads, NULL); if (0 < option_edit) { @@ -887,7 +893,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); } - if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(), + if (!no_verify && run_commit_hook(0 < option_edit, repo_get_index_file(the_repository), NULL, "commit-msg", git_path_merge_msg(the_repository), NULL)) abort_commit(remoteheads, NULL); @@ -1275,7 +1281,10 @@ static int merging_a_throwaway_tag(struct commit *commit) return is_throwaway_tag; } -int cmd_merge(int argc, const char **argv, const char *prefix) +int cmd_merge(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct object_id result_tree, stash, head_oid; struct commit *head_commit; @@ -1347,7 +1356,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) REF_NO_DEREF); /* Invoke 'git reset --merge' */ - ret = cmd_reset(nargc, nargv, prefix); + ret = cmd_reset(nargc, nargv, prefix, the_repository); if (!is_null_oid(&stash_oid)) { oid_to_hex_r(stash_oid_hex, &stash_oid); @@ -1379,7 +1388,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) die(_("There is no merge in progress (MERGE_HEAD missing).")); /* Invoke 'git commit' */ - ret = cmd_commit(nargc, nargv, prefix); + ret = cmd_commit(nargc, nargv, prefix, the_repository); goto done; } diff --git a/builtin/mktag.c b/builtin/mktag.c index c6b644219f..6e188dce50 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -71,7 +72,10 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type) return ret; } -int cmd_mktag(int argc, const char **argv, const char *prefix) +int cmd_mktag(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { static struct option builtin_mktag_options[] = { OPT_BOOL(0, "strict", &option_strict, diff --git a/builtin/mktree.c b/builtin/mktree.c index 9a22d4e277..3c16faa40e 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -3,6 +3,7 @@ * * Copyright (c) Junio C Hamano, 2006, 2009 */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" @@ -150,7 +151,10 @@ static void mktree_line(char *buf, int nul_term_line, int allow_missing) free(to_free); } -int cmd_mktree(int ac, const char **av, const char *prefix) +int cmd_mktree(int ac, + const char **av, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf sb = STRBUF_INIT; struct object_id oid; @@ -199,5 +203,6 @@ int cmd_mktree(int ac, const char **av, const char *prefix) used=0; /* reset tree entry buffer for re-use in batch mode */ } strbuf_release(&sb); + return 0; } diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index 8805cbbeb3..2a938466f5 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "midx.h" @@ -9,6 +9,7 @@ #include "trace2.h" #include "object-store-ll.h" #include "replace-object.h" +#include "repository.h" #define BUILTIN_MIDX_WRITE_USAGE \ N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \ @@ -63,7 +64,7 @@ static int parse_object_dir(const struct option *opt, const char *arg, char **value = opt->value; free(*value); if (unset) - *value = xstrdup(get_object_directory()); + *value = xstrdup(repo_get_object_directory(the_repository)); else *value = real_pathdup(arg, 1); return 0; @@ -118,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[] = { @@ -163,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); @@ -174,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); @@ -182,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[] = { @@ -209,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[] = { @@ -236,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[] = { @@ -267,8 +272,10 @@ static int cmd_multi_pack_index_repack(int argc, const char **argv, (size_t)opts.batch_size, opts.flags); } -int cmd_multi_pack_index(int argc, const char **argv, - const char *prefix) +int cmd_multi_pack_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { int res; parse_opt_subcommand_fn *fn = NULL; @@ -294,7 +301,7 @@ int cmd_multi_pack_index(int argc, const char **argv, 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 6c69033c5f..472a278737 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -3,6 +3,7 @@ * * Copyright (C) 2006 Johannes Schindelin */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" @@ -18,7 +19,7 @@ #include "string-list.h" #include "parse-options.h" #include "read-cache-ll.h" -#include "repository.h" + #include "setup.h" #include "strvec.h" #include "submodule.h" @@ -178,7 +179,10 @@ static void remove_empty_src_dirs(const char **src_dir, size_t src_dir_nr) strbuf_release(&a_src_dir); } -int cmd_mv(int argc, const char **argv, const char *prefix) +int cmd_mv(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, flags, gitmodules_modified = 0; int verbose = 0, show_only = 0, force = 0, ignore_errors = 0, ignore_sparse = 0; diff --git a/builtin/name-rev.c b/builtin/name-rev.c index a468ef84c3..765eb20a93 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -1,8 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "commit.h" #include "tag.h" @@ -65,7 +65,7 @@ static void set_commit_cutoff(struct commit *commit) static void adjust_cutoff_timestamp_for_slop(void) { if (cutoff) { - /* check for undeflow */ + /* check for underflow */ if (cutoff > TIME_MIN + CUTOFF_DATE_SLOP) cutoff = cutoff - CUTOFF_DATE_SLOP; else @@ -558,7 +558,10 @@ static void name_rev_line(char *p, struct name_ref_data *data) strbuf_release(&buf); } -int cmd_name_rev(int argc, const char **argv, const char *prefix) +int cmd_name_rev(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct mem_pool string_pool; struct object_array revs = OBJECT_ARRAY_INIT; diff --git a/builtin/notes.c b/builtin/notes.c index 04f9dfb7fb..d051abf6df 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -6,7 +6,7 @@ * Based on git-notes.sh by Johannes Schindelin, * and builtin/tag.c by Kristian Høgsberg and Carlos Rica. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "editor.h" @@ -17,7 +17,7 @@ #include "object-name.h" #include "object-store-ll.h" #include "path.h" -#include "repository.h" + #include "pretty.h" #include "refs.h" #include "exec-cmd.h" @@ -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>"), @@ -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 @@ out: 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; @@ -897,6 +908,7 @@ static int merge(int argc, const char **argv, const char *prefix) 1, PARSE_OPT_NONEG), OPT_END() }; + char *notes_ref; argc = parse_options(argc, argv, prefix, options, git_notes_merge_usage, 0); @@ -924,7 +936,8 @@ static int merge(int argc, const char **argv, const char *prefix) if (do_commit) return merge_commit(&o); - o.local_ref = default_notes_ref(); + notes_ref = default_notes_ref(the_repository); + o.local_ref = notes_ref; strbuf_addstr(&remote_ref, argv[0]); expand_loose_notes_ref(&remote_ref); o.remote_ref = remote_ref.buf; @@ -953,7 +966,7 @@ static int merge(int argc, const char **argv, const char *prefix) } strbuf_addf(&msg, "notes: Merged notes from %s into %s", - remote_ref.buf, default_notes_ref()); + remote_ref.buf, notes_ref); strbuf_add(&(o.commit_msg), msg.buf + 7, msg.len - 7); /* skip "notes: " */ result = notes_merge(&o, t, &result_oid); @@ -961,7 +974,7 @@ static int merge(int argc, const char **argv, const char *prefix) if (result >= 0) /* Merge resulted (trivially) in result_oid */ /* Update default notes ref with new commit */ refs_update_ref(get_main_ref_store(the_repository), msg.buf, - default_notes_ref(), &result_oid, NULL, 0, + notes_ref, &result_oid, NULL, 0, UPDATE_REFS_DIE_ON_ERR); else { /* Merge has unresolved conflicts */ struct worktree **worktrees; @@ -973,14 +986,14 @@ static int merge(int argc, const char **argv, const char *prefix) /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */ worktrees = get_worktrees(); wt = find_shared_symref(worktrees, "NOTES_MERGE_REF", - default_notes_ref()); + notes_ref); if (wt) die(_("a notes merge into %s is already in-progress at %s"), - default_notes_ref(), wt->path); + notes_ref, wt->path); free_worktrees(worktrees); - if (refs_update_symref(get_main_ref_store(the_repository), "NOTES_MERGE_REF", default_notes_ref(), NULL)) + 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)"), - default_notes_ref()); + notes_ref); 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"), @@ -988,6 +1001,7 @@ static int merge(int argc, const char **argv, const char *prefix) } free_notes(t); + free(notes_ref); strbuf_release(&remote_ref); strbuf_release(&msg); return result < 0; /* return non-zero on conflicts */ @@ -1009,7 +1023,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; @@ -1052,7 +1067,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; @@ -1081,9 +1097,11 @@ 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; argc = parse_options(argc, argv, prefix, options, git_notes_get_ref_usage, 0); @@ -1092,11 +1110,16 @@ static int get_ref(int argc, const char **argv, const char *prefix) usage_with_options(git_notes_get_ref_usage, options); } - puts(default_notes_ref()); + notes_ref = default_notes_ref(the_repository); + puts(notes_ref); + free(notes_ref); return 0; } -int cmd_notes(int argc, const char **argv, const char *prefix) +int cmd_notes(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { const char *override_notes_ref = NULL; parse_opt_subcommand_fn *fn = NULL; @@ -1135,5 +1158,5 @@ int cmd_notes(int argc, const char **argv, const char *prefix) 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 c6e2852d3c..7dc51c03c4 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1,8 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" #include "config.h" #include "attr.h" #include "object.h" @@ -239,6 +239,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; @@ -1100,78 +1101,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 +1170,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]; @@ -1529,7 +1515,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 +1542,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) { @@ -3627,7 +3613,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) @@ -3858,7 +3844,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 +3914,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 | @@ -3968,7 +3957,7 @@ static int add_loose_object(const struct object_id *oid, const char *path, */ static void add_unreachable_loose_objects(void) { - for_each_loose_file_in_objdir(get_object_directory(), + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), add_loose_object, NULL, NULL, NULL); } @@ -3984,7 +3973,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; } @@ -4312,7 +4301,22 @@ static int option_parse_cruft_expiration(const struct option *opt UNUSED, return 0; } -int cmd_pack_objects(int argc, const char **argv, const char *prefix) +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, + struct repository *repo UNUSED) { int use_internal_rev_list = 0; int shallow = 0; @@ -4421,6 +4425,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) 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, @@ -4501,10 +4508,18 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) 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; @@ -4624,6 +4639,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) 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); } @@ -4669,6 +4688,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) cleanup: clear_packing_data(&to_pack); list_objects_filter_release(&filter_options); + string_list_clear(&keep_pack_list, 0); strvec_clear(&rp); return 0; diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index dd9bf35f5b..bc61990a93 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -5,13 +5,15 @@ * This file is licensed under the GPL v2. * */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hex.h" -#include "repository.h" + #include "packfile.h" #include "object-store-ll.h" +#include "strbuf.h" #define BLKSIZE 512 @@ -68,6 +70,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; @@ -205,6 +216,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; @@ -418,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; } @@ -433,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) @@ -443,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) @@ -561,13 +589,10 @@ static void load_all(void) } } -int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED) -{ - int i; - int i_still_use_this = 0; - struct pack_list *min = NULL, *red, *pl; +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")) @@ -627,11 +652,11 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED) /* 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); @@ -665,7 +690,7 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED) 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; } @@ -673,5 +698,9 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED) 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 db40825666..2d83c1ed2a 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" #include "refs.h" -#include "repository.h" #include "revision.h" static char const * const pack_refs_usage[] = { @@ -11,7 +11,10 @@ static char const * const pack_refs_usage[] = { NULL }; -int cmd_pack_refs(int argc, const char **argv, const char *prefix) +int cmd_pack_refs(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct ref_exclusions excludes = REF_EXCLUSIONS_INIT; struct string_list included_refs = STRING_LIST_INIT_NODUP; diff --git a/builtin/patch-id.c b/builtin/patch-id.c index 35c1179f7e..93b398e391 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "diff.h" @@ -7,9 +8,10 @@ #include "parse-options.h" #include "setup.h" -static void flush_current_id(struct object_id *id, struct object_id *result) +static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result) { - printf("%s %s\n", oid_to_hex(result), oid_to_hex(id)); + if (patchlen) + printf("%s %s\n", oid_to_hex(result), oid_to_hex(id)); } static int remove_space(char *line) @@ -59,27 +61,9 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after) return 1; } -/* - * flag bits to control get_one_patchid()'s behaviour. - * - * STABLE/VERBATIM are given from the command line option as - * --stable/--verbatim. FIND_HEADER conveys the internal state - * maintained by the caller to allow the function to avoid mistaking - * lines of log message before seeing the "diff" part as the beginning - * of the next patch. - */ -enum { - GOPID_STABLE = (1<<0), /* --stable */ - GOPID_VERBATIM = (1<<1), /* --verbatim */ - GOPID_FIND_HEADER = (1<<2), /* stop at the beginning of patch message */ -}; - static int get_one_patchid(struct object_id *next_oid, struct object_id *result, - struct strbuf *line_buf, unsigned flags) + struct strbuf *line_buf, int stable, int verbatim) { - int stable = flags & GOPID_STABLE; - int verbatim = flags & GOPID_VERBATIM; - int find_header = flags & GOPID_FIND_HEADER; int patchlen = 0, found_next = 0; int before = -1, after = -1; int diff_is_binary = 0; @@ -94,40 +78,24 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, const char *p = line; int len; - /* - * The caller hasn't seen us find a patch header and - * return to it, or we have started processing patch - * and may encounter the beginning of the next patch. - */ - if (find_header) { - /* - * If we see a line that begins with "<object name>", - * "commit <object name>" or "From <object name>", it is - * the beginning of a patch. Return to the caller, as - * we are done with the one we have been processing. - */ - if (skip_prefix(line, "commit ", &p)) - ; - else if (skip_prefix(line, "From ", &p)) - ; - if (!get_oid_hex(p, next_oid)) { - if (verbatim) - the_hash_algo->update_fn(&ctx, line, strlen(line)); - found_next = 1; - break; - } + /* Possibly skip over the prefix added by "log" or "format-patch" */ + if (!skip_prefix(line, "commit ", &p) && + !skip_prefix(line, "From ", &p) && + starts_with(line, "\\ ") && 12 < strlen(line)) { + if (verbatim) + the_hash_algo->update_fn(&ctx, line, strlen(line)); + continue; + } + + if (!get_oid_hex(p, next_oid)) { + found_next = 1; + break; } /* Ignore commit comments */ if (!patchlen && !starts_with(line, "diff ")) continue; - /* - * We are past the commit log message. Prepare to - * stop at the beginning of the next patch header. - */ - find_header = 1; - /* Parsing diff header? */ if (before == -1) { if (starts_with(line, "GIT binary patch") || @@ -160,16 +128,6 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, break; } - /* - * A hunk about an incomplete line may have this - * marker at the end, which should just be ignored. - */ - if (starts_with(line, "\\ ") && 12 < strlen(line)) { - if (verbatim) - the_hash_algo->update_fn(&ctx, line, strlen(line)); - continue; - } - if (diff_is_binary) { if (starts_with(line, "diff ")) { diff_is_binary = 0; @@ -216,20 +174,17 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, return patchlen; } -static void generate_id_list(unsigned flags) +static void generate_id_list(int stable, int verbatim) { struct object_id oid, n, result; int patchlen; struct strbuf line_buf = STRBUF_INIT; oidclr(&oid, the_repository->hash_algo); - flags |= GOPID_FIND_HEADER; while (!feof(stdin)) { - patchlen = get_one_patchid(&n, &result, &line_buf, flags); - if (patchlen) - flush_current_id(&oid, &result); + patchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim); + flush_current_id(patchlen, &oid, &result); oidcpy(&oid, &n); - flags &= ~GOPID_FIND_HEADER; } strbuf_release(&line_buf); } @@ -260,12 +215,14 @@ static int git_patch_id_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_patch_id(int argc, const char **argv, const char *prefix) +int cmd_patch_id(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { /* if nothing is set, default to unstable */ struct patch_id_opts config = {0, 0}; int opts = 0; - unsigned flags = 0; struct option builtin_patch_id_options[] = { OPT_CMDMODE(0, "unstable", &opts, N_("use the unstable patch-id algorithm"), 1), @@ -297,11 +254,7 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix) if (!the_hash_algo) repo_set_hash_algo(the_repository, GIT_HASH_SHA1); - if (opts ? opts > 1 : config.stable) - flags |= GOPID_STABLE; - if (opts ? opts == 3 : config.verbatim) - flags |= GOPID_VERBATIM; - generate_id_list(flags); - + generate_id_list(opts ? opts > 1 : config.stable, + opts ? opts == 3 : config.verbatim); return 0; } diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c index ca3578e158..4d63f26b0a 100644 --- a/builtin/prune-packed.c +++ b/builtin/prune-packed.c @@ -8,7 +8,10 @@ static const char * const prune_packed_usage[] = { NULL }; -int cmd_prune_packed(int argc, const char **argv, const char *prefix) +int cmd_prune_packed(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int opts = isatty(2) ? PRUNE_PACKED_VERBOSE : 0; const struct option prune_packed_options[] = { diff --git a/builtin/prune.c b/builtin/prune.c index 57fe31467f..2b1de01339 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "commit.h" #include "diff.h" @@ -147,7 +148,10 @@ static void remove_temporary_files(const char *path) closedir(dir); } -int cmd_prune(int argc, const char **argv, const char *prefix) +int cmd_prune(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; int exclude_promisor_objects = 0; @@ -193,12 +197,12 @@ int cmd_prune(int argc, const char **argv, const char *prefix) revs.exclude_promisor_objects = 1; } - for_each_loose_file_in_objdir(get_object_directory(), prune_object, - prune_cruft, prune_subdir, &revs); + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + prune_object, prune_cruft, prune_subdir, &revs); prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0); - remove_temporary_files(get_object_directory()); - s = mkpathdup("%s/pack", get_object_directory()); + remove_temporary_files(repo_get_object_directory(the_repository)); + s = mkpathdup("%s/pack", repo_get_object_directory(the_repository)); remove_temporary_files(s); free(s); diff --git a/builtin/pull.c b/builtin/pull.c index 4c54d8196f..edc56907aa 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -6,6 +6,7 @@ * Fetch one or more remote refs and merge it/them into the current HEAD. */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -84,7 +85,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; @@ -217,8 +218,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"), @@ -977,7 +978,10 @@ static void show_advice_pull_non_ff(void) "invocation.\n")); } -int cmd_pull(int argc, const char **argv, const char *prefix) +int cmd_pull(int argc, + const char **argv, + const char *prefix, + struct repository *repository UNUSED) { const char *repo, **refspecs; struct oid_array merge_heads = OID_ARRAY_INIT; @@ -1024,8 +1028,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix) * "--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) @@ -1135,7 +1141,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix) 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 7a67398124..51c609f208 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -1,6 +1,7 @@ /* * "git push" */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "branch.h" @@ -13,7 +14,6 @@ #include "transport.h" #include "parse-options.h" #include "pkt-line.h" -#include "repository.h" #include "submodule.h" #include "submodule-config.h" #include "send-pack.h" @@ -72,13 +72,15 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref, const char *branch_name; if (remote->push.nr) { - struct refspec_item query; - memset(&query, 0, sizeof(struct refspec_item)); - query.src = matched->name; + struct refspec_item query = { + .src = matched->name, + }; + if (!query_refspecs(&remote->push, &query) && query.dst) { refspec_appendf(refspec, "%s%s:%s", query.force ? "+" : "", query.src, query.dst); + free(query.dst); return; } } @@ -517,14 +519,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; @@ -546,7 +541,10 @@ static int git_push_config(const char *k, const char *v, return git_default_config(k, v, ctx, NULL); } -int cmd_push(int argc, const char **argv, const char *prefix) +int cmd_push(int argc, + const char **argv, + const char *prefix, + struct repository *repository UNUSED) { int flags = 0; int tags = 0; @@ -664,6 +662,7 @@ int cmd_push(int argc, const char **argv, const char *prefix) 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 f02cbac087..1b33ab66a7 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -1,10 +1,11 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "object-name.h" #include "parse-options.h" #include "range-diff.h" #include "config.h" -#include "repository.h" + static const char * const builtin_range_diff_usage[] = { N_("git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>"), @@ -13,7 +14,10 @@ N_("git range-diff [<options>] <base> <old-tip> <new-tip>"), NULL }; -int cmd_range_diff(int argc, const char **argv, const char *prefix) +int cmd_range_diff(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct diff_options diffopt = { NULL }; struct strvec other_arg = STRVEC_INIT; diff --git a/builtin/read-tree.c b/builtin/read-tree.c index a8cf8504b8..d2a807a828 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -16,7 +16,6 @@ #include "cache-tree.h" #include "unpack-trees.h" #include "parse-options.h" -#include "repository.h" #include "resolve-undo.h" #include "setup.h" #include "sparse-index.h" @@ -108,7 +107,10 @@ static int git_read_tree_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) +int cmd_read_tree(int argc, + const char **argv, + const char *cmd_prefix, + struct repository *repo UNUSED) { int i, stage = 0; struct object_id oid; diff --git a/builtin/rebase.c b/builtin/rebase.c index a2c96c080e..bbaca3c5d5 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -3,8 +3,9 @@ * * Copyright (c) 2018 Pratik Karki */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "environment.h" #include "gettext.h" @@ -527,6 +528,23 @@ static int rebase_write_basic_state(struct rebase_options *opts) return 0; } +static int cleanup_autostash(struct rebase_options *opts) +{ + int ret; + struct strbuf dir = STRBUF_INIT; + const char *path = state_dir_path("autostash", opts); + + if (!file_exists(path)) + return 0; + ret = apply_autostash(path); + strbuf_addstr(&dir, opts->state_dir); + if (remove_dir_recursively(&dir, 0)) + ret = error_errno(_("could not remove '%s'"), opts->state_dir); + strbuf_release(&dir); + + return ret; +} + static int finish_rebase(struct rebase_options *opts) { struct strbuf dir = STRBUF_INIT; @@ -1063,7 +1081,10 @@ static int check_exec_cmd(const char *cmd) return 0; } -int cmd_rebase(int argc, const char **argv, const char *prefix) +int cmd_rebase(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rebase_options options = REBASE_OPTIONS_INIT; const char *branch_name; @@ -1727,7 +1748,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (require_clean_work_tree(the_repository, "rebase", _("Please commit or stash them."), 1, 1)) { ret = -1; - goto cleanup; + goto cleanup_autostash; } /* @@ -1750,7 +1771,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) if (options.switch_to) { ret = checkout_up_to_date(&options); if (ret) - goto cleanup; + goto cleanup_autostash; } if (!(options.flags & REBASE_NO_QUIET)) @@ -1776,8 +1797,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) /* If a hook exists, give it a chance to interrupt*/ if (!ok_to_skip_pre_rebase && run_hooks_l(the_repository, "pre-rebase", options.upstream_arg, - argc ? argv[0] : NULL, NULL)) - die(_("The pre-rebase hook refused to rebase.")); + argc ? argv[0] : NULL, NULL)) { + ret = error(_("The pre-rebase hook refused to rebase.")); + goto cleanup_autostash; + } if (options.flags & REBASE_DIFFSTAT) { struct diff_options opts; @@ -1822,9 +1845,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) RESET_HEAD_RUN_POST_CHECKOUT_HOOK; ropts.head_msg = msg.buf; ropts.default_reflog_action = options.reflog_action; - if (reset_head(the_repository, &ropts)) - die(_("Could not detach HEAD")); - strbuf_release(&msg); + if (reset_head(the_repository, &ropts)) { + ret = error(_("Could not detach HEAD")); + goto cleanup_autostash; + } /* * If the onto is a proper descendant of the tip of the branch, then @@ -1852,9 +1876,14 @@ run_rebase: cleanup: strbuf_release(&buf); + strbuf_release(&msg); strbuf_release(&revisions); rebase_options_release(&options); free(squash_onto_name); free(keep_base_onto_name); return !!ret; + +cleanup_autostash: + ret |= !!cleanup_autostash(&options); + goto cleanup; } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 478c62ca83..9d2c07f68d 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1,6 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" -#include "repository.h" + #include "config.h" #include "environment.h" #include "gettext.h" @@ -373,6 +374,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, @@ -1082,7 +1084,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; @@ -1338,7 +1340,7 @@ static int update_shallow_ref(struct command *cmd, struct shallow_info *si) } /* - * NEEDSWORK: we should consolidate various implementions of "are we + * NEEDSWORK: we should consolidate various implementations of "are we * on an unborn branch?" test into one, and make the unified one more * robust. !get_sha1() based check used here and elsewhere would not * allow us to tell an unborn branch from corrupt ref, for example. @@ -1847,7 +1849,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); @@ -1876,7 +1878,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); @@ -2053,6 +2055,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; } @@ -2494,7 +2498,10 @@ static int delete_only(struct command *commands) return 1; } -int cmd_receive_pack(int argc, const char **argv, const char *prefix) +int cmd_receive_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int advertise_refs = 0; struct command *commands; diff --git a/builtin/reflog.c b/builtin/reflog.c index 0d2ff95c6e..5a0c22f2f7 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -1,7 +1,7 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" -#include "repository.h" #include "revision.h" #include "reachable.h" #include "wildmatch.h" @@ -234,7 +234,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() @@ -244,7 +245,7 @@ static int cmd_reflog_show(int argc, const char **argv, const char *prefix) PARSE_OPT_KEEP_DASHDASH | PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); - return cmd_log_reflog(argc, argv, prefix); + return cmd_log_reflog(argc, argv, prefix, the_repository); } static int show_reflog(const char *refname, void *cb_data UNUSED) @@ -253,7 +254,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 +272,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 +397,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 +428,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() @@ -447,7 +452,10 @@ static int cmd_reflog_exists(int argc, const char **argv, const char *prefix) * main "reflog" */ -int cmd_reflog(int argc, const char **argv, const char *prefix) +int cmd_reflog(int argc, + const char **argv, + const char *prefix, + struct repository *repository) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -464,7 +472,7 @@ int cmd_reflog(int argc, const char **argv, const char *prefix) 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); + return cmd_log_reflog(argc, argv, prefix, repository); } diff --git a/builtin/refs.c b/builtin/refs.c index 131f98be98..a29f195834 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -1,10 +1,11 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "fsck.h" #include "parse-options.h" #include "refs.h" -#include "repository.h" #include "strbuf.h" +#include "worktree.h" #define REFS_MIGRATE_USAGE \ N_("git refs migrate --ref-format=<format> [--dry-run]") @@ -12,7 +13,8 @@ #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, @@ -63,9 +65,11 @@ out: 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 +79,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,13 +88,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) +int cmd_refs(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { const char * const refs_usage[] = { REFS_MIGRATE_USAGE, @@ -105,5 +116,5 @@ int cmd_refs(int argc, const char **argv, const char *prefix) }; 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 282782eccd..33c8ae0fc7 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -195,7 +195,10 @@ static int command_loop(const char *child) } } -int cmd_remote_ext(int argc, const char **argv, const char *prefix) +int cmd_remote_ext(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { BUG_ON_NON_EMPTY_PREFIX(prefix); diff --git a/builtin/remote-fd.c b/builtin/remote-fd.c index 9020fab9c5..ae896eda57 100644 --- a/builtin/remote-fd.c +++ b/builtin/remote-fd.c @@ -53,7 +53,10 @@ static void command_loop(int input_fd, int output_fd) } } -int cmd_remote_fd(int argc, const char **argv, const char *prefix) +int cmd_remote_fd(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int input_fd = -1; int output_fd = -1; diff --git a/builtin/remote.c b/builtin/remote.c index 0acc547d69..32d02ca4a0 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -154,7 +155,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; @@ -376,7 +378,7 @@ 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)) @@ -632,12 +634,12 @@ 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); if (remote->origin == REMOTE_REMOTES) unlink_or_warn(git_path("remotes/%s", remote->name)); else if (remote->origin == REMOTE_BRANCHES) @@ -705,7 +707,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[] = { @@ -758,16 +761,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; @@ -880,7 +883,8 @@ out: 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() @@ -1302,7 +1306,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[] = { @@ -1398,11 +1403,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, @@ -1413,8 +1449,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]); @@ -1433,25 +1471,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; } @@ -1502,7 +1554,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[] = { @@ -1533,7 +1586,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[] = { @@ -1615,7 +1669,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[] = { @@ -1634,7 +1689,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; @@ -1673,7 +1729,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; @@ -1761,7 +1818,10 @@ out: return 0; } -int cmd_remote(int argc, const char **argv, const char *prefix) +int cmd_remote(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -1784,7 +1844,7 @@ int cmd_remote(int argc, const char **argv, const char *prefix) 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 8bb875532b..9c21fc482d 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" @@ -85,17 +86,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; @@ -386,7 +404,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) { @@ -425,9 +443,11 @@ static void repack_promisor_objects(const struct pack_objects_args *args, free(promisor_name); } + fclose(out); if (finish_command(&cmd)) die(_("could not finish pack-objects to repack promisor objects")); + strbuf_release(&line); } struct pack_geometry { @@ -1134,7 +1154,10 @@ static const char *find_pack_prefix(const char *packdir, const char *packtmp) return pack_prefix; } -int cmd_repack(int argc, const char **argv, const char *prefix) +int cmd_repack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct child_process cmd = CHILD_PROCESS_INIT; struct string_list_item *item; @@ -1150,12 +1173,16 @@ int cmd_repack(int argc, const char **argv, const char *prefix) 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, @@ -1189,13 +1216,13 @@ int cmd_repack(int argc, const char **argv, const char *prefix) 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")), @@ -1222,6 +1249,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix) 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")); @@ -1258,7 +1290,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (write_midx && write_bitmaps) { struct strbuf path = STRBUF_INIT; - strbuf_addf(&path, "%s/%s_XXXXXX", get_object_directory(), + strbuf_addf(&path, "%s/%s_XXXXXX", repo_get_object_directory(the_repository), "bitmap-ref-tips"); refs_snapshot = xmks_tempfile(path.buf); @@ -1267,7 +1299,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) strbuf_release(&path); } - packdir = mkpathdup("%s/pack", get_object_directory()); + packdir = mkpathdup("%s/pack", repo_get_object_directory(the_repository)); packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid()); packtmp = mkpathdup("%s/%s", packdir, packtmp_name); @@ -1387,13 +1419,13 @@ int cmd_repack(int argc, const char **argv, const char *prefix) 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,14 +1569,17 @@ int cmd_repack(int argc, const char **argv, const char *prefix) unsigned flags = 0; if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL, 0)) flags |= MIDX_WRITE_INCREMENTAL; - write_midx_file(get_object_directory(), NULL, NULL, flags); + write_midx_file(the_repository, repo_get_object_directory(the_repository), + NULL, NULL, flags); } cleanup: + string_list_clear(&keep_pack_list, 0); 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 34cc4672bc..a4eaadff91 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -7,11 +7,10 @@ * and Carlos Rica <jasampler@gmail.com> that was itself based on * git-tag.sh and mktag.c by Linus Torvalds. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "editor.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h" @@ -22,7 +21,6 @@ #include "object-name.h" #include "object-store-ll.h" #include "replace-object.h" -#include "repository.h" #include "tag.h" #include "wildmatch.h" @@ -203,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) || @@ -514,7 +512,7 @@ static int create_graft(int argc, const char **argv, int force, int gentle) static int convert_graft_file(int force) { - const char *graft_file = get_graft_file(the_repository); + const char *graft_file = repo_get_graft_file(the_repository); FILE *fp = fopen_or_warn(graft_file, "r"); struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT; struct strvec args = STRVEC_INIT; @@ -545,7 +543,10 @@ static int convert_graft_file(int force) return -1; } -int cmd_replace(int argc, const char **argv, const char *prefix) +int cmd_replace(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int force = 0; int raw = 0; diff --git a/builtin/replay.c b/builtin/replay.c index 138198ce9c..2d12a4e403 100644 --- a/builtin/replay.c +++ b/builtin/replay.c @@ -4,6 +4,7 @@ #include "git-compat-util.h" +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "environment.h" #include "hex.h" @@ -274,7 +275,10 @@ static struct commit *pick_regular_commit(struct commit *pickme, return create_commit(result->tree, pickme, replayed_base); } -int cmd_replay(int argc, const char **argv, const char *prefix) +int cmd_replay(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *advance_name_opt = NULL; char *advance_name = NULL; diff --git a/builtin/rerere.c b/builtin/rerere.c index 81b65ffa39..f7143c3f5d 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -1,8 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "parse-options.h" -#include "repository.h" + #include "string-list.h" #include "rerere.h" #include "xdiff/xdiff.h" @@ -48,7 +49,10 @@ static int diff_two(const char *file1, const char *label1, return ret; } -int cmd_rerere(int argc, const char **argv, const char *prefix) +int cmd_rerere(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct string_list merge_rr = STRING_LIST_INIT_DUP; int i, autoupdate = -1, flags = 0; diff --git a/builtin/reset.c b/builtin/reset.c index 5f941fb3a2..7154f88826 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -7,7 +7,7 @@ * * Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -26,6 +26,7 @@ #include "object-name.h" #include "parse-options.h" #include "path.h" +#include "repository.h" #include "unpack-trees.h" #include "cache-tree.h" #include "setup.h" @@ -330,7 +331,10 @@ static int git_reset_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_reset(int argc, const char **argv, const char *prefix) +int cmd_reset(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int reset_type = NONE, update_ref_status = 0, quiet = 0; int no_refresh = 0; @@ -441,7 +445,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) else trace2_cmd_mode(reset_type_names[reset_type]); - if (reset_type != SOFT && (reset_type != MIXED || get_git_work_tree())) + if (reset_type != SOFT && (reset_type != MIXED || repo_get_work_tree(the_repository))) setup_work_tree(); if (reset_type == MIXED && is_bare_repository()) @@ -474,7 +478,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) goto cleanup; } the_repository->index->updated_skipworktree = 1; - if (!no_refresh && get_git_work_tree()) { + if (!no_refresh && repo_get_work_tree(the_repository)) { uint64_t t_begin, t_delta_in_ms; t_begin = getnanotime(); diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 97d077a994..8fe83893fa 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "commit.h" @@ -120,7 +121,7 @@ static inline void finish_object__ma(struct object *obj) 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)); @@ -484,6 +485,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; @@ -513,7 +521,10 @@ static int try_bitmap_disk_usage(struct rev_info *revs, return 0; } -int cmd_rev_list(int argc, const char **argv, const char *prefix) +int cmd_rev_list(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct rev_info revs; struct rev_list_info info; diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 4285dc34a7..8401b4d7ab 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -3,8 +3,9 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" + #include "abspath.h" #include "config.h" #include "commit.h" @@ -19,6 +20,8 @@ #include "path.h" #include "diff.h" #include "read-cache-ll.h" +#include "repo-settings.h" +#include "repository.h" #include "revision.h" #include "setup.h" #include "split-index.h" @@ -688,7 +691,10 @@ static void print_path(const char *path, const char *prefix, enum format_type fo free(cwd); } -int cmd_rev_parse(int argc, const char **argv, const char *prefix) +int cmd_rev_parse(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i, as_is = 0, verify = 0, quiet = 0, revs_count = 0, type = 0; const struct git_hash_algo *output_algo = NULL; @@ -898,7 +904,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) } if (opt_with_value(arg, "--abbrev-ref", &arg)) { abbrev_ref = 1; - abbrev_ref_strict = warn_ambiguous_refs; + abbrev_ref_strict = + repo_settings_get_warn_ambiguous_refs(the_repository); if (arg) { if (!strcmp(arg, "strict")) abbrev_ref_strict = 1; @@ -966,7 +973,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "--show-toplevel")) { - const char *work_tree = get_git_work_tree(); + const char *work_tree = repo_get_work_tree(the_repository); if (work_tree) print_path(work_tree, prefix, format, DEFAULT_UNMODIFIED); else @@ -991,7 +998,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) const char *pfx = prefix; if (!is_inside_work_tree()) { const char *work_tree = - get_git_work_tree(); + repo_get_work_tree(the_repository); if (work_tree) printf("%s\n", work_tree); continue; @@ -1042,7 +1049,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix) continue; } if (!strcmp(arg, "--git-common-dir")) { - print_path(get_git_common_dir(), prefix, format, DEFAULT_RELATIVE_IF_SHARED); + print_path(repo_get_common_dir(the_repository), prefix, format, DEFAULT_RELATIVE_IF_SHARED); continue; } if (!strcmp(arg, "--is-inside-git-dir")) { diff --git a/builtin/revert.c b/builtin/revert.c index 7bf2b4e11d..b7917dddd3 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -1,9 +1,9 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "builtin.h" #include "parse-options.h" #include "diff.h" #include "gettext.h" -#include "repository.h" #include "revision.h" #include "rerere.h" #include "sequencer.h" @@ -110,6 +110,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 +128,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 +243,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); @@ -261,7 +270,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, return sequencer_pick_revisions(the_repository, opts); } -int cmd_revert(int argc, const char **argv, const char *prefix) +int cmd_revert(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct replay_opts opts = REPLAY_OPTS_INIT; int res; @@ -275,7 +287,10 @@ int cmd_revert(int argc, const char **argv, const char *prefix) return res; } -int cmd_cherry_pick(int argc, const char **argv, const char *prefix) +int cmd_cherry_pick(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { struct replay_opts opts = REPLAY_OPTS_INIT; int res; diff --git a/builtin/rm.c b/builtin/rm.c index 0e79cbab62..eaff027258 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds 2006 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -15,7 +15,7 @@ #include "object-name.h" #include "parse-options.h" #include "read-cache.h" -#include "repository.h" + #include "string-list.h" #include "setup.h" #include "sparse-index.h" @@ -261,7 +261,10 @@ static struct option builtin_rm_options[] = { OPT_END(), }; -int cmd_rm(int argc, const char **argv, const char *prefix) +int cmd_rm(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct lock_file lock_file = LOCK_INIT; int i, ret = 0; diff --git a/builtin/send-pack.c b/builtin/send-pack.c index ef0df80824..59b626aae8 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "hex.h" @@ -147,7 +148,10 @@ static int send_pack_config(const char *k, const char *v, return git_default_config(k, v, ctx, cb); } -int cmd_send_pack(int argc, const char **argv, const char *prefix) +int cmd_send_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct refspec rs = REFSPEC_INIT_PUSH; const char *remote_name = NULL; @@ -336,8 +340,11 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) /* 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 b529608c92..c86b75d981 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "commit.h" @@ -5,7 +6,6 @@ #include "environment.h" #include "gettext.h" #include "string-list.h" -#include "repository.h" #include "revision.h" #include "utf8.h" #include "mailmap.h" @@ -378,7 +378,10 @@ void shortlog_finish_setup(struct shortlog *log) string_list_sort(&log->trailers); } -int cmd_shortlog(int argc, const char **argv, const char *prefix) +int cmd_shortlog(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct shortlog log = { STRING_LIST_INIT_NODUP }; struct rev_info rev; @@ -404,6 +407,18 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix) 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 29237f653d..cd6bdf63bc 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "environment.h" @@ -10,7 +11,7 @@ #include "strvec.h" #include "object-name.h" #include "parse-options.h" -#include "repository.h" + #include "dir.h" #include "commit-slab.h" #include "date.h" @@ -632,7 +633,10 @@ static int parse_reflog_param(const struct option *opt, const char *arg, return 0; } -int cmd_show_branch(int ac, const char **av, const char *prefix) +int cmd_show_branch(int ac, + const char **av, + const char *prefix, + struct repository *repo UNUSED) { struct commit *rev[MAX_REVS], *commit; char *reflog_msg[MAX_REVS] = {0}; diff --git a/builtin/show-index.c b/builtin/show-index.c index 540dc3dad1..f164c01bbe 100644 --- a/builtin/show-index.c +++ b/builtin/show-index.c @@ -1,17 +1,20 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "gettext.h" #include "hash.h" #include "hex.h" #include "pack.h" #include "parse-options.h" -#include "repository.h" static const char *const show_index_usage[] = { "git show-index [--object-format=<hash-algorithm>]", NULL }; -int cmd_show_index(int argc, const char **argv, const char *prefix) +int cmd_show_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i; unsigned nr; diff --git a/builtin/show-ref.c b/builtin/show-ref.c index f5899ce9ff..285cd3e433 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -287,7 +288,10 @@ static int exclude_existing_callback(const struct option *opt, const char *arg, return 0; } -int cmd_show_ref(int argc, const char **argv, const char *prefix) +int cmd_show_ref(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { struct exclude_existing_options exclude_existing_opts = {0}; struct patterns_options patterns_opts = {0}; diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 5ccf696862..34af5b2590 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "dir.h" @@ -7,7 +8,6 @@ #include "object-name.h" #include "parse-options.h" #include "pathspec.h" -#include "repository.h" #include "strbuf.h" #include "string-list.h" #include "lockfile.h" @@ -48,7 +48,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 +444,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 +671,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 +681,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 +708,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 +723,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 +737,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 +759,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 +775,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 +786,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 +799,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); + + ret = modify_pattern_list(&patterns, add_opts.use_stdin, ADD); - return modify_pattern_list(argc, argv, add_opts.use_stdin, ADD); + strvec_clear(&patterns); + return ret; } static char const * const builtin_sparse_checkout_set_usage[] = { @@ -808,7 +821,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 +840,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 +862,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 +887,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 +923,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 +947,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 +1012,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, @@ -1029,7 +1058,10 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char * return ret; } -int cmd_sparse_checkout(int argc, const char **argv, const char *prefix) +int cmd_sparse_checkout(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option builtin_sparse_checkout_options[] = { @@ -1052,5 +1084,5 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix) 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 be842258d0..c212b1c0b2 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "config.h" @@ -19,6 +20,7 @@ #include "entry.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "rerere.h" #include "revision.h" #include "setup.h" @@ -247,7 +249,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() @@ -539,8 +542,8 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, NULL, NULL, NULL)) return error(_("could not write index")); - if (write_index_as_tree(&c_tree, the_repository->index, get_index_file(), 0, - NULL)) + if (write_index_as_tree(&c_tree, the_repository->index, + repo_get_index_file(the_repository), 0, NULL)) return error(_("cannot apply a stash in the middle of a merge")); if (index) { @@ -565,7 +568,7 @@ static int do_apply_stash(const char *prefix, struct stash_info *info, discard_index(the_repository->index); repo_read_index(the_repository); if (write_index_as_tree(&index_tree, the_repository->index, - get_index_file(), 0, NULL)) + repo_get_index_file(the_repository), 0, NULL)) return error(_("could not save index tree")); reset_head(); @@ -640,9 +643,9 @@ restore_untracked: cp.git_cmd = 1; cp.dir = prefix; strvec_pushf(&cp.env, GIT_WORK_TREE_ENVIRONMENT"=%s", - absolute_path(get_git_work_tree())); + absolute_path(repo_get_work_tree(the_repository))); strvec_pushf(&cp.env, GIT_DIR_ENVIRONMENT"=%s", - absolute_path(get_git_dir())); + absolute_path(repo_get_git_dir(the_repository))); strvec_push(&cp.args, "status"); run_command(&cp); } @@ -650,7 +653,8 @@ restore_untracked: 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; @@ -724,7 +728,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; @@ -746,7 +751,8 @@ cleanup: 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; @@ -776,7 +782,8 @@ cleanup: 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; @@ -814,7 +821,8 @@ cleanup: 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[] = { @@ -887,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; @@ -974,7 +983,7 @@ static int show_stash(int argc, const char **argv, const char *prefix) } log_tree_diff_flush(&rev); - ret = diff_result_code(&rev.diffopt); + ret = diff_result_code(&rev); cleanup: strvec_clear(&revision_args); @@ -1015,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; @@ -1126,13 +1136,13 @@ static int check_changes_tracked_files(const struct pathspec *ps) diff_setup_done(&rev.diffopt); run_diff_index(&rev, DIFF_INDEX_CACHED); - if (diff_result_code(&rev.diffopt)) { + if (diff_result_code(&rev)) { ret = 1; goto done; } run_diff_files(&rev, 0); - if (diff_result_code(&rev.diffopt)) { + if (diff_result_code(&rev)) { ret = 1; goto done; } @@ -1405,8 +1415,8 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b strbuf_addf(&commit_tree_label, "index on %s\n", msg.buf); commit_list_insert(head_commit, &parents); - if (write_index_as_tree(&info->i_tree, the_repository->index, get_index_file(), 0, - NULL) || + if (write_index_as_tree(&info->i_tree, the_repository->index, + repo_get_index_file(the_repository), 0, NULL) || commit_tree(commit_tree_label.buf, commit_tree_label.len, &info->i_tree, parents, &info->i_commit, NULL, NULL)) { if (!quiet) @@ -1489,7 +1499,8 @@ done: 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; @@ -1757,7 +1768,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, @@ -1819,16 +1830,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; @@ -1871,7 +1886,10 @@ static int save_stash(int argc, const char **argv, const char *prefix) return ret; } -int cmd_stash(int argc, const char **argv, const char *prefix) +int cmd_stash(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { pid_t pid = getpid(); const char *index_file; @@ -1904,14 +1922,14 @@ int cmd_stash(int argc, const char **argv, const char *prefix) prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - index_file = get_index_file(); + index_file = repo_get_index_file(the_repository); strbuf_addf(&stash_index_path, "%s.stash.%" PRIuMAX, index_file, (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/stripspace.c b/builtin/stripspace.c index e5626e5126..e147f3ff92 100644 --- a/builtin/stripspace.c +++ b/builtin/stripspace.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "environment.h" @@ -29,7 +30,10 @@ enum stripspace_mode { COMMENT_LINES }; -int cmd_stripspace(int argc, const char **argv, const char *prefix) +int cmd_stripspace(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf buf = STRBUF_INIT; enum stripspace_mode mode = STRIP_DEFAULT; diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index a46ffd49b3..19e5878381 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1,9 +1,10 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "environment.h" #include "gettext.h" #include "hex.h" -#include "repository.h" + #include "config.h" #include "parse-options.h" #include "quote.h" @@ -363,9 +364,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; @@ -394,7 +399,8 @@ cleanup: 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 }; @@ -539,7 +545,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 }; @@ -672,7 +679,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, setup_revisions(diff_files_args.nr, diff_files_args.v, &rev, &opt); run_diff_files(&rev, 0); - if (!diff_result_code(&rev.diffopt)) { + if (!diff_result_code(&rev)) { print_status(flags, ' ', path, ce_oid, displaypath); } else if (!(flags & OPT_CACHED)) { @@ -695,6 +702,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, if (flags & OPT_RECURSIVE) { struct child_process cpr = CHILD_PROCESS_INIT; + int res; cpr.git_cmd = 1; cpr.dir = path; @@ -710,7 +718,10 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, if (flags & OPT_QUIET) strvec_push(&cpr.args, "--quiet"); - if (run_command(&cpr)) + res = run_command(&cpr); + if (res == SIGPIPE + 128) + raise(SIGPIPE); + else if (res) die(_("failed to recurse into submodule '%s'"), path); } @@ -729,7 +740,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 }; @@ -1154,7 +1166,8 @@ cleanup: 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; @@ -1330,7 +1343,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 }; @@ -1476,7 +1490,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 }; @@ -1617,6 +1632,8 @@ static int add_possible_reference_from_superproject( ; /* nothing */ } } + + strbuf_release(&err); strbuf_release(&sb); } @@ -1709,7 +1726,7 @@ static int clone_submodule(const struct module_clone_data *clone_data, exit(128); if (!is_absolute_path(clone_data->path)) - clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(), + clone_data_path = to_free = xstrfmt("%s/%s", repo_get_work_tree(the_repository), clone_data->path); if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0) @@ -1831,7 +1848,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; @@ -2021,6 +2039,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); } @@ -2321,7 +2340,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); @@ -2641,15 +2667,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); } @@ -2755,7 +2786,8 @@ cleanup: 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 }; @@ -2887,7 +2919,8 @@ cleanup: 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; @@ -2958,14 +2991,17 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED) rs->src); } } + refspec_clear(&refspec); + free_refs(local_refs); } free(head); 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 }; @@ -2998,7 +3034,8 @@ cleanup: 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; @@ -3037,7 +3074,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; @@ -3087,7 +3125,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; @@ -3398,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; @@ -3528,7 +3568,10 @@ cleanup: return ret; } -int cmd_submodule__helper(int argc, const char **argv, const char *prefix) +int cmd_submodule__helper(int argc, + const char **argv, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; const char *const usage[] = { @@ -3554,5 +3597,5 @@ int cmd_submodule__helper(int argc, const char **argv, const char *prefix) }; argc = parse_options(argc, argv, prefix, options, usage, 0); - return fn(argc, argv, prefix); + return fn(argc, argv, prefix, repo); } diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 81abdd170f..299d23d76a 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -41,7 +42,10 @@ static int check_symref(const char *HEAD, int quiet, int shorten, int recurse, i return 0; } -int cmd_symbolic_ref(int argc, const char **argv, const char *prefix) +int cmd_symbolic_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int quiet = 0, delete = 0, shorten = 0, recurse = 1, ret = 0; const char *msg = NULL; diff --git a/builtin/tag.c b/builtin/tag.c index a1fb218512..affa14d659 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -5,7 +5,7 @@ * Carlos Rica <jasampler@gmail.com> * Based on git-tag.sh and mktag.c by Linus Torvalds. */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "advice.h" #include "config.h" @@ -160,11 +160,11 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid, const struct git_hash_algo *compat = the_repository->compat_hash_algo; struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT; struct strbuf compat_buf = STRBUF_INIT; - const char *keyid = get_signing_key(); + char *keyid = get_signing_key(); 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; @@ -190,6 +190,7 @@ out: strbuf_release(&sig); strbuf_release(&compat_sig); strbuf_release(&compat_buf); + free(keyid); return ret; } @@ -446,18 +447,10 @@ 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) +int cmd_tag(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strbuf buf = STRBUF_INIT; struct strbuf ref = STRBUF_INIT; @@ -646,7 +639,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) 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)) @@ -677,7 +670,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) } 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, @@ -702,6 +695,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) 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 c129e2bb6c..6da2825753 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "hex.h" @@ -25,7 +26,10 @@ static char *create_temp_file(struct object_id *oid) return path; } -int cmd_unpack_file(int argc, const char **argv, const char *prefix UNUSED) +int cmd_unpack_file(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { struct object_id oid; diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 08fa2a7a74..02b8d02f63 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "bulk-checkin.h" #include "config.h" @@ -601,7 +602,10 @@ static void unpack_all(void) die("unresolved deltas left after unpacking"); } -int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED) +int cmd_unpack_objects(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { int i; struct object_id oid; diff --git a/builtin/update-index.c b/builtin/update-index.c index 35a1f957ad..45b4a8b555 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -3,7 +3,7 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "bulk-checkin.h" #include "config.h" @@ -22,7 +22,6 @@ #include "pathspec.h" #include "dir.h" #include "read-cache.h" -#include "repository.h" #include "setup.h" #include "sparse-index.h" #include "split-index.h" @@ -917,7 +916,10 @@ static enum parse_opt_result reupdate_callback( return 0; } -int cmd_update_index(int argc, const char **argv, const char *prefix) +int cmd_update_index(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int newfd, entries, has_errors = 0, nul_term_line = 0; enum uc_mode untracked_cache = UC_UNSPECIFIED; @@ -1194,7 +1196,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) "remove or change it, if you really want to " "enable the untracked cache")); add_untracked_cache(the_repository->index); - report(_("Untracked cache enabled for '%s'"), get_git_work_tree()); + report(_("Untracked cache enabled for '%s'"), repo_get_work_tree(the_repository)); break; default: BUG("bad untracked_cache value: %d", untracked_cache); @@ -1239,7 +1241,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) if (newfd < 0) { if (refresh_args.flags & REFRESH_QUIET) exit(128); - unable_to_lock_die(get_index_file(), lock_error); + unable_to_lock_die(repo_get_index_file(the_repository), lock_error); } if (write_locked_index(the_repository->index, &lock_file, COMMIT_LOCK)) die("Unable to write new index file"); diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 8f31da9a4b..670e7812d6 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -6,7 +7,6 @@ #include "object-name.h" #include "parse-options.h" #include "quote.h" -#include "repository.h" static const char * const git_update_ref_usage[] = { N_("git update-ref [<options>] -d <refname> [<old-oid>]"), @@ -612,7 +612,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 +680,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); @@ -713,7 +713,10 @@ static void update_refs_stdin(void) strbuf_release(&input); } -int cmd_update_ref(int argc, const char **argv, const char *prefix) +int cmd_update_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *refname, *oldval; struct object_id oid, oldoid; diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index 1dc3971ede..6769611a02 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -9,7 +10,10 @@ static const char * const update_server_info_usage[] = { NULL }; -int cmd_update_server_info(int argc, const char **argv, const char *prefix) +int cmd_update_server_info(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int force = 0; struct option options[] = { diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index 313a8dfa81..9e9343f121 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -1,12 +1,12 @@ /* * Copyright (c) 2006 Franck Bui-Huu */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "archive.h" #include "path.h" #include "pkt-line.h" #include "sideband.h" -#include "repository.h" #include "run-command.h" #include "strvec.h" @@ -18,7 +18,10 @@ static const char deadchild[] = #define MAX_ARGS (64) -int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix) +int cmd_upload_archive_writer(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { struct strvec sent_argv = STRVEC_INIT; const char *arg_cmd = "argument "; @@ -80,7 +83,10 @@ static ssize_t process_input(int child_fd, int band) return sz; } -int cmd_upload_archive(int argc, const char **argv, const char *prefix) +int cmd_upload_archive(int argc, +const char **argv, +const char *prefix, +struct repository *repo UNUSED) { struct child_process writer = CHILD_PROCESS_INIT; diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c index 46d93278d9..dd63d6eadf 100644 --- a/builtin/upload-pack.c +++ b/builtin/upload-pack.c @@ -17,7 +17,10 @@ static const char * const upload_pack_usage[] = { NULL }; -int cmd_upload_pack(int argc, const char **argv, const char *prefix) +int cmd_upload_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { const char *dir; int strict = 0; @@ -36,6 +39,7 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix) 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(); @@ -51,7 +55,9 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix) 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()) { diff --git a/builtin/var.c b/builtin/var.c index e30ff45be1..2ecaed51b4 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" #include "config.h" #include "editor.h" @@ -210,7 +212,10 @@ static int show_config(const char *var, const char *value, return git_default_config(var, value, ctx, cb); } -int cmd_var(int argc, const char **argv, const char *prefix UNUSED) +int cmd_var(int argc, + const char **argv, + const char *prefix UNUSED, + struct repository *repo UNUSED) { const struct git_var *git_var; char *val; diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index 0d2b9aea2a..779b7988ca 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -5,11 +5,11 @@ * * Based on git-verify-tag */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" #include "object-name.h" -#include "repository.h" #include "commit.h" #include "parse-options.h" #include "gpg-interface.h" @@ -51,7 +51,10 @@ static int verify_commit(const char *name, unsigned flags) return run_gpg_verify((struct commit *)obj, flags); } -int cmd_verify_commit(int argc, const char **argv, const char *prefix) +int cmd_verify_commit(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i = 1, verbose = 0, had_error = 0; unsigned flags = 0; diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index 011dddd2dc..34e4ed715f 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -61,7 +62,10 @@ static const char * const verify_pack_usage[] = { NULL }; -int cmd_verify_pack(int argc, const char **argv, const char *prefix) +int cmd_verify_pack(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int err = 0; unsigned int flags = 0; diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index c731e2f87b..a7f20618ff 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -5,6 +5,7 @@ * * Based on git-verify-tag.sh */ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "gettext.h" @@ -19,7 +20,10 @@ static const char * const verify_tag_usage[] = { NULL }; -int cmd_verify_tag(int argc, const char **argv, const char *prefix) +int cmd_verify_tag(int argc, + const char **argv, + const char *prefix, + struct repository *repo UNUSED) { int i = 1, verbose = 0, had_error = 0; unsigned flags = 0; @@ -65,5 +69,6 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix) 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 41e7f6a327..0186d60ab1 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -1,3 +1,4 @@ +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "abspath.h" #include "advice.h" @@ -17,7 +18,6 @@ #include "read-cache-ll.h" #include "refs.h" #include "remote.h" -#include "repository.h" #include "run-command.h" #include "hook.h" #include "sigchain.h" @@ -120,12 +120,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 +136,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); @@ -219,7 +224,7 @@ static void prune_worktrees(void) } closedir(dir); - strbuf_add_absolute_path(&main_path, get_git_common_dir()); + strbuf_add_absolute_path(&main_path, repo_get_common_dir(the_repository)); /* massage main worktree absolute path to match 'gitdir' content */ strbuf_strip_suffix(&main_path, "/."); string_list_append_nodup(&kept, strbuf_detach(&main_path, NULL)); @@ -231,7 +236,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")), @@ -414,7 +420,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 +438,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) @@ -490,11 +496,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, get_git_common_dir(), 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 +584,6 @@ done: strbuf_release(&sb_repo); strbuf_release(&sb_git); strbuf_release(&sb_name); - strbuf_release(&realpath); free_worktree(wt); return ret; } @@ -604,7 +605,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); @@ -745,7 +746,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 +762,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 +796,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 +843,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 +1042,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 +1088,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[] = { @@ -1117,7 +1124,8 @@ static int lock_worktree(int ac, const char **av, const char *prefix) 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() @@ -1180,13 +1188,16 @@ static void validate_no_submodules(const struct worktree *wt) 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 +1250,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 +1321,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 +1387,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,12 +1402,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) +int cmd_worktree(int ac, + const char **av, + const char *prefix, + struct repository *repo) { parse_opt_subcommand_fn *fn = NULL; struct option options[] = { @@ -1417,5 +1435,5 @@ int cmd_worktree(int ac, const char **av, const char *prefix) 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/builtin/write-tree.c b/builtin/write-tree.c index 8c75b4609b..43f233e69b 100644 --- a/builtin/write-tree.c +++ b/builtin/write-tree.c @@ -3,23 +3,24 @@ * * Copyright (C) Linus Torvalds, 2005 */ - +#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" -#include "environment.h" #include "gettext.h" #include "hex.h" #include "tree.h" #include "cache-tree.h" #include "parse-options.h" -#include "repository.h" static const char * const write_tree_usage[] = { N_("git write-tree [--missing-ok] [--prefix=<prefix>/]"), NULL }; -int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix) +int cmd_write_tree(int argc, + const char **argv, + const char *cmd_prefix, + struct repository *repo UNUSED) { int flags = 0, ret; const char *tree_prefix = NULL; @@ -44,7 +45,8 @@ int cmd_write_tree(int argc, const char **argv, const char *cmd_prefix) prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - ret = write_index_as_tree(&oid, the_repository->index, get_index_file(), + ret = write_index_as_tree(&oid, the_repository->index, + repo_get_index_file(the_repository), flags, tree_prefix); switch (ret) { case 0: diff --git a/bulk-checkin.c b/bulk-checkin.c index 9089c214fa..2753d5bbe4 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -75,7 +75,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state) close(fd); } - strbuf_addf(&packname, "%s/pack/pack-%s.", get_object_directory(), + strbuf_addf(&packname, "%s/pack/pack-%s.", repo_get_object_directory(the_repository), hash_to_hex(hash)); finish_tmp_packfile(&packname, state->pack_tmp_name, state->written, state->nr_written, @@ -113,7 +113,7 @@ static void flush_batch_fsync(void) * to ensure that the data in each new object file is durable before * the final name is visible. */ - strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", get_object_directory()); + strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", repo_get_object_directory(the_repository)); temp = xmks_tempfile(temp_path.buf); fsync_or_die(get_tempfile_fd(temp), get_tempfile_path(temp)); delete_tempfile(&temp); diff --git a/bundle-uri.c b/bundle-uri.c index dc0c96955b..cdf9e4f9e1 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -4,7 +4,6 @@ #include "bundle-uri.h" #include "bundle.h" #include "copy.h" -#include "environment.h" #include "gettext.h" #include "refs.h" #include "run-command.h" @@ -14,6 +13,7 @@ #include "fetch-pack.h" #include "remote.h" #include "trace2.h" +#include "object-store-ll.h" static struct { enum bundle_list_heuristic heuristic; @@ -367,18 +367,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 +416,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; } @@ -420,36 +420,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,11 +598,15 @@ out: 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)) return -1; strvec_pushl(&ip.args, "index-pack", "--fix-thin", "--stdin", NULL); @@ -641,8 +615,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); @@ -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,12 @@ 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'. */ 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 50610c3f3c..c595e86120 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -1,7 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" -#include "environment.h" +#include "gettext.h" #include "hex.h" #include "lockfile.h" #include "tree.h" @@ -12,6 +12,7 @@ #include "object-store-ll.h" #include "read-cache-ll.h" #include "replace-object.h" +#include "repository.h" #include "promisor-remote.h" #include "trace.h" #include "trace2.h" @@ -725,7 +726,8 @@ int write_index_as_tree(struct object_id *oid, struct index_state *index_state, hold_lock_file_for_update(&lock_file, index_path, LOCK_DIE_ON_ERROR); - entries = read_index_from(index_state, index_path, get_git_dir()); + entries = read_index_from(index_state, index_path, + repo_get_git_dir(the_repository)); if (entries < 0) { ret = WRITE_TREE_UNREADABLE_INDEX; goto out; @@ -864,15 +866,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; } /* @@ -881,6 +883,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, @@ -890,18 +893,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) { /* @@ -911,12 +919,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; @@ -924,6 +934,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]; @@ -934,16 +949,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; @@ -956,27 +978,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 faae88be63..b82c4963e7 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 @@ -12,7 +12,7 @@ static struct cb_node *cb_node_of(const void *p) return (struct cb_node *)((uintptr_t)p - 1); } -/* locate the best match, does not do a final comparision */ +/* locate the best match, does not do a final comparison */ static struct cb_node *cb_internal_best_match(struct cb_node *p, const uint8_t *k, size_t klen) { diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 4781cd20bb..d020cb7aa5 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -29,41 +29,54 @@ alpine-*) 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 ;; -ubuntu-*) +ubuntu-*|ubuntu32-*|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' + ;; + ubuntu32-*) + 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 libsvn-perl apache2 cvs cvsps git gnupg subversion \ + $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 \ ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE - mkdir --parents "$CUSTOM_PATH" - wget --quiet --directory-prefix="$CUSTOM_PATH" \ - "$P4WHENCE/bin.linux26x86_64/p4d" "$P4WHENCE/bin.linux26x86_64/p4" - chmod a+x "$CUSTOM_PATH/p4d" "$CUSTOM_PATH/p4" + case "$distro" in + ubuntu-*) + mkdir --parents "$CUSTOM_PATH" - wget --quiet "$LFSWHENCE/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" - tar -xzf "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" \ - -C "$CUSTOM_PATH" --strip-components=1 "git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs" - rm "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + wget --quiet --directory-prefix="$CUSTOM_PATH" \ + "$P4WHENCE/bin.linux26x86_64/p4d" "$P4WHENCE/bin.linux26x86_64/p4" + chmod a+x "$CUSTOM_PATH/p4d" "$CUSTOM_PATH/p4" - wget --quiet "$JGITWHENCE" --output-document="$CUSTOM_PATH/jgit" - chmod a+x "$CUSTOM_PATH/jgit" - ;; -ubuntu32-*) - sudo linux32 --32bit i386 sh -c ' - apt update >/dev/null && - apt install -y build-essential libcurl4-openssl-dev \ - libssl-dev libexpat-dev gettext python >/dev/null - ' + wget --quiet "$LFSWHENCE/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + tar -xzf "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" \ + -C "$CUSTOM_PATH" --strip-components=1 "git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs" + rm "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + + wget --quiet "$JGITWHENCE" --output-document="$CUSTOM_PATH/jgit" + chmod a+x "$CUSTOM_PATH/jgit" + ;; + esac ;; macos-*) export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 @@ -107,6 +120,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 0000000000..66f24838a4 --- /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" @@ -62,7 +62,7 @@ trap "end_group 'CI setup'" EXIT # 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 () { @@ -250,8 +250,13 @@ 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 +264,12 @@ then export PATH="$(brew --prefix)/bin:$PATH" CI_OS_NAME=osx + JOBS=$(nproc) + ;; + *,alpine:*|*,fedora:*|*,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 +280,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 +289,6 @@ then cache_dir="$HOME/none" distro=$(echo "$CI_JOB_IMAGE" | tr : -) - JOBS=$(nproc) else echo "Could not identify CI type" >&2 env >&2 @@ -336,7 +344,14 @@ ubuntu-*) fi MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/$PYTHON_PACKAGE" - export GIT_TEST_HTTPD=true + case "$distro" in + ubuntu-16.04) + # Apache is too old for HTTP/2. + ;; + *) + export GIT_TEST_HTTPD=true + ;; + esac # The Linux build installs the defined dependency versions below. # The OS X build installs much more recent versions, whichever @@ -369,7 +384,6 @@ linux-musl) ;; linux-leaks|linux-reftable-leaks) export SANITIZE=leak - export GIT_TEST_PASSING_SANITIZE_LEAK=true ;; linux-asan-ubsan) export SANITIZE=address,undefined diff --git a/ci/run-build-and-minimal-fuzzers.sh b/ci/run-build-and-minimal-fuzzers.sh index af8065f349..e7b97952e7 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-docker-build.sh b/ci/run-docker-build.sh deleted file mode 100755 index 6cd832efb9..0000000000 --- a/ci/run-docker-build.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# -# Build and test Git inside container -# -# Usage: -# run-docker-build.sh <host-user-id> -# - -set -ex - -if test $# -ne 1 || test -z "$1" -then - echo >&2 "usage: run-docker-build.sh <host-user-id>" - exit 1 -fi - -case "$jobname" in -linux32) - switch_cmd="linux32 --32bit i386" - ;; -linux-musl) - switch_cmd= - useradd () { adduser -D "$@"; } - ;; -*) - exit 1 - ;; -esac - -"${0%/*}/install-docker-dependencies.sh" - -# If this script runs inside a docker container, then all commands are -# usually executed as root. Consequently, the host user might not be -# able to access the test output files. -# If a non 0 host user id is given, then create a user "ci" with that -# user id to make everything accessible to the host user. -HOST_UID=$1 -if test $HOST_UID -eq 0 -then - # Just in case someone does want to run the test suite as root. - CI_USER=root -else - CI_USER=ci - if test "$(id -u $CI_USER 2>/dev/null)" = $HOST_UID - then - echo "user '$CI_USER' already exists with the requested ID $HOST_UID" - else - useradd -u $HOST_UID $CI_USER - fi -fi - -# Build and test -command $switch_cmd su -m -l $CI_USER -c " - set -ex - export DEVELOPER='$DEVELOPER' - export DEFAULT_TEST_TARGET='$DEFAULT_TEST_TARGET' - export GIT_PROVE_OPTS='$GIT_PROVE_OPTS' - export GIT_TEST_OPTS='$GIT_TEST_OPTS' - export GIT_TEST_CLONE_2GB='$GIT_TEST_CLONE_2GB' - export MAKEFLAGS='$MAKEFLAGS' - export cache_dir='$cache_dir' - cd /usr/src/git - test -n '$cache_dir' && ln -s '$cache_dir/.prove' t/.prove - make - make test -" diff --git a/ci/run-docker.sh b/ci/run-docker.sh deleted file mode 100755 index af89d1624a..0000000000 --- a/ci/run-docker.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# Download and run Docker image to build and test Git -# - -. ${0%/*}/lib.sh - -case "$jobname" in -linux32) - CI_CONTAINER="daald/ubuntu32:xenial" - ;; -linux-musl) - CI_CONTAINER=alpine - ;; -*) - exit 1 - ;; -esac - -docker pull "$CI_CONTAINER" - -# Use the following command to debug the docker build locally: -# <host-user-id> must be 0 if podman is used as drop-in replacement for docker -# $ docker run -itv "${PWD}:/usr/src/git" --entrypoint /bin/sh "$CI_CONTAINER" -# root@container:/# export jobname=<jobname> -# root@container:/# /usr/src/git/ci/run-docker-build.sh <host-user-id> - -container_cache_dir=/tmp/container-cache - -docker run \ - --interactive \ - --env DEVELOPER \ - --env DEFAULT_TEST_TARGET \ - --env GIT_PROVE_OPTS \ - --env GIT_TEST_OPTS \ - --env GIT_TEST_CLONE_2GB \ - --env MAKEFLAGS \ - --env jobname \ - --env cache_dir="$container_cache_dir" \ - --volume "${PWD}:/usr/src/git" \ - --volume "$cache_dir:$container_cache_dir" \ - "$CI_CONTAINER" \ - /usr/src/git/ci/run-docker-build.sh $(id -u $USER) - -check_unignored_build_artifacts - -save_good_tree diff --git a/ci/test-documentation.sh b/ci/test-documentation.sh index 02b3af3941..6c018b673e 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/combine-diff.c b/combine-diff.c index 829a44e416..33d0ed7097 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -1185,7 +1185,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 +1221,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) { @@ -1393,9 +1394,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 */ diff --git a/commit-graph.c b/commit-graph.c index aa6e08eb39..e2e2083951 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1914,7 +1914,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx, 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; @@ -1960,7 +1960,7 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx) ctx->progress = start_delayed_progress( _("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); @@ -2055,7 +2055,6 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) } if (safe_create_leading_directories(ctx->graph_name)) { - UNLEAK(ctx->graph_name); error(_("unable to create leading directories of %s"), ctx->graph_name); return -1; @@ -183,7 +183,7 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid) commit_graft_oid_access); } -static void unparse_commit(struct repository *r, const struct object_id *oid) +void unparse_commit(struct repository *r, const struct object_id *oid) { struct commit *c = lookup_commit(r, oid); @@ -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); @@ -292,14 +292,14 @@ static int read_graft_file(struct repository *r, const char *graft_file) void prepare_commit_graft(struct repository *r) { - char *graft_file; + const char *graft_file; if (r->parsed_objects->commit_graft_prepared) return; if (!startup_info->have_repository) return; - graft_file = get_graft_file(r); + graft_file = repo_get_graft_file(r); read_graft_file(r, graft_file); /* make sure shallows are read */ is_repository_shallow(r); @@ -324,18 +324,6 @@ int for_each_commit_graft(each_commit_graft_fn fn, void *cb_data) return ret; } -void reset_commit_grafts(struct repository *r) -{ - int i; - - for (i = 0; i < r->parsed_objects->grafts_nr; i++) { - unparse_commit(r, &r->parsed_objects->grafts[i]->oid); - free(r->parsed_objects->grafts[i]); - } - r->parsed_objects->grafts_nr = 0; - r->parsed_objects->commit_graft_prepared = 0; -} - struct commit_buffer { void *buffer; unsigned long size; @@ -607,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; } @@ -1156,11 +1145,14 @@ int add_header_signature(struct strbuf *buf, struct strbuf *sig, const struct gi static int sign_commit_to_strbuf(struct strbuf *sig, struct strbuf *buf, const char *keyid) { + char *keyid_to_free = NULL; + int ret = 0; if (!keyid || !*keyid) - keyid = get_signing_key(); + keyid = keyid_to_free = get_signing_key(); if (sign_buffer(buf, sig, keyid)) - return -1; - return 0; + ret = -1; + free(keyid_to_free); + return ret; } int parse_signed_commit(const struct commit *commit, @@ -110,6 +110,8 @@ static inline int repo_parse_commit_no_graph(struct repository *r, void parse_commit_or_die(struct commit *item); +void unparse_commit(struct repository *r, const struct object_id *oid); + struct buffer_slab; struct buffer_slab *allocate_commit_buffer_slab(void); void free_commit_buffer_slab(struct buffer_slab *bs); @@ -242,7 +244,6 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid); int register_commit_graft(struct repository *r, struct commit_graft *, int); void prepare_commit_graft(struct repository *r); struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid); -void reset_commit_grafts(struct repository *r); struct commit *get_fork_point(const char *refname, struct commit *commit); @@ -253,7 +254,10 @@ struct oid_array; struct ref; int for_each_commit_graft(each_commit_graft_fn, void *); -int interactive_add(const char **argv, const char *prefix, int patch); +int interactive_add(struct repository *repo, + const char **argv, + const char *prefix, + int patch); struct commit_extra_header { struct commit_extra_header *next; diff --git a/compat/compiler.h b/compat/compiler.h index e9ad9db84f..e12e426404 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 2fc67442eb..dfa551459d 100644 --- a/compat/fsmonitor/fsm-listen-darwin.c +++ b/compat/fsmonitor/fsm-listen-darwin.c @@ -516,6 +516,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 5a21dade7b..9a6efc9bea 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 eb13c02a76..63f36c893b 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "../git-compat-util.h" #include "win32.h" #include <aclapi.h> @@ -500,7 +502,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(); @@ -531,6 +533,70 @@ static int mingw_open_append(wchar_t const *wfilename, int oflags, ...) } /* + * 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? */ @@ -565,6 +631,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; @@ -780,7 +848,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]; @@ -889,7 +957,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)) @@ -1004,7 +1072,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 && @@ -1272,7 +1340,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); @@ -1337,7 +1406,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, "/\\")) @@ -1954,7 +2023,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]; @@ -1966,7 +2035,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); @@ -1981,7 +2051,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); /* @@ -1999,7 +2070,7 @@ char *mingw_getenv(const char *name) int mingw_putenv(const char *namevalue) { - int size; + size_t size; wchar_t *wide, *equal; BOOL result; @@ -2009,7 +2080,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) @@ -2149,10 +2221,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; /* @@ -2163,11 +2241,84 @@ 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_ATTRIBUTE_NORMAL, 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) { @@ -3083,7 +3234,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/regex/regexec.c b/compat/regex/regexec.c index e92be5741d..2eeec82f40 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 cb176d966f..d1c21b49bd 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 9b3f2cdf8c..7db3b2a897 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 8bfe51248e..a8fc812adf 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/vcbuild/include/unistd.h b/compat/vcbuild/include/unistd.h index 3a959d124c..a261a925b7 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/path-utils.c b/compat/win32/path-utils.c index b658ca3f81..966ef779b9 100644 --- a/compat/win32/path-utils.c +++ b/compat/win32/path-utils.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "../../git-compat-util.h" #include "../../environment.h" @@ -6,6 +6,8 @@ * */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "advice.h" @@ -304,13 +306,16 @@ static int include_by_branch(struct config_include_data *data, int flags; int ret; struct strbuf pattern = STRBUF_INIT; - const char *refname = (!data->repo || !data->repo->gitdir) ? - NULL : refs_resolve_ref_unsafe(get_main_ref_store(data->repo), - "HEAD", 0, NULL, &flags); - const char *shortname; + const char *refname, *shortname; + + if (!data->repo || data->repo->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN) + return 0; - if (!refname || !(flags & REF_ISSYMREF) || - !skip_prefix(refname, "refs/heads/", &shortname)) + refname = refs_resolve_ref_unsafe(get_main_ref_store(data->repo), + "HEAD", 0, NULL, &flags); + if (!refname || + !(flags & REF_ISSYMREF) || + !skip_prefix(refname, "refs/heads/", &shortname)) return 0; strbuf_add(&pattern, cond, cond_len); @@ -1445,26 +1450,6 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.prefersymlinkrefs")) { - prefer_symlink_refs = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.logallrefupdates")) { - if (value && !strcasecmp(value, "always")) - log_all_ref_updates = LOG_REFS_ALWAYS; - else if (git_config_bool(var, value)) - log_all_ref_updates = LOG_REFS_NORMAL; - else - log_all_ref_updates = LOG_REFS_NONE; - return 0; - } - - if (!strcmp(var, "core.warnambiguousrefs")) { - warn_ambiguous_refs = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.abbrev")) { if (!value) return config_error_nonbool(var); @@ -1508,33 +1493,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; @@ -1573,14 +1536,6 @@ static int git_default_core_config(const char *var, const char *value, return git_config_string(&check_roundtrip_encoding, var, value); } - if (!strcmp(var, "core.notesref")) { - if (!value) - return config_error_nonbool(var); - free(notes_ref_name); - notes_ref_name = xstrdup(value); - return 0; - } - if (!strcmp(var, "core.editor")) { FREE_AND_NULL(editor_program); return git_config_string(&editor_program, var, value); @@ -2202,7 +2157,7 @@ static void configset_iter(struct config_set *set, config_fn_t fn, void *data) } } -void read_early_config(config_fn_t cb, void *data) +void read_early_config(struct repository *repo, config_fn_t cb, void *data) { struct config_options opts = {0}; struct strbuf commondir = STRBUF_INIT; @@ -2210,9 +2165,9 @@ void read_early_config(config_fn_t cb, void *data) opts.respect_includes = 1; - if (have_git_dir()) { - opts.commondir = get_git_common_dir(); - opts.git_dir = get_git_dir(); + if (repo && repo->gitdir) { + opts.commondir = repo_get_common_dir(repo); + opts.git_dir = repo_get_git_dir(repo); /* * When setup_git_directory() was not yet asked to discover the * GIT_DIR, we ask discover_git_directory() to figure out whether there @@ -2232,10 +2187,6 @@ void read_early_config(config_fn_t cb, void *data) strbuf_release(&gitdir); } -/* - * Read config but only enumerate system and global settings. - * Omit any repo-local, worktree-local, or command-line settings. - */ void read_very_early_config(config_fn_t cb, void *data) { struct config_options opts = { 0 }; @@ -192,7 +192,18 @@ int git_config_from_blob_oid(config_fn_t fn, const char *name, void git_config_push_parameter(const char *text); void git_config_push_env(const char *spec); int git_config_from_parameters(config_fn_t fn, void *data); -void read_early_config(config_fn_t cb, void *data); + +/* + * Read config when the Git directory has not yet been set up. In case + * `the_repository` has not yet been set up, try to discover the Git + * directory to read the configuration from. + */ +void read_early_config(struct repository *repo, config_fn_t cb, void *data); + +/* + * Read config but only enumerate system and global settings. + * Omit any repo-local, worktree-local, or command-line settings. + */ void read_very_early_config(config_fn_t cb, void *data); /** diff --git a/config.mak.dev b/config.mak.dev index 50026d1e0e..8eca7fa228 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -69,7 +69,7 @@ DEVELOPER_CFLAGS += -Wno-missing-braces endif endif -# Old versions of clang complain about initializaing a +# Old versions of clang complain about initializing a # struct-within-a-struct using just "{0}" rather than "{{0}}". This # error is considered a false-positive and not worth fixing, because # new clang versions do not, so just disable it. diff --git a/configure.ac b/configure.ac index d1a96da14e..5923edc44a 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]) @@ -1485,6 +1485,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 87cc4b57a1..3099da84f3 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 @@ no_promisor_pack_found: * 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 832f46b316..49904ca8a9 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,87 @@ 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}/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) + 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}/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") @@ -970,18 +992,15 @@ if(BUILD_TESTING) add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c) target_link_libraries(test-fake-ssh common-main) -#reftable-tests -parse_makefile_for_sources(test-reftable_SOURCES "REFTABLE_TEST_OBJS") -list(TRANSFORM test-reftable_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/") - #unit-tests -add_library(unit-test-lib OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/test-lib.c) -add_library(unit-test-lib-oid OBJECT ${CMAKE_SOURCE_DIR}/t/unit-tests/lib-oid.c) +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_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 unit-test-lib-oid common-main) + target_link_libraries("${unit_test}" unit-test-lib common-main) set_target_properties("${unit_test}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) if(MSVC) @@ -1004,12 +1023,47 @@ foreach(unit_test ${unit_test_PROGRAMS}) endif() endforeach() +parse_makefile_for_scripts(clar_test_SUITES "CLAR_TEST_SUITES" "") +list(TRANSFORM clar_test_SUITES PREPEND "${CMAKE_SOURCE_DIR}/t/unit-tests/") +list(TRANSFORM clar_test_SUITES APPEND ".c") +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_SOURCE_DIR}/t/unit-tests/clar/clar.c" + "${CMAKE_BINARY_DIR}/t/unit-tests/clar-decls.h" + "${CMAKE_BINARY_DIR}/t/unit-tests/clar.suite" +) +target_include_directories(unit-tests-lib PUBLIC "${CMAKE_BINARY_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) +set_target_properties(unit-tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/unit-tests/bin) +if(MSVC) + set_target_properties(unit-tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/unit-tests/bin) + set_target_properties(unit-tests + PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/unit-tests/bin) +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/") -add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES} ${test-reftable_SOURCES}) +add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES}) target_link_libraries(test-tool test-lib common-main) set_target_properties(test-fake-ssh test-tool @@ -1031,22 +1085,25 @@ set(wrapper_test_scripts 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 "@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 "@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 "@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 @@ -1059,6 +1116,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 ) @@ -1072,6 +1130,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() @@ -1088,26 +1150,58 @@ 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 "@SHELL_PATH@" "'${SHELL_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@TEST_SHELL_PATH@" "'${TEST_SHELL_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@PERL_PATH@" "'${PERL_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@PERL_LOCALEDIR@" "'${LOCALEDIR}'" git_build_options "${git_build_options}") +string(REPLACE "@NO_PERL_CPAN_FALLBACKS@" "" git_build_options "${git_build_options}") +string(REPLACE "@DIFF@" "'${DIFF}'" git_build_options "${git_build_options}") +string(REPLACE "@PYTHON_PATH@" "'${PYTHON_PATH}'" git_build_options "${git_build_options}") +string(REPLACE "@TAR@" "'${TAR}'" git_build_options "${git_build_options}") +string(REPLACE "@NO_CURL@" "${NO_CURL}" git_build_options "${git_build_options}") +string(REPLACE "@NO_ICONV@" "${NO_ICONV}" git_build_options "${git_build_options}") +string(REPLACE "@NO_EXPAT@" "${NO_EXPAT}" git_build_options "${git_build_options}") +string(REPLACE "@USE_LIBPCRE2@" "" git_build_options "${git_build_options}") +string(REPLACE "@NO_PERL@" "${NO_PERL}" 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 "@SANITIZE_LEAK@" "" git_build_options "${git_build_options}") +string(REPLACE "@SANITIZE_ADDRESS@" "" git_build_options "${git_build_options}") +string(REPLACE "@X@" "${EXE_EXTENSION}" 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 "@TEST_OUTPUT_DIRECTORY@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_OPTS@" "" 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_UTF8_LOCALE@" "" git_build_options "${git_build_options}") +string(REPLACE "@NO_GETTEXT@" "${NO_GETTEXT}" 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_PERF_LARGE_REPO@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_MAKE_OPTS@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_PERF_MAKE_COMMAND@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_INTEROP_MAKE_OPTS@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_INDEX_VERSION@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_PERL_FATAL_WARNINGS@" "" 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_POPATH@" "'${CMAKE_BINARY_DIR}/po'" 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_GITPERLLIB@" "'${CMAKE_BINARY_DIR}/perl/build/lib'" git_build_options "${git_build_options}") +string(REPLACE "@GIT_TEST_MERGE_TOOLS_DIR@" "'${RUNTIME_PREFIX}'" git_build_options "${git_build_options}") +string(REPLACE "@RUNTIME_PREFIX@" "'${RUNTIME_PREFIX}'" git_build_options "${git_build_options}") +string(REPLACE "@GITWEBDIR@" "'${GITWEBDIR}'" git_build_options "${git_build_options}") +string(REPLACE "@USE_GETTEXT_SCHEME@" "" git_build_options "${git_build_options}") +string(REPLACE "@LOCALEDIR@" "'${LOCALEDIR}'" git_build_options "${git_build_options}") +string(REPLACE "@BROKEN_PATH_FIX@" "" 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 0000000000..9750505ae7 --- /dev/null +++ b/contrib/buildsystems/git-version.in @@ -0,0 +1 @@ +@GIT_MAJOR_VERSION@.@GIT_MINOR_VERSION@.@GIT_MICRO_VERSION@ diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 60a22d619a..b3b6aa3bae 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 @@ -3296,7 +3296,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 +3698,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 0000000000..3a9ddab594 --- /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/diff-highlight/DiffHighlight.pm b/contrib/diff-highlight/DiffHighlight.pm index 636add6968..3d061bc0b7 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/git-jump/git-jump b/contrib/git-jump/git-jump index 47e0c557e6..3f69675961 100755 --- a/contrib/git-jump/git-jump +++ b/contrib/git-jump/git-jump @@ -44,13 +44,13 @@ open_editor() { mode_diff() { git diff --no-prefix --relative "$@" | perl -ne ' - if (m{^\+\+\+ (.*)}) { $file = $1; next } + if (m{^\+\+\+ (.*)}) { $file = $1 eq "/dev/null" ? undef : $1; next } defined($file) or next; if (m/^@@ .*?\+(\d+)/) { $line = $1; next } defined($line) or next; if (/^ /) { $line++; next } if (/^[-+]\s*(.*)/) { - print "$file:$line: $1\n"; + print "$file:$line:1: $1\n"; $line = undef; } ' diff --git a/contrib/meson.build b/contrib/meson.build new file mode 100644 index 0000000000..a7b77b87c2 --- /dev/null +++ b/contrib/meson.build @@ -0,0 +1 @@ +subdir('completion') diff --git a/contrib/mw-to-git/Git/Mediawiki.pm b/contrib/mw-to-git/Git/Mediawiki.pm index ff7811225e..629c0cea44 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/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh index 5dab3f506c..15ae86db1b 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/t/t7900-subtree.sh b/contrib/subtree/t/t7900-subtree.sh index c3bd2a58b9..3c6103f6d2 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/credential.c b/credential.c index ee46351ce0..6dea3859ec 100644 --- a/credential.c +++ b/credential.c @@ -13,6 +13,8 @@ #include "strbuf.h" #include "urlmatch.h" #include "git-compat-util.h" +#include "trace2.h" +#include "repository.h" void credential_init(struct credential *c) { @@ -251,14 +253,36 @@ static char *credential_ask_one(const char *what, struct credential *c, return xstrdup(r); } -static void credential_getpass(struct credential *c) +static int credential_getpass(struct credential *c) { + int interactive; + char *value; + if (!git_config_get_maybe_bool("credential.interactive", &interactive) && + !interactive) { + trace2_data_intmax("credential", the_repository, + "interactive/skipped", 1); + return -1; + } + if (!git_config_get_string("credential.interactive", &value)) { + int same = !strcmp(value, "never"); + free(value); + if (same) { + trace2_data_intmax("credential", the_repository, + "interactive/skipped", 1); + return -1; + } + } + + trace2_region_enter("credential", "interactive", the_repository); 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); + + return 0; } int credential_has_capability(const struct credential_capability *capa, @@ -501,8 +525,8 @@ void credential_fill(struct credential *c, int all_capabilities) c->helpers.items[i].string); } - credential_getpass(c); - if (!c->username && !c->password && !c->credential) + if (credential_getpass(c) || + (!c->username && !c->password && !c->credential)) die("unable to get password from user"); } diff --git a/csum-file.c b/csum-file.c index bf82ad8f9f..c203ebf11b 100644 --- a/csum-file.c +++ b/csum-file.c @@ -50,7 +50,7 @@ void hashflush(struct hashfile *f) if (offset) { if (!f->skip_hash) - the_hash_algo->update_fn(&f->ctx, f->buffer, offset); + the_hash_algo->unsafe_update_fn(&f->ctx, f->buffer, offset); flush(f, f->buffer, offset); f->offset = 0; } @@ -73,7 +73,7 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result, if (f->skip_hash) hashclr(f->buffer, the_repository->hash_algo); else - the_hash_algo->final_fn(f->buffer, &f->ctx); + the_hash_algo->unsafe_final_fn(f->buffer, &f->ctx); if (result) hashcpy(result, f->buffer, the_repository->hash_algo); @@ -128,7 +128,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); + the_hash_algo->unsafe_update_fn(&f->ctx, buf, nr); flush(f, buf, nr); } else { /* @@ -174,7 +174,7 @@ 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); + the_hash_algo->unsafe_init_fn(&f->ctx); f->buffer_len = buffer_len; f->buffer = xmalloc(buffer_len); @@ -208,7 +208,7 @@ void hashfile_checkpoint(struct hashfile *f, struct hashfile_checkpoint *checkpo { hashflush(f); checkpoint->offset = f->total; - the_hash_algo->clone_fn(&checkpoint->ctx, &f->ctx); + the_hash_algo->unsafe_clone_fn(&checkpoint->ctx, &f->ctx); } int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint) @@ -219,7 +219,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); + the_hash_algo->unsafe_clone_fn(&f->ctx, &checkpoint->ctx); f->offset = 0; /* hashflush() was called in checkpoint */ return 0; } @@ -245,9 +245,9 @@ int hashfile_checksum_valid(const unsigned char *data, size_t total_len) if (total_len < the_hash_algo->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); + the_hash_algo->unsafe_init_fn(&ctx); + the_hash_algo->unsafe_update_fn(&ctx, data, data_len); + the_hash_algo->unsafe_final_fn(got, &ctx); return hasheq(got, data + data_len, the_repository->hash_algo); } @@ -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) { @@ -1308,17 +1311,20 @@ 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 (strtol_i(v, 10, &max_connections)) + die(_("invalid max-connections '%s', expecting an integer"), v); if (max_connections < 0) - max_connections = 0; /* unlimited */ + max_connections = 0; /* unlimited */ continue; } if (!strcmp(arg, "--strict-paths")) { diff --git a/diff-lib.c b/diff-lib.c index a680768ee7..3cf353946f 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -661,6 +661,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 +702,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 +717,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 3a8965672c..c5fb06e6d1 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -362,7 +362,7 @@ int diff_no_index(struct rev_info *revs, * The return code for --no-index imitates diff(1): * 0 = no changes, 1 = changes, else error */ - ret = diff_result_code(&revs->diffopt); + ret = diff_result_code(revs); out: for (i = 0; i < ARRAY_SIZE(to_free); i++) @@ -12,6 +12,7 @@ #include "environment.h" #include "gettext.h" #include "tempfile.h" +#include "revision.h" #include "quote.h" #include "diff.h" #include "diffcore.h" @@ -29,6 +30,7 @@ #include "merge-ll.h" #include "string-list.h" #include "strvec.h" +#include "tmp-objdir.h" #include "graph.h" #include "oid-array.h" #include "packfile.h" @@ -441,8 +443,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) @@ -2313,12 +2317,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) @@ -3673,6 +3674,7 @@ static void builtin_diff(const char *name_a, emit_diff_symbol(o, DIFF_SYMBOL_BINARY_FILES, sb.buf, sb.len, 0); strbuf_release(&sb); + o->found_changes = 1; goto free_ab_and_return; } if (fill_mmfile(o->repo, &mf1, one) < 0 || @@ -4039,7 +4041,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; /* @@ -4775,7 +4778,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; @@ -5395,7 +5398,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; } @@ -5978,11 +5980,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) @@ -6546,8 +6555,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; } @@ -6727,6 +6735,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); @@ -6829,8 +6838,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); /* @@ -6861,9 +6869,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; @@ -6956,8 +6962,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]; @@ -7088,10 +7093,16 @@ void diffcore_std(struct diff_options *options) options->found_follow = 0; } -int diff_result_code(struct diff_options *opt) +int diff_result_code(struct rev_info *revs) { + struct diff_options *opt = &revs->diffopt; int result = 0; + if (revs->remerge_diff) { + tmp_objdir_destroy(revs->remerge_objdir); + revs->remerge_objdir = NULL; + } + diff_warn_rename_limit("diff.renameLimit", opt->needed_rename_limit, opt->degraded_cc_to_c); @@ -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 @@ -235,7 +235,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 +274,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 @@ -648,7 +647,7 @@ 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); -int diff_result_code(struct diff_options *); +int diff_result_code(struct rev_info *); int diff_no_index(struct rev_info *, int implicit_no_index, int, const char **); diff --git a/diffcore-break.c b/diffcore-break.c index 831b66b5c3..c4c2173f30 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 e7d20ebd2d..912513d3e6 100644 --- a/diffcore-order.c +++ b/diffcore-order.c @@ -14,8 +14,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 +23,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 +38,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 +50,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 b195fa4eb3..43fef8e8ba 100644 --- a/diffcore-pickaxe.c +++ b/diffcore-pickaxe.c @@ -182,9 +182,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 fab45b10d7..1b1c1a6a1f 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -933,7 +933,7 @@ static int find_basename_matches(struct diff_options *options, * spend more cycles to find similarities between files, so it may * be less likely that this heuristic is wanted. If someone is * doing break detection, that means they do not want filename - * similarity to imply any form of content similiarity, and thus + * similarity to imply any form of content similarity, and thus * this heuristic would definitely be incompatible. */ @@ -1388,7 +1388,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; @@ -1534,7 +1534,7 @@ void diffcore_rename_extended(struct diff_options *options, * - remove ones not found in relevant_sources * and * - remove ones in relevant_sources which are needed only - * for directory renames IF no ancestory directory + * for directory renames IF no ancestry directory * actually needs to know any more individual path * renames under them */ @@ -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 533986cf63..73ca20b331 100644 --- a/diffcore-rotate.c +++ b/diffcore-rotate.c @@ -10,7 +10,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 +31,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 1701ed50b9..2feb325031 100644 --- a/diffcore.h +++ b/diffcore.h @@ -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 { @@ -20,6 +20,7 @@ #include "object-store-ll.h" #include "path.h" #include "refs.h" +#include "repository.h" #include "wildmatch.h" #include "pathspec.h" #include "utf8.h" @@ -1055,6 +1056,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]); @@ -1082,6 +1085,8 @@ 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; @@ -2135,8 +2140,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; } @@ -2148,8 +2152,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; } @@ -2838,7 +2841,7 @@ static const char *get_ident_string(void) return sb.buf; if (uname(&uts) < 0) die_errno(_("failed to get kernel name and information")); - strbuf_addf(&sb, "Location %s, system %s", get_git_work_tree(), + strbuf_addf(&sb, "Location %s, system %s", repo_get_work_tree(the_repository), uts.sysname); return sb.buf; } @@ -2869,14 +2872,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; @@ -3574,6 +3577,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; } @@ -3906,6 +3911,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/environment.c b/environment.c index 1d6c48b52d..8389a27270 100644 --- a/environment.c +++ b/environment.c @@ -22,15 +22,9 @@ #include "fmt-merge-msg.h" #include "commit.h" #include "strvec.h" -#include "object-file.h" -#include "object-store-ll.h" #include "path.h" -#include "replace-object.h" -#include "tmp-objdir.h" #include "chdir-notify.h" #include "setup.h" -#include "shallow.h" -#include "trace.h" #include "write-or-die.h" int trust_executable_bit = 1; @@ -40,9 +34,7 @@ int has_symlinks = 1; int minimum_abbrev = 4, default_abbrev = -1; int ignore_case; int assume_unchanged; -int prefer_symlink_refs; int is_bare_repository_cfg = -1; /* unspecified */ -int warn_ambiguous_refs = 1; int warn_on_object_refname_ambiguity = 1; int repository_format_precious_objects; char *git_commit_encoding; @@ -57,9 +49,6 @@ 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; @@ -75,7 +64,6 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; #define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS #endif enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE; -char *notes_ref_name; int grafts_keep_true_parents; int core_apply_sparse_checkout; int core_sparse_checkout_cone; @@ -83,7 +71,6 @@ int sparse_expect_files_outside_of_patterns; int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; -enum log_refs_config log_all_ref_updates = LOG_REFS_UNSET; int max_allowed_tree_depth = #ifdef _MSC_VER /* @@ -123,8 +110,6 @@ int core_preload_index = 1; /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; -static char *git_namespace; - /* * Repository-local GIT_* environment variables; see environment.h for details. */ @@ -147,27 +132,6 @@ const char * const local_repo_env[] = { NULL }; -static char *expand_namespace(const char *raw_namespace) -{ - struct strbuf buf = STRBUF_INIT; - struct strbuf **components, **c; - - if (!raw_namespace || !*raw_namespace) - return xstrdup(""); - - strbuf_addstr(&buf, raw_namespace); - components = strbuf_split(&buf, '/'); - strbuf_reset(&buf); - for (c = components; *c; c++) - if (strcmp((*c)->buf, "/") != 0) - strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf); - strbuf_list_free(components); - if (check_refname_format(buf.buf, 0)) - die(_("bad git namespace path \"%s\""), raw_namespace); - strbuf_addch(&buf, '/'); - return strbuf_detach(&buf, NULL); -} - const char *getenv_safe(struct strvec *argv, const char *name) { const char *value = getenv(name); @@ -179,47 +143,10 @@ const char *getenv_safe(struct strvec *argv, const char *name) return argv->v[argv->nr - 1]; } -void setup_git_env(const char *git_dir) -{ - char *git_replace_ref_base; - const char *shallow_file; - const char *replace_ref_base; - struct set_gitdir_args args = { NULL }; - struct strvec to_free = STRVEC_INIT; - - args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT); - args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT); - args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT); - args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); - args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); - if (getenv(GIT_QUARANTINE_ENVIRONMENT)) { - args.disable_ref_updates = 1; - } - - repo_set_gitdir(the_repository, git_dir, &args); - strvec_clear(&to_free); - - if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) - disable_replace_refs(); - replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); - git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base - : "refs/replace/"); - update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base); - - free(git_namespace); - git_namespace = expand_namespace(getenv(GIT_NAMESPACE_ENVIRONMENT)); - shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); - if (shallow_file) - set_alternate_shallow_file(the_repository, shallow_file, 0); - - if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) - fetch_if_missing = 0; -} - int is_bare_repository(void) { /* if core.bare is not 'false', let's see if there is a work tree */ - return is_bare_repository_cfg && !get_git_work_tree(); + return is_bare_repository_cfg && !repo_get_work_tree(the_repository); } int have_git_dir(void) @@ -228,156 +155,45 @@ int have_git_dir(void) || the_repository->gitdir; } -const char *get_git_dir(void) -{ - if (!the_repository->gitdir) - BUG("git environment hasn't been setup"); - return the_repository->gitdir; -} - -const char *get_git_common_dir(void) -{ - if (!the_repository->commondir) - BUG("git environment hasn't been setup"); - return the_repository->commondir; -} - const char *get_git_namespace(void) { - if (!git_namespace) - BUG("git environment hasn't been setup"); - return git_namespace; -} + static const char *namespace; -const char *strip_namespace(const char *namespaced_ref) -{ - const char *out; - if (skip_prefix(namespaced_ref, get_git_namespace(), &out)) - return out; - return NULL; -} - -static int git_work_tree_initialized; + struct strbuf buf = STRBUF_INIT; + struct strbuf **components, **c; + const char *raw_namespace; -/* - * Note. This works only before you used a work tree. This was added - * primarily to support git-clone to work in a new repository it just - * created, and is not meant to flip between different work trees. - */ -void set_git_work_tree(const char *new_work_tree) -{ - if (git_work_tree_initialized) { - struct strbuf realpath = STRBUF_INIT; + if (namespace) + return namespace; - strbuf_realpath(&realpath, new_work_tree, 1); - new_work_tree = realpath.buf; - if (strcmp(new_work_tree, the_repository->worktree)) - die("internal error: work tree has already been set\n" - "Current worktree: %s\nNew worktree: %s", - the_repository->worktree, new_work_tree); - strbuf_release(&realpath); - return; + raw_namespace = getenv(GIT_NAMESPACE_ENVIRONMENT); + if (!raw_namespace || !*raw_namespace) { + namespace = ""; + return namespace; } - git_work_tree_initialized = 1; - repo_set_worktree(the_repository, new_work_tree); -} - -const char *get_git_work_tree(void) -{ - return the_repository->worktree; -} - -const char *get_object_directory(void) -{ - if (!the_repository->objects->odb) - BUG("git environment hasn't been setup"); - return the_repository->objects->odb->path; -} - -int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) -{ - int fd; - /* - * we let the umask do its job, don't try to be more - * restrictive except to remove write permission. - */ - int mode = 0444; - git_path_buf(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); - safe_create_leading_directories(temp_filename->buf); - return xmkstemp_mode(temp_filename->buf, mode); -} - -int odb_pack_keep(const char *name) -{ - int fd; - - fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); - if (0 <= fd) - return fd; - - /* slow path */ - safe_create_leading_directories_const(name); - return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); -} - -char *get_index_file(void) -{ - if (!the_repository->index_file) - BUG("git environment hasn't been setup"); - return the_repository->index_file; -} - -char *get_graft_file(struct repository *r) -{ - if (!r->graft_file) - BUG("git environment hasn't been setup"); - return r->graft_file; -} -static void set_git_dir_1(const char *path) -{ - xsetenv(GIT_DIR_ENVIRONMENT, path, 1); - setup_git_env(path); -} + strbuf_addstr(&buf, raw_namespace); + components = strbuf_split(&buf, '/'); + strbuf_reset(&buf); + for (c = components; *c; c++) + if (strcmp((*c)->buf, "/") != 0) + strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf); + strbuf_list_free(components); + if (check_refname_format(buf.buf, 0)) + die(_("bad git namespace path \"%s\""), raw_namespace); + strbuf_addch(&buf, '/'); -static void update_relative_gitdir(const char *name UNUSED, - const char *old_cwd, - const char *new_cwd, - void *data UNUSED) -{ - char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir()); - struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb(); + namespace = strbuf_detach(&buf, NULL); - trace_printf_key(&trace_setup_key, - "setup: move $GIT_DIR to '%s'", - path); - set_git_dir_1(path); - if (tmp_objdir) - tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd); - free(path); + return namespace; } -void set_git_dir(const char *path, int make_realpath) +const char *strip_namespace(const char *namespaced_ref) { - struct strbuf realpath = STRBUF_INIT; - - if (make_realpath) { - strbuf_realpath(&realpath, path, 1); - path = realpath.buf; - } - - set_git_dir_1(path); - if (!is_absolute_path(path)) - chdir_notify_register(NULL, update_relative_gitdir, NULL); - - strbuf_release(&realpath); + const char *out; + if (skip_prefix(namespaced_ref, get_git_namespace(), &out)) + return out; + return NULL; } const char *get_log_output_encoding(void) diff --git a/environment.h b/environment.h index 0148738ed6..2f43340f0b 100644 --- a/environment.h +++ b/environment.h @@ -1,22 +1,7 @@ #ifndef ENVIRONMENT_H #define ENVIRONMENT_H -struct repository; -struct strvec; - -/* - * The character that begins a commented line in user-editable file - * that is subject to stripspace. - */ -extern const char *comment_line_str; -extern char *comment_line_str_to_free; -extern int auto_comment_line_char; - -/* - * Wrapper of getenv() that returns a strdup value. This value is kept - * in argv to be freed later. - */ -const char *getenv_safe(struct strvec *argv, const char *name); +#include "repo-settings.h" /* Double-check local_repo_env below if you add to this list. */ #define GIT_DIR_ENVIRONMENT "GIT_DIR" @@ -87,6 +72,8 @@ const char *getenv_safe(struct strvec *argv, const char *name); */ #define GIT_IMPLICIT_WORK_TREE_ENVIRONMENT "GIT_IMPLICIT_WORK_TREE" +#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" + /* * Repository-local GIT_* environment variables; these will be cleared * when git spawns a sub-process that runs inside another repository. @@ -95,6 +82,50 @@ const char *getenv_safe(struct strvec *argv, const char *name); */ extern const char * const local_repo_env[]; +struct strvec; + +/* + * Wrapper of getenv() that returns a strdup value. This value is kept + * in argv to be freed later. + */ +const char *getenv_safe(struct strvec *argv, const char *name); + +/* + * Should we print an ellipsis after an abbreviated SHA-1 value + * when doing diff-raw output or indicating a detached HEAD? + */ +int print_sha1_ellipsis(void); + +/* + * Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). + */ +int use_optional_locks(void); + +const char *get_git_namespace(void); +const char *strip_namespace(const char *namespaced_ref); + +/* + * TODO: All the below state either explicitly or implicitly relies on + * `the_repository`. We should eventually get rid of these and make the + * dependency on a repository explicit: + * + * - `setup_git_env()` ideally shouldn't exist as it modifies global state, + * namely the environment. The current process shouldn't ever access that + * state via envvars though, but should instead consult a `struct + * repository`. When spawning new processes, we would ideally also pass a + * `struct repository` and then set up the environment variables for the + * child process, only. + * + * - `have_git_dir()` should not have to exist at all. Instead, we should + * decide on whether or not we have a `struct repository`. + * + * - All the global config variables should become tied to a repository. Like + * this, we'd correctly honor repository-local configuration and be able to + * distinguish configuration values from different repositories. + * + * Please do not add new global config variables here. + */ +# ifdef USE_THE_REPOSITORY_VARIABLE void setup_git_env(const char *git_dir); /* @@ -103,21 +134,19 @@ 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; -const char *get_git_dir(void); -const char *get_git_common_dir(void); -const char *get_object_directory(void); -char *get_index_file(void); -char *get_graft_file(struct repository *r); -void set_git_dir(const char *path, int make_realpath); -const char *get_git_namespace(void); -const char *strip_namespace(const char *namespaced_ref); -const char *get_git_work_tree(void); -void set_git_work_tree(const char *tree); - -#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" /* Environment bits from configuration mechanism */ extern int trust_executable_bit; @@ -127,8 +156,6 @@ extern int has_symlinks; extern int minimum_abbrev, default_abbrev; extern int ignore_case; extern int assume_unchanged; -extern int prefer_symlink_refs; -extern int warn_ambiguous_refs; extern int warn_on_object_refname_ambiguity; extern char *apply_default_whitespace; extern char *apply_default_ignorewhitespace; @@ -138,21 +165,10 @@ 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; -/* - * 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 core_preload_index; extern int precomposed_unicode; extern int protect_hfs; @@ -162,25 +178,13 @@ extern int core_apply_sparse_checkout; extern int core_sparse_checkout_cone; extern int sparse_expect_files_outside_of_patterns; -/* - * Returns the boolean value of $GIT_OPTIONAL_LOCKS (or the default value). - */ -int use_optional_locks(void); - -enum log_refs_config { - LOG_REFS_UNSET = -1, - LOG_REFS_NONE = 0, - LOG_REFS_NORMAL, - LOG_REFS_ALWAYS -}; -extern enum log_refs_config log_all_ref_updates; - enum rebase_setup_type { AUTOREBASE_NEVER = 0, AUTOREBASE_LOCAL, AUTOREBASE_REMOTE, AUTOREBASE_ALWAYS }; +extern enum rebase_setup_type autorebase; enum push_default_type { PUSH_DEFAULT_NOTHING = 0, @@ -190,38 +194,18 @@ enum push_default_type { PUSH_DEFAULT_CURRENT, PUSH_DEFAULT_UNSPECIFIED }; - -extern enum rebase_setup_type autorebase; extern enum push_default_type push_default; enum object_creation_mode { OBJECT_CREATION_USES_HARDLINKS = 0, OBJECT_CREATION_USES_RENAMES = 1 }; - extern enum object_creation_mode object_creation_mode; -extern char *notes_ref_name; - extern int grafts_keep_true_parents; extern int repository_format_precious_objects; -/* - * Create a temporary file rooted in the object database directory, or - * die on failure. The filename is taken from "pattern", which should have the - * usual "XXXXXX" trailer, and the resulting filename is written into the - * "template" buffer. Returns the open descriptor. - */ -int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); - -/* - * Create a pack .keep file named "name" (which should generally be the output - * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on - * error. - */ -int odb_pack_keep(const char *name); - const char *get_log_output_encoding(void); const char *get_commit_output_encoding(void); @@ -233,9 +217,12 @@ extern char *askpass_program; extern char *excludes_file; /* - * Should we print an ellipsis after an abbreviated SHA-1 value - * when doing diff-raw output or indicating a detached HEAD? + * The character that begins a commented line in user-editable file + * that is subject to stripspace. */ -int print_sha1_ellipsis(void); +extern const char *comment_line_str; +extern char *comment_line_str_to_free; +extern int auto_comment_line_char; -#endif +# endif /* USE_THE_REPOSITORY_VARIABLE */ +#endif /* ENVIRONMENT_H */ diff --git a/fetch-pack.c b/fetch-pack.c index 983c560785..c095f3a84b 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -122,29 +122,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 +164,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 +174,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) { @@ -1839,7 +1841,7 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args, string_list_append_nodup(pack_lockfiles, xstrfmt("%s/pack/pack-%s.keep", - get_object_directory(), + repo_get_object_directory(the_repository), packname)); } string_list_clear(&packfile_uris, 0); @@ -1855,8 +1857,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 +1866,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 0; + strbuf_addf(msg_types, "%cskiplist=%s", + msg_types->len ? ',' : '=', path); free(path); return 0; } @@ -1875,14 +1877,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) @@ -2227,7 +2239,10 @@ void negotiate_using_fetch(const struct oid_array *negotiation_tips, trace2_region_leave("fetch-pack", "negotiate_using_fetch", the_repository); trace2_data_intmax("negotiate_using_fetch", the_repository, "total_rounds", negotiation_round); + clear_common_flag(acked_commits); + object_array_clear(&nt_object_array); + negotiator.release(&negotiator); strbuf_release(&req_buf); } diff --git a/fetch-pack.h b/fetch-pack.h index b5c579cdae..9d3470366f 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 @@ -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, @@ -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-settings.c b/fsmonitor-settings.c index e818583420..a6587a8972 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -7,7 +7,7 @@ #include "fsmonitor-path-utils.h" /* - * We keep this structure defintion private and have getters + * We keep this structure definition private and have getters * for all fields so that we can lazy load it as needed. */ struct fsmonitor_settings { diff --git a/fsmonitor.c b/fsmonitor.c index 28130f748f..309a2541cb 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -8,6 +8,7 @@ #include "fsmonitor.h" #include "fsmonitor-ipc.h" #include "name-hash.h" +#include "repository.h" #include "run-command.h" #include "strbuf.h" #include "trace2.h" @@ -169,7 +170,7 @@ static int query_fsmonitor_hook(struct repository *r, strvec_pushf(&cp.args, "%d", version); strvec_pushf(&cp.args, "%s", last_update); cp.use_shell = 1; - cp.dir = get_git_work_tree(); + cp.dir = repo_get_work_tree(the_repository); trace2_region_enter("fsm_hook", "query", NULL); @@ -246,7 +247,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 205541e0f7..b923a5aab8 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.txt" 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 8692fe5cf4..579422619c 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.txt "$SOURCE_DIR"/Documentation/config/*.txt | 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 2f9f54eb54..e22068c2fa 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.txt | LC_ALL=C sort cat <<EOF NULL, }; EOF + +} >"$OUTPUT" diff --git a/generate-perl.sh b/generate-perl.sh new file mode 100755 index 0000000000..65f122ebfc --- /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 0000000000..31ac115689 --- /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 0000000000..a149e4f0ba --- /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/git-archimport.perl b/git-archimport.perl index f5a317b899..6d0169cb6a 100755 --- a/git-archimport.perl +++ b/git-archimport.perl @@ -54,7 +54,7 @@ and can contain multiple, unrelated branches. =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 e4a306dd56..a06d4f3809 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1527,26 +1527,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> diff --git a/git-curl-compat.h b/git-curl-compat.h index e1d0bdd273..703756ba85 100644 --- a/git-curl-compat.h +++ b/git-curl-compat.h @@ -29,104 +29,6 @@ */ /** - * 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 * automatically. diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl index 1e03ba94d1..edf02f9964 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 211ec8459a..e10ad5334e 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 124f598bdc..a4e1bad33c 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::Path qw/rmtree/; 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 dd0c9a5b7f..d32e47cc09 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/lib/commit.tcl b/git-gui/lib/commit.tcl index 11379f8ad3..208dc2817c 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/mergetool.tcl b/git-gui/lib/mergetool.tcl index e688b016ef..8b8c16b1d6 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-instaweb.sh b/git-instaweb.sh index 994431c887..5ad50160bb 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 @@ -612,7 +612,7 @@ python_conf() { ln -sf "$root/static" "$fqgitdir/gitweb/$httpd_only/" # generate a standalone 'python http.server' script in $fqgitdir/gitweb - # This asumes that python is in user's $PATH + # This assumes that python is in user's $PATH # This script is Python 2 and 3 compatible cat > "$fqgitdir/gitweb/gitweb.py" <<EOF #!/usr/bin/env python @@ -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 1ff26170ff..11ea181259 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 @@ -54,7 +54,7 @@ import time import zipfile import zlib -# On python2.7 where raw_input() and input() are both availble, +# On python2.7 where raw_input() and input() are both available, # we want raw_input's semantics, but aliased to input for python3 # compatibility # support basestring in python3 @@ -1804,7 +1804,7 @@ class P4Submit(Command, P4UserMap): status from the script will abort the process. The purpose of the hook is to edit the message file in place, and it is not - supressed by the `--no-verify` option. This hook is called even if + suppressed by the `--no-verify` option. This hook is called even if `--prepare-p4-only` is set. The `p4-changelist` hook is executed after the changelist message has been diff --git a/git-request-pull.sh b/git-request-pull.sh index 01640a044b..775ba8ea11 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 c835d4c11a..798d59b84f 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 a15c0620db..ae4b2d6ba9 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 ce273fe0e4..19aef72ec2 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-svn.perl b/git-svn.perl index 01e7a70de1..32c648c395 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 @@ use vars qw/ $AUTHOR $VERSION $_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/; @@ -31,7 +31,7 @@ struct cmd_struct { const char *cmd; - int (*fn)(int, const char **, const char *); + int (*fn)(int, const char **, const char *, struct repository *); unsigned int option; }; @@ -362,7 +362,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 +370,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 +390,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 +423,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; } @@ -441,9 +439,10 @@ static int handle_alias(int *argcp, const char ***argv) return ret; } -static int run_builtin(struct cmd_struct *p, int argc, 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 +454,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) 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; } @@ -479,9 +478,9 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) trace_argv_printf(argv, "trace: built-in: git"); trace2_cmd_name(p->cmd); - validate_cache_entries(the_repository->index); - status = p->fn(argc, argv, prefix); - validate_cache_entries(the_repository->index); + validate_cache_entries(repo->index); + status = p->fn(argc, argv, prefix, no_repo ? NULL : repo); + validate_cache_entries(repo->index); if (status) return status; @@ -697,47 +696,57 @@ void load_builtin_commands(const char *prefix, struct cmdnames *cmds) } #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)); - strvec_clear(&args); } static void execv_dashed_external(const char **argv) @@ -783,10 +792,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,8 +809,8 @@ 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; @@ -817,8 +826,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 (i = 0; i < args->nr; i++) + strvec_push(&cmd.args, args->v[i]); trace_argv_printf(cmd.args.v, "trace: exec:"); @@ -833,13 +842,13 @@ static int run_argv(int *argcp, const char ***argv) i = run_command(&cmd); if (i >= 0 || errno != ENOENT) exit(i); - die("could not execute builtin %s", **argv); + 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; @@ -856,14 +865,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 +884,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 +910,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 +946,34 @@ int cmd_main(int argc, const char **argv) */ setup_path(); + for (size_t 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; } @@ -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/gitk b/gitk-git/gitk index 7a087f123d..47a7c1d29c 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -1969,6 +1969,10 @@ proc confirm_popup {msg {owner .}} { return $confirm_ok } +proc haveselectionclipboard {} { + return [expr {[tk windowingsystem] eq "x11"}] +} + proc setoptions {} { global use_ttk @@ -2089,7 +2093,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 @@ -2223,7 +2227,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 +2435,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 @@ -7344,7 +7348,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 +7414,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 @@ -8756,7 +8764,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 +8783,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 +8800,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] } @@ -11576,12 +11584,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 +11603,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 +11663,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 +11682,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 +11740,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 +11753,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 +11762,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 +11888,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 +11902,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 +11952,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} { @@ -12392,6 +12427,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 +12436,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 +12534,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 @@ -12687,7 +12725,7 @@ catch { 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/po/sv.po b/gitk-git/po/sv.po index 2a06fe5bbc..5afbe6da1d 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 0000000000..41ac20654c --- /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 3b68ab2d67..d5748e9359 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 0000000000..ede9038c33 --- /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 0000000000..01bb22b04b --- /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 b09a8d0523..b5490dfecf 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 @@ our $logo_url = "https://git-scm.com/"; 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 @@ our $default_projects_order = "project"; # 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 @@ our $omit_owner=0; 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 @@ our $prevent_xss = 0; # 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 0000000000..89b403dc9d --- /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 6587085cd1..07335987a6 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -45,8 +45,8 @@ struct gpg_format { size_t signature_size); int (*sign_buffer)(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); - const char *(*get_default_key)(void); - const char *(*get_key_id)(void); + char *(*get_default_key)(void); + char *(*get_key_id)(void); }; static const char *openpgp_verify_args[] = { @@ -86,9 +86,9 @@ static int sign_buffer_gpg(struct strbuf *buffer, struct strbuf *signature, static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); -static const char *get_default_ssh_signing_key(void); +static char *get_default_ssh_signing_key(void); -static const char *get_ssh_key_id(void); +static char *get_ssh_key_id(void); static struct gpg_format gpg_format[] = { { @@ -400,7 +400,7 @@ static void parse_ssh_output(struct signature_check *sigc) * Note that "PRINCIPAL" can contain whitespace, "RSA" and * "SHA256" part could be a different token that names of * the algorithms used, and "FINGERPRINT" is a hexadecimal - * string. By finding the last occurence of " with ", we can + * string. By finding the last occurrence of " with ", we can * reliably parse out the PRINCIPAL. */ sigc->result = 'B'; @@ -847,7 +847,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key) } /* Returns the first public key from an ssh-agent to use for signing */ -static const char *get_default_ssh_signing_key(void) +static char *get_default_ssh_signing_key(void) { struct child_process ssh_default_key = CHILD_PROCESS_INIT; int ret = -1; @@ -899,12 +899,16 @@ static const char *get_default_ssh_signing_key(void) return default_key; } -static const char *get_ssh_key_id(void) { - return get_ssh_key_fingerprint(get_signing_key()); +static char *get_ssh_key_id(void) +{ + char *signing_key = get_signing_key(); + char *key_id = get_ssh_key_fingerprint(signing_key); + free(signing_key); + return key_id; } /* Returns a textual but unique representation of the signing key */ -const char *get_signing_key_id(void) +char *get_signing_key_id(void) { gpg_interface_lazy_init(); @@ -916,17 +920,17 @@ const char *get_signing_key_id(void) return get_signing_key(); } -const char *get_signing_key(void) +char *get_signing_key(void) { gpg_interface_lazy_init(); if (configured_signing_key) - return configured_signing_key; + return xstrdup(configured_signing_key); if (use_format->get_default_key) { return use_format->get_default_key(); } - return git_committer_info(IDENT_STRICT | IDENT_NO_DATE); + return xstrdup(git_committer_info(IDENT_STRICT | IDENT_NO_DATE)); } const char *gpg_trust_level_to_str(enum signature_trust_level level) diff --git a/gpg-interface.h b/gpg-interface.h index 7cd98161f7..e09f12e8d0 100644 --- a/gpg-interface.h +++ b/gpg-interface.h @@ -80,13 +80,13 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *gpg_trust_level_to_str(enum signature_trust_level level); void set_signing_key(const char *); -const char *get_signing_key(void); +char *get_signing_key(void); /* * Returns a textual unique representation of the signing key in use * Either a GPG KeyID or a SSH Key Fingerprint */ -const char *get_signing_key_id(void); +char *get_signing_key_id(void); int check_signature(struct signature_check *sigc, const char *signature, size_t slen); void print_signature_buffer(const struct signature_check *sigc, @@ -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; @@ -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); } @@ -756,6 +756,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 +844,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 +907,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 +955,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 +1466,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 +1662,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)) @@ -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) @@ -178,6 +236,8 @@ enum get_oid_result { /* A suitably aligned type for stack allocations of hash contexts. */ union git_hash_ctx { git_SHA_CTX sha1; + git_SHA_CTX_unsafe sha1_unsafe; + git_SHA256_CTX sha256; }; typedef union git_hash_ctx git_hash_ctx; @@ -222,6 +282,21 @@ struct git_hash_algo { /* The hash finalization function for object IDs. */ git_hash_final_oid_fn final_oid_fn; + /* The non-cryptographic hash initialization function. */ + git_hash_init_fn unsafe_init_fn; + + /* The non-cryptographic hash context cloning function. */ + git_hash_clone_fn unsafe_clone_fn; + + /* The non-cryptographic hash update function. */ + git_hash_update_fn unsafe_update_fn; + + /* The non-cryptographic hash finalization function. */ + git_hash_final_fn unsafe_final_fn; + + /* The non-cryptographic hash finalization function. */ + git_hash_final_oid_fn unsafe_final_oid_fn; + /* The OID of the empty tree. */ const struct object_id *empty_tree; @@ -16,6 +16,7 @@ #include "parse-options.h" #include "prompt.h" #include "fsmonitor-ipc.h" +#include "repository.h" #ifndef NO_CURL #include "git-curl-compat.h" /* For LIBCURL_VERSION only */ @@ -545,8 +546,10 @@ 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_PROMPT (-3) #define AUTOCORRECT_NEVER (-2) @@ -554,28 +557,29 @@ static struct cmdnames aliases; 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; + cfg->autocorrect = AUTOCORRECT_NEVER; } else if (!strcmp(value, "immediate")) { - autocorrect = AUTOCORRECT_IMMEDIATELY; + cfg->autocorrect = AUTOCORRECT_IMMEDIATELY; } else if (!strcmp(value, "prompt")) { - autocorrect = AUTOCORRECT_PROMPT; + cfg->autocorrect = AUTOCORRECT_PROMPT; } else { int v = git_config_int(var, value, ctx->kvi); - autocorrect = (v < 0) + cfg->autocorrect = (v < 0) ? AUTOCORRECT_IMMEDIATELY : 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; } @@ -608,32 +612,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(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); @@ -692,20 +694,19 @@ 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 && 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); @@ -718,9 +719,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; } @@ -775,7 +780,7 @@ void get_version_info(struct strbuf *buf, int show_build_options) } } -int cmd_version(int argc, const char **argv, const char *prefix) +int cmd_version(int argc, const char **argv, const char *prefix, struct repository *repository UNUSED) { struct strbuf buf = STRBUF_INIT; int build_options = 0; @@ -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); @@ -39,7 +39,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 79ce097359..73eec4ea3d 100644 --- a/http-backend.c +++ b/http-backend.c @@ -601,7 +601,7 @@ static void get_head(struct strbuf *hdr, char *arg UNUSED) static void get_info_packs(struct strbuf *hdr, char *arg UNUSED) { - size_t objdirlen = strlen(get_object_directory()); + size_t objdirlen = strlen(repo_get_object_directory(the_repository)); struct strbuf buf = STRBUF_INIT; struct packed_git *p; size_t cnt = 0; diff --git a/http-fetch.c b/http-fetch.c index d460bb1837..02ab80533f 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 7315a694aa..4d24e6b8d4 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; @@ -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); @@ -1370,9 +1375,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 +1407,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 +1417,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 +1527,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 +1719,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 +1984,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 +1996,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 e417a7f51c..43cde0ebe5 100644 --- a/http-walker.c +++ b/http-walker.c @@ -74,7 +74,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 +110,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 +147,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 +422,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 +432,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 +441,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 +478,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 +488,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 +496,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 +544,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 +580,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); @@ -19,6 +19,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 +53,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 +506,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)) { @@ -700,7 +690,6 @@ static int has_cert_password(void) 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) @@ -714,37 +703,12 @@ static int has_proxy_cert_password(void) } 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"); @@ -1707,7 +1653,7 @@ void run_active_slot(struct active_request_slot *slot) * The value of slot->finished we set before the loop was used * to set our "finished" variable when our request completed. * - * 1. The slot may not have been reused for another requst + * 1. The slot may not have been reused for another request * yet, in which case it still has &finished. * * 2. The slot may already be in-use to serve another request, @@ -1850,10 +1796,8 @@ static int handle_curl_result(struct slot_results *results) */ credential_reject(&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) { @@ -2289,17 +2233,19 @@ 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"); } @@ -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", @@ -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,7 +2762,6 @@ 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); if (freq->zret != Z_STREAM_END) { unlink_or_warn(freq->tmpfile.buf); @@ -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; } @@ -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/imap-send.c b/imap-send.c index 2dd42807cd..25c68fd90d 100644 --- a/imap-send.c +++ b/imap-send.c @@ -31,9 +31,6 @@ #include "parse-options.h" #include "setup.h" #include "strbuf.h" -#if defined(NO_OPENSSL) && !defined(HAVE_OPENSSL_CSPRNG) -typedef void *SSL; -#endif #ifdef USE_CURL_FOR_IMAP_SEND #include "http.h" #endif @@ -85,7 +82,11 @@ struct imap_server_conf { struct imap_socket { int fd[2]; +#if defined(NO_OPENSSL) && !defined(HAVE_OPENSSL_CSPRNG) + void *ssl; +#else SSL *ssl; +#endif }; struct imap_buffer { @@ -667,12 +668,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; } @@ -685,8 +686,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; } @@ -772,7 +773,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; @@ -1416,15 +1420,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) diff --git a/line-log.c b/line-log.c index 67c80b39a0..bc67b75d10 100644 --- a/line-log.c +++ b/line-log.c @@ -248,8 +248,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 +573,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 +618,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 +764,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 +783,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 +853,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 +900,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 +909,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 +996,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 +1004,9 @@ out: */ 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 +1088,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 +1123,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 +1199,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 +1212,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 +1230,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 +1237,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 +1249,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 00611107d2..fa72e81e4a 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, diff --git a/list-objects.c b/list-objects.c index 985d008799..d11a389b3a 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) diff --git a/log-tree.c b/log-tree.c index 04cef08b83..83cc4b1cfb 100644 --- a/log-tree.c +++ b/log-tree.c @@ -232,6 +232,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 +248,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 +701,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 +720,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 +948,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 @@ -1015,6 +1036,17 @@ static int do_remerge_diff(struct rev_info *opt, struct strbuf parent1_desc = STRBUF_INIT; struct strbuf parent2_desc = STRBUF_INIT; + /* + * Lazily prepare a temporary object directory and rotate it + * into the alternative object store list as the primary. + */ + if (opt->remerge_diff && !opt->remerge_objdir) { + opt->remerge_objdir = tmp_objdir_create("remerge-diff"); + if (!opt->remerge_objdir) + return error(_("unable to create temporary object directory")); + tmp_objdir_replace_primary_odb(opt->remerge_objdir, 1); + } + /* Setup merge options */ init_ui_merge_options(&o, the_repository); o.show_rename_progress = 0; @@ -1051,10 +1083,7 @@ static int do_remerge_diff(struct rev_info *opt, merge_finalize(&o, &res); /* Clean up the contents of the temporary object directory */ - if (opt->remerge_objdir) - tmp_objdir_discard_objects(opt->remerge_objdir); - else - BUG("did a remerge diff without remerge_objdir?!?"); + tmp_objdir_discard_objects(opt->remerge_objdir); return !opt->loginfo; } diff --git a/log-tree.h b/log-tree.h index 94978e2c83..ebe491c543 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 *); @@ -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" @@ -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) diff --git a/match-trees.c b/match-trees.c index f17c74d483..147b03abf1 100644 --- a/match-trees.c +++ b/match-trees.c @@ -294,18 +294,22 @@ void shift_tree(struct repository *r, unsigned short mode; if (!*del_prefix) - return; + goto out; if (get_tree_entry(r, hash2, del_prefix, shifted, &mode)) die("cannot find path %s in tree %s", del_prefix, oid_to_hex(hash2)); - return; + goto out; } if (!*add_prefix) - return; + goto out; splice_tree(hash1, add_prefix, hash2, shifted); + +out: + free(add_prefix); + free(del_prefix); } /* diff --git a/merge-ll.c b/merge-ll.c index badb6dea57..62fc625552 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -15,6 +15,7 @@ #include "merge-ll.h" #include "quote.h" #include "strbuf.h" +#include "gettext.h" struct ll_merge_driver; @@ -334,7 +335,7 @@ static int read_merge_config(const char *var, const char *value, * %X - the revision for our version * %Y - the revision for their version * - * If the file is not named indentically in all versions, then each + * If the file is not named identically in all versions, then each * revision is joined with the corresponding path, separated by a colon. * The external merge driver should write the results in the * file named by %A, and signal that it has done with zero exit @@ -427,7 +428,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 +458,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 3752c7e595..11029c10be 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -1147,7 +1147,7 @@ static void collect_rename_info(struct merge_options *opt, * Update dir_rename_mask (determines ignore-rename-source validity) * * dir_rename_mask helps us keep track of when directory rename - * detection may be relevant. Basically, whenver a directory is + * detection may be relevant. Basically, whenever a directory is * removed on one side of history, and a file is added to that * directory on the other side of history, directory rename * detection is relevant (meaning we have to detect renames for all @@ -2710,7 +2710,7 @@ static void apply_directory_rename_modifications(struct merge_options *opt, struct conflict_info *dir_ci; char *cur_dir = dirs_to_insert.items[i].string; - CALLOC_ARRAY(dir_ci, 1); + dir_ci = mem_pool_calloc(&opt->priv->pool, 1, sizeof(*dir_ci)); dir_ci->merged.directory_name = parent_name; len = strlen(parent_name); @@ -2838,6 +2838,8 @@ static void apply_directory_rename_modifications(struct merge_options *opt, * Finally, record the new location. */ pair->two->path = new_path; + + string_list_clear(&dirs_to_insert, 0); } /*** Function Grouping: functions related to regular rename detection ***/ @@ -3534,7 +3536,7 @@ simple_cleanup: /* 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]); @@ -3835,7 +3837,7 @@ static int write_completed_directory(struct merge_options *opt, * src/moduleB 2 * * which is used to know that xtract.c & token.txt are from the - * toplevel dirctory, while umm.c & stuff.h & baz.c are from the + * toplevel directory, while umm.c & stuff.h & baz.c are from the * src/moduleB directory. Again, following the example above, * once we need to process src/moduleB, then info->offsets is * updated to diff --git a/mergetools/vimdiff b/mergetools/vimdiff index f8ad6b35d4..ffc9be86c8 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 0000000000..0dccebcdf1 --- /dev/null +++ b/meson.build @@ -0,0 +1,1901 @@ +# 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', + version: 'v2.47.GIT', +) + +fs = import('fs') + +program_path = [] +# Git for Windows provides all the tools we need to build Git. +if host_machine.system() == 'windows' + 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) +shell = find_program('sh', dirs: program_path) +tar = find_program('tar', dirs: program_path) + +script_environment = environment() +foreach tool : ['cat', 'cut', 'grep', 'sed', 'sort', 'tr', 'uname'] + program = find_program(tool, dirs: program_path) + script_environment.prepend('PATH', fs.parent(program.full_path())) +endforeach + +git = find_program('git', dirs: program_path, required: false) +if git.found() + script_environment.prepend('PATH', fs.parent(git.full_path())) +endif + +if get_option('sane_tool_path') != '' + script_environment.prepend('PATH', get_option('sane_tool_path')) +endif + +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', + 'compat/nonblock.c', + 'compat/obstack.c', + 'compat/terminal.c', + 'compat/zlib-uncompress2.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', + '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', + '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', +] + +builtin_sources = [ + 'builtin/add.c', + 'builtin/am.c', + 'builtin/annotate.c', + 'builtin/apply.c', + 'builtin/archive.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/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', +] + +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, +) + +libgit_sources += custom_target( + output: 'config-list.h', + command: [ + shell, + meson.current_source_dir() + '/generate-configlist.sh', + meson.current_source_dir(), + '@OUTPUT@', + ], + env: script_environment, +) + +libgit_sources += custom_target( + input: 'Documentation/githooks.txt', + 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('GIT_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('sane_tool_path') != '' + build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + get_option('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_EXEC_PATH="' + get_option('prefix') / get_option('libexecdir') / 'git-core"', + '-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', + '-Wno-sign-compare', + ] + 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') + libgit_c_args += '-DSUPPRESS_ANNOTATED_LEAKS' + 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') + 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. +perl = find_program('perl', version: '>=5.8.1', dirs: program_path, required: perl_required) +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 = dependency('zlib', default_options: ['default_library=static', 'tests=disabled']) +if zlib.version().version_compare('<1.2.0') + libgit_c_args += '-DNO_DEFLATE_BOUND' +endif +libgit_dependencies += zlib + +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 + + libgit_dependencies += curl + 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/flush.c', + 'compat/win32/path-utils.c', + 'compat/win32/pthread.c', + 'compat/win32/syslog.c', + 'compat/win32/dirent.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 + +https_backend = get_option('https_backend') + +security_framework = dependency('Security', required: https_backend == 'CommonCrypto') +core_foundation_framework = dependency('CoreFoundation', required: security_framework.found()) +if https_backend == 'auto' and security_framework.found() + https_backend = 'CommonCrypto' +endif + +openssl_required = https_backend == 'openssl' or get_option('sha1_backend') == 'openssl' or get_option('sha256_backend') == 'openssl' +openssl = dependency('openssl', required: openssl_required, 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. +endif + +if https_backend != 'openssl' + libgit_c_args += '-DNO_OPENSSL' +endif + +sha1_backend = get_option('sha1_backend') +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', + ] +elif sha1_backend == 'common-crypto' + libgit_c_args += '-DCOMMON_DIGEST_FOR_OPENSSL' + libgit_c_args += '-DSHA1_APPLE' + # Apple CommonCrypto requires chunking + libgit_c_args += '-DSHA1_MAX_BLOCK_SIZE=1024L*1024L*1024L' +elif sha1_backend == 'openssl' + libgit_c_args += '-DSHA1_OPENSSL' + libgit_dependencies += openssl +elif sha1_backend == 'block' + libgit_c_args += '-DSHA1_BLK' + libgit_sources += 'block-sha1/sha1.c' +else + error('Unhandled SHA1 backend ' + sha1_backend) +endif + +sha256_backend = get_option('sha256_backend') +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 + +if compiler.has_header_symbol('stdlib.h', 'arc4random_buf') + libgit_c_args += '-DHAVE_ARC4RANDOM' +elif compiler.has_header_symbol('bsd/stdlib.h', 'arc4random_buf') + libgit_c_args += '-DHAVE_ARC4RANDOM_BSD' +elif compiler.has_function('getrandom', prefix: '#include <sys/random.h>') + libgit_c_args += '-DHAVE_GETRANDOM' +elif compiler.has_function('getentropy', prefix: '#include <unistd.h>') + libgit_c_args += '-DHAVE_GETENTROPY' +elif compiler.has_function('RtlGenRandom', prefix: '#include <windows.h>\n#include <ntsecapi.h>') + libgit_c_args += '-DHAVE_RTLGENRANDOM' +elif openssl.found() + libgit_c_args += '-DHAVE_OPENSSL_CSPRNG' +endif + +if get_option('runtime_prefix') + libgit_c_args += '-DRUNTIME_PREFIX' + build_options_config.set('RUNTIME_PREFIX', 'true') + + 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') +endif + +foreach key, value : { + 'DIFF': diff.full_path(), + 'GIT_TEST_CMP': diff.full_path() + ' -u', + 'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl', + 'GIT_TEST_MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools', + 'GIT_TEST_POPATH': meson.project_source_root() / 'po', + '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, +) + +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', + 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], +) + +# Build a separate library for "version.c" so that we do not have to rebuild +# everything when the current Git commit changes. +libgit_version_library = static_library('git-version', + sources: [ + 'version.c', + version_def_h, + ], + c_args: libgit_c_args, + dependencies: libgit_dependencies, + include_directories: libgit_include_directories, +) + +libgit_library = static_library('git', + sources: libgit_sources, + c_args: libgit_c_args, + link_with: libgit_version_library, + dependencies: libgit_dependencies, + include_directories: libgit_include_directories, +) + +libgit = declare_dependency( + compile_args: libgit_c_args, + link_with: libgit_library, + 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], + ) + + 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 +common_main_library = static_library('common-main', + sources: common_main_sources, + c_args: libgit_c_args, + dependencies: libgit_dependencies, + include_directories: libgit_include_directories, +) +common_main = declare_dependency( + link_with: common_main_library, + link_args: common_main_link_args, +) + +bin_wrappers = [ ] +test_dependencies = [ ] + +git = executable('git', + sources: builtin_sources + 'git.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) +bin_wrappers += git + +test_dependencies += executable('git-daemon', + sources: 'daemon.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +test_dependencies += executable('git-sh-i18n--envsubst', + sources: 'sh-i18n--envsubst.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +bin_wrappers += executable('git-shell', + sources: 'shell.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +test_dependencies += executable('git-http-backend', + sources: 'http-backend.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +bin_wrappers += executable('scalar', + sources: 'scalar.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('curl').enabled() + curl_sources = [ + 'http.c', + 'http-walker.c', + ] + + git_remote_http = executable('git-remote-http', + sources: curl_sources + 'remote-curl.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + test_dependencies += git_remote_http + + test_dependencies += executable('git-http-fetch', + sources: curl_sources + 'http-fetch.c', + dependencies: [libgit, common_main], + install: true, + install_dir: get_option('libexecdir') / 'git-core', + ) + + if expat.found() + test_dependencies += executable('git-http-push', + sources: curl_sources + 'http-push.c', + dependencies: [libgit, common_main], + 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, + objects: git_remote_http.extract_all_objects(recursive: false), + dependencies: [libgit, common_main], + ) + + install_symlink(alias + executable_suffix, + install_dir: get_option('libexecdir') / 'git-core', + pointing_to: 'git-remote-http', + ) + endforeach +endif + +imap_send_sources = ['imap-send.c'] +if use_curl_for_imap_send + imap_send_sources += curl_sources +endif + +test_dependencies += executable('git-imap-send', + sources: imap_send_sources, + dependencies: [libgit, common_main], + 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.extract_all_objects(recursive: false), + dependencies: [libgit, common_main], + ) + + 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 +subdir('contrib') +subdir('gitweb') +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 + +subdir('bin-wrappers') +if get_option('docs') != [] + subdir('Documentation') +endif + +summary({ + 'curl': curl.found(), + 'expat': expat.found(), + 'gettext': intl.found(), + 'https': https_backend, + 'iconv': iconv.found(), + 'pcre2': pcre2.found(), + 'perl': perl_features_enabled, + 'python': python.found(), +}, section: 'Auto-detected features') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000000..32a72139ba --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,81 @@ +# 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: 'string', value: '', + description: 'A colon-separated list of paths to prepend to PATH if your tools in /usr/bin are broken.') + +# Features supported by Git. +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('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('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', 'common-crypto'], value: 'sha1dc', + description: 'The backend used for hashing objects with the SHA1 object format') +option('sha256_backend', type: 'combo', choices: ['openssl', 'nettle', 'gcrypt', 'block'], value: 'block', + description: 'The backend used for hashing objects with the SHA256 object format') + +# Build tweaks. +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).') + +# Testing. +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') diff --git a/midx-write.c b/midx-write.c index 1ef62c4f4b..bcd1d50eb0 100644 --- a/midx-write.c +++ b/midx-write.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "abspath.h" #include "config.h" @@ -35,13 +33,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 +108,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 +154,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 +480,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 +605,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 +640,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,11 +649,12 @@ 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); @@ -662,8 +663,9 @@ static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash, 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 +673,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 +687,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 +703,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 +761,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 +777,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 +785,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 +822,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 +840,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 +859,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 +892,7 @@ cleanup: 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 +944,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 +991,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 +1013,8 @@ done: 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 +1039,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 +1049,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 +1070,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 +1083,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; @@ -1350,7 +1352,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 +1374,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 +1407,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 +1440,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 +1465,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 +1498,26 @@ cleanup: } 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); } @@ -1569,7 +1574,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 +1772,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); @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "config.h" #include "dir.h" @@ -25,20 +23,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 +92,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 +118,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 +130,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 +143,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 +205,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 +232,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 +252,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 +294,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 +306,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 +315,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 +326,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 +351,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 +361,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 +372,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 +452,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 +463,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 +526,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 +557,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 +728,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 +822,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 +882,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 +891,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")); @@ -973,7 +994,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), @@ -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 3a58ce03d9..95528e3bcd 100644 --- a/name-hash.c +++ b/name-hash.c @@ -5,6 +5,9 @@ * * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "environment.h" #include "gettext.h" diff --git a/negotiator/skipping.c b/negotiator/skipping.c index 6e61b3c5f1..abedb70a48 100644 --- a/negotiator/skipping.c +++ b/negotiator/skipping.c @@ -247,8 +247,11 @@ static int ack(struct fetch_negotiator *n, struct commit *c) static void release(struct fetch_negotiator *n) { - clear_prio_queue(&((struct data *)n->data)->rev_list); - FREE_AND_NULL(n->data); + struct data *data = n->data; + for (int 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); } void skipping_negotiator_init(struct fetch_negotiator *negotiator) @@ -992,15 +992,16 @@ static int notes_display_config(const char *k, const char *v, return 0; } -const char *default_notes_ref(void) +char *default_notes_ref(struct repository *repo) { - const char *notes_ref = NULL; + char *notes_ref = NULL; + if (!notes_ref) - notes_ref = getenv(GIT_NOTES_REF_ENVIRONMENT); + notes_ref = xstrdup_or_null(getenv(GIT_NOTES_REF_ENVIRONMENT)); if (!notes_ref) - notes_ref = notes_ref_name; /* value of core.notesRef config */ + repo_config_get_string(repo, "core.notesref", ¬es_ref); if (!notes_ref) - notes_ref = GIT_NOTES_DEFAULT_REF; + notes_ref = xstrdup(GIT_NOTES_DEFAULT_REF); return notes_ref; } @@ -1010,13 +1011,14 @@ void init_notes(struct notes_tree *t, const char *notes_ref, struct object_id oid, object_oid; unsigned short mode; struct leaf_node root_tree; + char *to_free = NULL; if (!t) t = &default_notes_tree; assert(!t->initialized); if (!notes_ref) - notes_ref = default_notes_ref(); + notes_ref = to_free = default_notes_ref(the_repository); update_ref_namespace(NAMESPACE_NOTES, xstrdup(notes_ref)); if (!combine_notes) @@ -1033,7 +1035,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref, if (flags & NOTES_INIT_EMPTY || repo_get_oid_treeish(the_repository, notes_ref, &object_oid)) - return; + goto out; if (flags & NOTES_INIT_WRITABLE && refs_read_ref(get_main_ref_store(the_repository), notes_ref, &object_oid)) die("Cannot use notes ref %s", notes_ref); if (get_tree_entry(the_repository, &object_oid, "", &oid, &mode)) @@ -1043,6 +1045,9 @@ void init_notes(struct notes_tree *t, const char *notes_ref, oidclr(&root_tree.key_oid, the_repository->hash_algo); oidcpy(&root_tree.val_oid, &oid); load_subtree(t, &root_tree, t->root, 0); + +out: + free(to_free); } struct notes_tree **load_notes_trees(struct string_list *refs, int flags) @@ -1105,7 +1110,7 @@ void load_display_notes(struct display_notes_opt *opt) if (!opt || opt->use_default_notes > 0 || (opt->use_default_notes == -1 && !opt->extra_notes_refs.nr)) { - string_list_append(&display_notes_refs, default_notes_ref()); + string_list_append_nodup(&display_notes_refs, default_notes_ref(the_repository)); display_ref_env = getenv(GIT_NOTES_DISPLAY_REF_ENVIRONMENT); if (display_ref_env) { string_list_add_refs_from_colon_sep(&display_notes_refs, @@ -4,6 +4,7 @@ #include "string-list.h" struct object_id; +struct repository; struct strbuf; /* @@ -70,7 +71,7 @@ extern struct notes_tree { * 3. The value of the core.notesRef config variable, if set * 4. GIT_NOTES_DEFAULT_REF (i.e. "refs/notes/commits") */ -const char *default_notes_ref(void); +char *default_notes_ref(struct repository *repo); /* * Flags controlling behaviour of notes tree initialization diff --git a/object-file.c b/object-file.c index c5994202ba..891eaa2b4b 100644 --- a/object-file.c +++ b/object-file.c @@ -44,31 +44,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 +63,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 = { @@ -115,6 +112,33 @@ static void git_hash_sha1_final_oid(struct object_id *oid, git_hash_ctx *ctx) oid->algo = GIT_HASH_SHA1; } +static void git_hash_sha1_init_unsafe(git_hash_ctx *ctx) +{ + git_SHA1_Init_unsafe(&ctx->sha1_unsafe); +} + +static void git_hash_sha1_clone_unsafe(git_hash_ctx *dst, const git_hash_ctx *src) +{ + git_SHA1_Clone_unsafe(&dst->sha1_unsafe, &src->sha1_unsafe); +} + +static void git_hash_sha1_update_unsafe(git_hash_ctx *ctx, const void *data, + size_t len) +{ + git_SHA1_Update_unsafe(&ctx->sha1_unsafe, data, len); +} + +static void git_hash_sha1_final_unsafe(unsigned char *hash, git_hash_ctx *ctx) +{ + git_SHA1_Final_unsafe(hash, &ctx->sha1_unsafe); +} + +static void git_hash_sha1_final_oid_unsafe(struct object_id *oid, git_hash_ctx *ctx) +{ + git_SHA1_Final_unsafe(oid->hash, &ctx->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_init(git_hash_ctx *ctx) { @@ -189,6 +213,11 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { .update_fn = git_hash_unknown_update, .final_fn = git_hash_unknown_final, .final_oid_fn = git_hash_unknown_final_oid, + .unsafe_init_fn = git_hash_unknown_init, + .unsafe_clone_fn = git_hash_unknown_clone, + .unsafe_update_fn = git_hash_unknown_update, + .unsafe_final_fn = git_hash_unknown_final, + .unsafe_final_oid_fn = git_hash_unknown_final_oid, .empty_tree = NULL, .empty_blob = NULL, .null_oid = NULL, @@ -204,6 +233,11 @@ 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_init_fn = git_hash_sha1_init_unsafe, + .unsafe_clone_fn = git_hash_sha1_clone_unsafe, + .unsafe_update_fn = git_hash_sha1_update_unsafe, + .unsafe_final_fn = git_hash_sha1_final_unsafe, + .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, @@ -219,6 +253,11 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = { .update_fn = git_hash_sha256_update, .final_fn = git_hash_sha256_final, .final_oid_fn = git_hash_sha256_final_oid, + .unsafe_init_fn = git_hash_sha256_init, + .unsafe_clone_fn = git_hash_sha256_clone, + .unsafe_update_fn = git_hash_sha256_update, + .unsafe_final_fn = git_hash_sha256_final, + .unsafe_final_oid_fn = git_hash_sha256_final_oid, .empty_tree = &empty_tree_oid_sha256, .empty_blob = &empty_blob_oid_sha256, .null_oid = &null_oid_sha256, @@ -271,30 +310,28 @@ int hash_algo_by_length(int len) * 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; @@ -419,6 +456,39 @@ enum scld_error safe_create_leading_directories_const(const char *path) return result; } +int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) +{ + int fd; + /* + * we let the umask do its job, don't try to be more + * restrictive except to remove write permission. + */ + int mode = 0444; + git_path_buf(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); + safe_create_leading_directories(temp_filename->buf); + return xmkstemp_mode(temp_filename->buf, mode); +} + +int odb_pack_keep(const char *name) +{ + int fd; + + fd = open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (0 <= fd) + return fd; + + /* slow path */ + safe_create_leading_directories_const(name); + return open(name, O_RDWR|O_CREAT|O_EXCL, 0600); +} + static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) { int i; @@ -1552,7 +1622,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; @@ -1774,7 +1844,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); @@ -1783,11 +1853,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; } @@ -1899,17 +1969,77 @@ static void write_object_file_prepare_literally(const struct git_hash_algo *algo hash_object_body(algo, &c, buf, len, oid, hdr, hdrlen); } +static int check_collision(const char *filename_a, const char *filename_b) +{ + char buf_a[4096], buf_b[4096]; + int fd_a = -1, fd_b = -1; + int ret = 0; + + fd_a = open(filename_a, O_RDONLY); + if (fd_a < 0) { + ret = error_errno(_("unable to open %s"), filename_a); + goto out; + } + + fd_b = open(filename_b, O_RDONLY); + if (fd_b < 0) { + ret = error_errno(_("unable to open %s"), filename_b); + goto out; + } + + while (1) { + ssize_t sz_a, sz_b; + + sz_a = read_in_full(fd_a, buf_a, sizeof(buf_a)); + if (sz_a < 0) { + ret = error_errno(_("unable to read %s"), filename_a); + goto out; + } + + sz_b = read_in_full(fd_b, buf_b, sizeof(buf_b)); + if (sz_b < 0) { + ret = error_errno(_("unable to read %s"), filename_b); + goto out; + } + + if (sz_a != sz_b || memcmp(buf_a, buf_b, sz_a)) { + ret = error(_("files '%s' and '%s' differ in contents"), + filename_a, filename_b); + goto out; + } + + if (sz_a < sizeof(buf_a)) + break; + } + +out: + if (fd_a > -1) + close(fd_a); + if (fd_b > -1) + close(fd_b); + return ret; +} + /* * Move the just written object into its final resting place. */ int finalize_object_file(const char *tmpfile, const char *filename) { + 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) +{ + struct stat st; int 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, @@ -1924,16 +2054,24 @@ int finalize_object_file(const char *tmpfile, const char *filename) */ if (ret && ret != EEXIST) { 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) && + check_collision(tmpfile, filename)) + return -1; + unlink_or_warn(tmpfile); } out: @@ -2053,7 +2191,7 @@ static int start_loose_object_common(struct strbuf *tmp_file, else if (errno == EACCES) return error(_("insufficient permission for adding " "an object to repository database %s"), - get_object_directory()); + repo_get_object_directory(the_repository)); else return error_errno( _("unable to create temporary file")); @@ -2186,7 +2324,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) @@ -2228,7 +2367,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, prepare_loose_object_bulk_checkin(); /* Since oid is not determined, save tmp file to odb path. */ - strbuf_addf(&filename, "%s/", get_object_directory()); + strbuf_addf(&filename, "%s/", repo_get_object_directory(the_repository)); hdrlen = format_object_header(hdr, sizeof(hdr), OBJ_BLOB, len); /* @@ -2275,7 +2414,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, /* * Common steps for write_loose_object and stream_loose_object to - * end writing loose oject: + * end writing loose object: * * - End the compression of zlib stream. * - Get the calculated oid. @@ -2308,7 +2447,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: diff --git a/object-file.h b/object-file.h index d6414610f8..81b30d269c 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 09c1bd93a3..a563635a8c 100644 --- a/object-name.c +++ b/object-name.c @@ -20,6 +20,7 @@ #include "pretty.h" #include "object-store-ll.h" #include "read-cache-ll.h" +#include "repo-settings.h" #include "repository.h" #include "setup.h" #include "midx.h" @@ -951,7 +952,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; @@ -959,7 +960,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len, int fatal = !(flags & GET_OID_QUIETLY); if (len == r->hash_algo->hexsz && !get_oid_hex(str, oid)) { - if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) { + if (repo_settings_get_warn_ambiguous_refs(r) && warn_on_object_refname_ambiguity) { refs_found = repo_dwim_ref(r, str, len, &tmp_oid, &real_ref, 0); if (refs_found > 0) { warning(warn_msg, len, str); @@ -1020,7 +1021,7 @@ static int get_oid_basic(struct repository *r, const char *str, int len, if (!refs_found) return -1; - if (warn_ambiguous_refs && !(flags & GET_OID_QUIETLY) && + if (repo_settings_get_warn_ambiguous_refs(r) && !(flags & GET_OID_QUIETLY) && (refs_found > 1 || !get_short_oid(r, str, len, &tmp_oid, GET_OID_QUIETLY))) warning(warn_msg, len, str); @@ -1400,7 +1401,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; @@ -1422,7 +1423,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; @@ -1733,42 +1734,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); diff --git a/object-store-ll.h b/object-store-ll.h index c5f2bb2fc2..cd3bd5bd99 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 */ }; @@ -232,6 +237,21 @@ struct raw_object_store *raw_object_store_new(void); void raw_object_store_clear(struct raw_object_store *o); /* + * Create a temporary file rooted in the object database directory, or + * die on failure. The filename is taken from "pattern", which should have the + * usual "XXXXXX" trailer, and the resulting filename is written into the + * "template" buffer. Returns the open descriptor. + */ +int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); + +/* + * Create a pack .keep file named "name" (which should generally be the output + * of odb_pack_name). Returns a file descriptor opened for writing, or -1 on + * error. + */ +int odb_pack_keep(const char *name); + +/* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid. */ @@ -530,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 */ @@ -545,11 +545,12 @@ void repo_clear_commit_marks(struct repository *r, unsigned int flags) } } -struct parsed_object_pool *parsed_object_pool_new(void) +struct parsed_object_pool *parsed_object_pool_new(struct repository *repo) { struct parsed_object_pool *o = xmalloc(sizeof(*o)); memset(o, 0, sizeof(*o)); + o->repo = repo; o->blob_state = allocate_alloc_state(); o->tree_state = allocate_alloc_state(); o->commit_state = allocate_alloc_state(); @@ -628,6 +629,16 @@ void raw_object_store_clear(struct raw_object_store *o) hashmap_clear(&o->pack_map); } +void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o) +{ + for (int i = 0; i < o->grafts_nr; i++) { + unparse_commit(o->repo, &o->grafts[i]->oid); + free(o->grafts[i]); + } + o->grafts_nr = 0; + o->commit_graft_prepared = 0; +} + void parsed_object_pool_clear(struct parsed_object_pool *o) { /* @@ -659,6 +670,7 @@ void parsed_object_pool_clear(struct parsed_object_pool *o) free_commit_buffer_slab(o->buffer_slab); o->buffer_slab = NULL; + parsed_object_pool_reset_commit_grafts(o); clear_alloc_state(o->blob_state); clear_alloc_state(o->tree_state); clear_alloc_state(o->commit_state); @@ -7,6 +7,7 @@ struct buffer_slab; struct repository; struct parsed_object_pool { + struct repository *repo; struct object **obj_hash; int nr_objs, obj_hash_size; @@ -31,8 +32,9 @@ struct parsed_object_pool { struct buffer_slab *buffer_slab; }; -struct parsed_object_pool *parsed_object_pool_new(void); +struct parsed_object_pool *parsed_object_pool_new(struct repository *repo); void parsed_object_pool_clear(struct parsed_object_pool *o); +void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o); struct object_list { struct object *item; @@ -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 a877c11f42..f2d74de457 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 0000000000..c872f9ad2d --- /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 0000000000..45a4c4e53c --- /dev/null +++ b/oss-fuzz/fuzz-parse-attr-line.c @@ -0,0 +1,39 @@ +#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) { + int 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 0000000000..2342aa993b --- /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/pack-bitmap-write.c b/pack-bitmap-write.c index 4dc0fe8e40..49758e2525 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -64,6 +64,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 +88,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]; @@ -905,6 +913,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); } diff --git a/pack-bitmap.c b/pack-bitmap.c index 9d9b8c4bfb..7aa2410d9b 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -1,5 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE - #include "git-compat-util.h" #include "commit.h" #include "gettext.h" @@ -177,12 +175,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; - if (index->map_size < header_size + the_hash_algo->rawsz) + size_t header_size = sizeof(*header) - GIT_MAX_RAWSZ + 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 +203,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 +375,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); } @@ -408,8 +415,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 +434,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,7 +445,9 @@ 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; @@ -492,8 +501,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 +528,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 +659,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 +945,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 +1223,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 +1233,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 +1283,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 +1293,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 +1317,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 +1327,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 +1403,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 +1622,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 +1731,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 +1741,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 +1904,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 +1923,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 +1997,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 +2044,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 +2275,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; @@ -2792,7 +2811,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 +2967,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-objects.h b/pack-objects.h index b9898a4e64..3f6f504203 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 diff --git a/pack-revindex.c b/pack-revindex.c index 22d3c23464..d3832478d9 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 d07f03d0ab..98a8c0e785 100644 --- a/pack-write.c +++ b/pack-write.c @@ -8,10 +8,12 @@ #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" #include "path.h" +#include "repository.h" #include "strbuf.h" void reset_pack_idx_option(struct pack_idx_option *opts) @@ -19,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) @@ -211,15 +214,15 @@ static void write_rev_trailer(struct hashfile *f, const unsigned char *hash) hashwrite(f, hash, the_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 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; @@ -237,13 +240,14 @@ const char *write_rev_file(const char *rev_name, 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 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)) @@ -253,12 +257,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)) { @@ -269,22 +274,24 @@ 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_index_positions(f, pack_order, nr_objects); write_rev_trailer(f, hash); - if (rev_name && adjust_shared_perm(rev_name) < 0) - die(_("failed to make %s readable"), rev_name); + if (adjust_shared_perm(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) @@ -473,7 +480,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", - get_object_directory(), name); + repo_get_object_directory(the_repository), name); return NULL; } if (is_well_formed) @@ -527,9 +534,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); } @@ -548,7 +555,7 @@ 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)) @@ -574,7 +581,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); } @@ -58,6 +58,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 *); @@ -96,8 +98,8 @@ 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 char *rev_name, struct pack_idx_entry **objects, uint32_t nr_objects, const unsigned char *hash, unsigned flags); +char *write_rev_file_order(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 diff --git a/packfile.c b/packfile.c index cf12a539ea..9c4bd81a8c 100644 --- a/packfile.c +++ b/packfile.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" #include "environment.h" @@ -25,28 +24,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", get_object_directory(), - 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 +45,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 +77,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 +215,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) { - const char *path = sha1_pack_name(sha1); + 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) +{ + 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 +276,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 +458,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 +538,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 +553,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 +595,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 +608,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 +619,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 +636,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 +665,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 +712,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 +732,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 +759,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 +892,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 +1254,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 +1278,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 +1503,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 +1622,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 +1707,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 +1889,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 +1915,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 +1940,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 +1951,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 +1976,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 +1993,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 +2004,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 +2030,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 +2053,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 +2156,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 +2177,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 +2213,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 +2244,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 +2252,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 +2298,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); diff --git a/packfile.h b/packfile.h index 0f78658229..58104fa009 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,7 +211,7 @@ 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); @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "config.h" #include "editor.h" @@ -92,7 +94,8 @@ const char *git_pager(int stdout_is_tty) pager = getenv("GIT_PAGER"); if (!pager) { if (!pager_program) - read_early_config(core_pager_config, NULL); + read_early_config(the_repository, + core_pager_config, NULL); pager = pager_program; } if (!pager) @@ -298,7 +301,7 @@ int check_pager_config(const char *cmd) data.want = -1; data.value = NULL; - read_early_config(pager_command_config, &data); + read_early_config(the_repository, pager_command_config, &data); if (data.value) pager_program = data.value; diff --git a/parse-options.c b/parse-options.c index 30b9e68f8a..33bfba0ed4 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; diff --git a/parse-options.h b/parse-options.h index ae15342390..f0801d4532 100644 --- a/parse-options.h +++ b/parse-options.h @@ -3,6 +3,8 @@ #include "gettext.h" +struct repository; + /** * Refer to Documentation/technical/api-parse-options.txt for the API doc. */ @@ -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`:: @@ -2,6 +2,8 @@ * Utilities for paths and pathnames */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" #include "environment.h" @@ -682,7 +684,7 @@ return_null: * 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; @@ -690,7 +692,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, }; @@ -734,7 +736,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); @@ -745,7 +748,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)) @@ -156,7 +156,22 @@ int calc_shared_perm(int mode); int adjust_shared_perm(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); diff --git a/pathspec.c b/pathspec.c index fe1f0f41af..0fc6f84a6e 100644 --- a/pathspec.c +++ b/pathspec.c @@ -495,9 +495,9 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags, if (!have_git_dir()) die(_("'%s' is outside the directory tree"), copyfrom); - hint_path = get_git_work_tree(); + hint_path = repo_get_work_tree(the_repository); if (!hint_path) - hint_path = get_git_dir(); + hint_path = repo_get_git_dir(the_repository); die(_("%s: '%s' is outside repository at '%s'"), elt, copyfrom, absolute_path(hint_path)); } diff --git a/perl/FromCPAN/Mail/meson.build b/perl/FromCPAN/Mail/meson.build new file mode 100644 index 0000000000..129cff161c --- /dev/null +++ b/perl/FromCPAN/Mail/meson.build @@ -0,0 +1,7 @@ +test_dependencies += custom_target( + input: 'Address.pm', + output: 'Address.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/FromCPAN/Mail', +) diff --git a/perl/FromCPAN/meson.build b/perl/FromCPAN/meson.build new file mode 100644 index 0000000000..4e7ea909df --- /dev/null +++ b/perl/FromCPAN/meson.build @@ -0,0 +1,9 @@ +test_dependencies += custom_target( + input: 'Error.pm', + output: 'Error.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/FromCPAN', +) + +subdir('Mail') diff --git a/perl/Git.pm b/perl/Git.pm index aebfe0c6e0..6f47d653ab 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) : (); @@ -187,7 +187,7 @@ sub repository { try { # Note that "--is-bare-repository" must come first, as # --git-dir output could contain newlines. - $out = $search->command([qw(rev-parse --is-bare-repository --git-dir)], + $out = $search->command([qw(rev-parse --is-bare-repository --absolute-git-dir)], STDERR => 0); } catch Git::Error::Command with { throw Error::Simple("fatal: not a git repository: $opts{Directory}"); @@ -196,12 +196,12 @@ sub repository { chomp $out; my ($bare, $dir) = split /\n/, $out, 2; - require Cwd; - if ($bare ne 'true') { - require File::Spec; - File::Spec->file_name_is_absolute($dir) or $dir = $opts{Directory} . '/' . $dir; - $opts{Repository} = Cwd::abs_path($dir); + # We know this is an absolute path, because we used + # --absolute-git-dir above. + $opts{Repository} = $dir; + if ($bare ne 'true') { + require Cwd; # If --git-dir went ok, this shouldn't die either. my $prefix = $search->command_oneline('rev-parse', '--show-prefix'); $dir = Cwd::abs_path($opts{Directory}) . '/'; @@ -214,8 +214,6 @@ sub repository { $opts{WorkingCopy} = $dir; $opts{WorkingSubdir} = $prefix; - } else { - $opts{Repository} = Cwd::abs_path($dir); } delete $opts{Directory}; diff --git a/perl/Git/I18N.pm b/perl/Git/I18N.pm index 5454c3a6d2..162230af81 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 8c7fa805f9..92d63c71d2 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 0000000000..7da5b37adb --- /dev/null +++ b/perl/Git/LoadCPAN/Mail/meson.build @@ -0,0 +1,7 @@ +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', +) diff --git a/perl/Git/LoadCPAN/meson.build b/perl/Git/LoadCPAN/meson.build new file mode 100644 index 0000000000..9468c073ae --- /dev/null +++ b/perl/Git/LoadCPAN/meson.build @@ -0,0 +1,9 @@ +test_dependencies += custom_target( + input: 'Error.pm', + output: 'Error.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git/LoadCPAN', +) + +subdir('Mail') diff --git a/perl/Git/Packet.pm b/perl/Git/Packet.pm index d896e69523..00fd9c484a 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 0000000000..515ab3dd92 --- /dev/null +++ b/perl/Git/SVN/Memoize/meson.build @@ -0,0 +1,7 @@ +test_dependencies += custom_target( + input: 'YAML.pm', + output: 'YAML.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5/Git/SVN', +) diff --git a/perl/Git/SVN/meson.build b/perl/Git/SVN/meson.build new file mode 100644 index 0000000000..8338531041 --- /dev/null +++ b/perl/Git/SVN/meson.build @@ -0,0 +1,20 @@ +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', + ) +endforeach + +subdir('Memoize') diff --git a/perl/Git/meson.build b/perl/Git/meson.build new file mode 100644 index 0000000000..259209d730 --- /dev/null +++ b/perl/Git/meson.build @@ -0,0 +1,18 @@ +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', + ) +endforeach + +subdir('LoadCPAN') +subdir('SVN') diff --git a/perl/header_templates/fixed_prefix.template.pl b/perl/header_templates/fixed_prefix.template.pl index 857b4391a4..d571ca5cde 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 9d28b3d863..e6f8e661a1 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 0000000000..c22d6f8a1a --- /dev/null +++ b/perl/meson.build @@ -0,0 +1,12 @@ +test_dependencies += custom_target( + input: 'Git.pm', + output: 'Git.pm', + command: generate_perl_command, + install: true, + install_dir: get_option('datadir') / 'perl5', +) + +subdir('Git') +if get_option('perl_cpan_fallback') + subdir('FromCPAN') +endif @@ -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 @@ -222,7 +222,9 @@ # reftable таблица с указатели # its referent '%s' сочещия го „%s“ # dry run пробно изпълнение -# +# mailmap файл за съответствията на имената и адресите на е-поща +# unit test поединичен тест +# test suite група тестове # # ------------------------ # „$var“ - може да не сработва за shell има gettext и eval_gettext - проверка - намират се лесно по „$ @@ -251,8 +253,8 @@ msgid "" msgstr "" "Project-Id-Version: git 2.45\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-20 07:37+0200\n" -"PO-Revision-Date: 2024-07-21 22:27+0300\n" +"POT-Creation-Date: 2024-10-05 01:20+0000\n" +"PO-Revision-Date: 2024-10-05 13:20+0200\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -808,7 +810,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 +822,7 @@ msgstr "" "s — разделяне на текущото парче на по-малки\n" "e — ръчно редактиране на текущото парче\n" "p — извеждане на текущото парче\n" +"P — извеждане на текущото парче през програма за прелистване\n" "? — извеждане на помощта\n" #, c-format @@ -1516,6 +1519,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 +1575,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“ не може да се обработи" @@ -1635,6 +1650,10 @@ 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“ липсва" @@ -2771,9 +2790,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“ не може да се отвори за добавяне" @@ -3789,9 +3805,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 "не са указани контакти" @@ -4146,6 +4170,10 @@ 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“" @@ -4426,7 +4454,9 @@ 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 [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]" @@ -4939,7 +4969,7 @@ msgstr "git commit-tree: не може да се прочете" 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" @@ -4949,11 +4979,11 @@ msgid "" msgstr "" "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 +5495,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>] [--" @@ -5498,6 +5527,14 @@ 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>" msgstr "" @@ -6326,8 +6363,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 +6403,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" @@ -6672,7 +6709,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=НАСТРОЙКА" @@ -7046,6 +7084,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 "" "изрично стартиране на събирането на боклука, дори и ако вече работи друго " @@ -7150,6 +7191,9 @@ msgstr "задачата „%s“ не може да се избере пове� msgid "run tasks based on the state of the repository" msgstr "изпълняване на задачи според състоянието на хранилището" +msgid "perform maintenance in the background" +msgstr "извършване на дейностите по поддръжка на заден фон" + msgid "frequency" msgstr "честота" @@ -8029,9 +8073,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 +8663,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 "АЛГОРИТЪМ" @@ -9110,6 +9142,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 "" "запазване на битовата маска за множество пакети, съдържаща само дадените " @@ -11196,6 +11231,9 @@ msgstr "неправилен формат на указател: %s" msgid "git refs migrate --ref-format=<format> [--dry-run]" msgstr "git refs migrate --ref-format=ФОРМАТ [--dry-run]" +msgid "git refs verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" + msgid "specify the reference format to convert to" msgstr "указване на форма̀та за указател, към който да се конвертира" @@ -11209,6 +11247,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>" @@ -12668,10 +12712,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 +12771,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 "настройките на работното дърво не може да се инициализират" @@ -13185,8 +13233,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 "" @@ -17918,13 +17966,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'" @@ -18486,6 +18537,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 +18581,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 +18607,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 +18678,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 +18729,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 "" "файлът с индекса за множество пакети съществува, но не може да бъде " @@ -18849,6 +18954,14 @@ 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“ не може да бъде записан" @@ -18934,10 +19047,6 @@ 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)" @@ -20212,6 +20321,10 @@ 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 +20462,8 @@ msgid "" "\n" "\tgit branch -m <name>\n" msgstr "" -"Първоначалният клон ще се казва „%s“. Това може да се променѝ. Може да зададете\n" +"Първоначалният клон ще се казва „%s“. Това може да се променѝ. Може да " +"зададете\n" "настройката и да спрете това съобщение. За това изпълнете:\n" "\n" " git config --global init.defaultBranch ИМЕ\n" @@ -20446,6 +20560,13 @@ 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" @@ -20993,7 +21114,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 +21220,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'" @@ -21121,6 +21247,10 @@ 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“ не може да се настрои" @@ -22241,6 +22371,10 @@ 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" "%sTo add an exception for this directory, call:\n" @@ -22715,6 +22849,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 +23115,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 "опцията не се поддържа от протокола" @@ -23915,6 +24069,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" @@ -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" +#: 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 "failed to open pack-index '%s'" +msgstr "no s'ha pogut obrir l'índex del paquet «%s»" + +#: 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" + +#: 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 "could not parse line: %s" +msgstr "no s'ha pogut analitzar la línia: %s" + +#: midx-write.c +#, c-format +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 "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 "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" @@ -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: 2024-10-05 16:17+0200\n" +"PO-Revision-Date: 2024-10-05 16:18+0200\n" "Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n" "Language-Team: German\n" "Language: de\n" @@ -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 @@ -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" @@ -1402,6 +1414,10 @@ 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" @@ -2525,9 +2541,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" @@ -3533,9 +3546,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" @@ -3898,6 +3916,10 @@ 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" @@ -4693,7 +4715,7 @@ msgstr "git commit-tree: Fehler beim Lesen" 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" @@ -4703,7 +4725,7 @@ msgid "" msgstr "" "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" @@ -5207,11 +5229,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>] " +"regexp] [--value=<Wert>] [--fixed-value] [--default=<Standardwert>] " "<Name>" msgid "" @@ -5243,6 +5264,15 @@ msgstr "" "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>" msgstr "" @@ -6061,8 +6091,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 +6131,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" @@ -6792,6 +6822,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" @@ -6895,6 +6928,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" @@ -7771,9 +7807,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 +8386,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>" @@ -8841,6 +8865,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" @@ -10930,6 +10957,9 @@ 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 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" @@ -10943,6 +10973,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>" @@ -12397,11 +12433,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 +12496,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 +12967,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 "" @@ -17635,13 +17675,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'" @@ -18213,6 +18256,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 +18296,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 +18386,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 +18425,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" @@ -18556,6 +18643,14 @@ 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." @@ -18642,10 +18737,6 @@ 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)." @@ -19882,6 +19973,10 @@ 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" @@ -20121,6 +20216,13 @@ msgstr "" "'%s': ist aber eine reguläre Referenz" #, 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" @@ -20766,12 +20868,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'" @@ -20790,6 +20895,10 @@ 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" @@ -21872,6 +21981,10 @@ 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" "%sTo add an exception for this directory, call:\n" @@ -22339,6 +22452,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" @@ -23588,6 +23719,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" @@ -80,8 +80,8 @@ msgid "" msgstr "" "Project-Id-Version: git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-17 21:57+0000\n" -"PO-Revision-Date: 2024-07-19 20:25+0200\n" +"POT-Creation-Date: 2024-10-02 16:57+0000\n" +"PO-Revision-Date: 2024-10-04 23:03+0200\n" "Last-Translator: Cédric Malard <c.malard-git@valdun.net>\n" "Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n" "Language: fr\n" @@ -628,7 +628,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 +639,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 @@ -1330,6 +1330,15 @@ 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é" @@ -1380,6 +1389,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 +1465,9 @@ msgstr "nom d'objet invalide : %s" msgid "not a tree object: %s" msgstr "objet arbre invalide : %s" +msgid "unable to checkout working tree" +msgstr "impossible d'extraire la copie de travail" + #, c-format msgid "File not found: %s" msgstr "Fichier non trouvé : %s" @@ -2566,9 +2581,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" @@ -3364,7 +3376,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 +3581,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é" @@ -3929,6 +3946,10 @@ 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'" @@ -4415,9 +4436,6 @@ 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" @@ -4707,7 +4725,7 @@ msgstr "git commit-tree : échec de la lecture" 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" @@ -4718,7 +4736,7 @@ msgstr "" "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" +" [-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" @@ -5222,12 +5240,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>] [--" @@ -5258,6 +5275,15 @@ 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>" msgstr "" @@ -6077,8 +6103,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 +6143,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" @@ -6797,6 +6823,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 " @@ -6897,6 +6926,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" @@ -7776,9 +7808,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" @@ -8365,15 +8394,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>" @@ -8848,6 +8868,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" @@ -10903,6 +10926,9 @@ 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 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" @@ -10916,6 +10942,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 strict" + +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>" @@ -12370,13 +12402,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" @@ -12435,6 +12465,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 +12938,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 "" @@ -17628,13 +17662,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'" @@ -18190,6 +18227,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 +18267,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 dpuis 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" + msgid "could not start pack-objects" msgstr "impossible de démarrer le groupement d'objets" @@ -18303,6 +18367,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 +18407,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é" @@ -18534,6 +18616,14 @@ 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" @@ -18619,10 +18709,6 @@ 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)" @@ -19866,6 +19952,10 @@ 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" @@ -20100,6 +20190,13 @@ msgstr "" "normale trouvée" #, 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" @@ -20750,13 +20847,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'" @@ -20775,6 +20876,10 @@ 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'" @@ -21846,6 +21951,10 @@ 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" "%sTo add an exception for this directory, call:\n" @@ -22320,6 +22429,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'" @@ -23526,6 +23654,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" @@ -23830,6 +23961,13 @@ msgstr "%s sauté avec un suffix de sauvegarde '%s'.\n" msgid "Do you really want to send %s? [y|N]: " msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : " +#~ msgid "revision walk setup failed\n" +#~ msgstr "échec de la préparation du parcours des révisions\n" + +#, c-format +#~ msgid "unable to parse contact: %s" +#~ msgstr "impossible d'analyser le contact : %s" + #, c-format #~ msgid "truncating .rej filename to %.*s.rej" #~ msgstr "troncature du nom de fichier .rej en %.*s.rej" @@ -23855,10 +23993,6 @@ msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : " #~ 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é" @@ -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: 2024-10-04 08:33+0700\n" +"PO-Revision-Date: 2024-10-04 08:52+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 @@ -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,10 @@ msgstr "bukan nama objek valid: %s" msgid "not a tree object: %s" msgstr "bukan objek pohon: %s" +#: archive.c builtin/clone.c +msgid "unable to checkout working tree" +msgstr "tidak dapat men-checkout pohon kerja" + #: archive.c #, c-format msgid "File not found: %s" @@ -1768,7 +1790,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 +1862,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 +2000,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 +2261,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 +2760,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" @@ -3037,10 +3059,6 @@ msgstr "" "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" msgstr "tidak dapat membuka '%s' untuk menambahkan" @@ -4282,9 +4300,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" @@ -4711,6 +4736,11 @@ 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'" msgstr "'%s' tidak dapat digunakan dengan '%s'" @@ -5178,7 +5208,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" @@ -5276,7 +5306,7 @@ msgstr "gagal membuat tautan '%s'" msgid "failed to copy file to '%s'" msgstr "gagal menyalin berkas ke '%s'" -#: builtin/clone.c +#: builtin/clone.c refs/files-backend.c #, c-format msgid "failed to iterate over '%s'" msgstr "gagal iterasi pada '%s'" @@ -5319,10 +5349,6 @@ 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" @@ -5342,7 +5368,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'" @@ -5687,7 +5714,7 @@ msgstr "git commit-tree: gagal membaca" 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" @@ -5697,7 +5724,7 @@ msgid "" msgstr "" "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 +6331,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 "" @@ -6345,6 +6370,16 @@ 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] " "[--value=<value>] [--fixed-value] <name> <value>" msgstr "" @@ -7372,8 +7407,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 +7454,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 @@ -8277,6 +8312,10 @@ 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" @@ -8397,6 +8436,10 @@ 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" @@ -9503,10 +9546,6 @@ 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" msgstr "git show %s: berkas jelek" @@ -10246,18 +10285,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>" @@ -10553,7 +10580,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" @@ -10853,6 +10880,10 @@ 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" @@ -13337,6 +13368,10 @@ 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 "sebutkan format referensi untuk dikonversi" @@ -13353,6 +13388,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] [--" @@ -15156,12 +15199,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" @@ -15228,6 +15271,11 @@ 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 +15845,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" @@ -18519,7 +18567,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'" @@ -19894,7 +19942,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" @@ -21529,6 +21577,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 +21588,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 @@ -22201,6 +22253,20 @@ 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" @@ -22237,14 +22303,30 @@ 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" @@ -22253,6 +22335,10 @@ 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" @@ -22329,6 +22415,33 @@ 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)" msgstr "pack-int-id jelek: %u (total pak %u)" @@ -22351,11 +22464,6 @@ 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" @@ -22616,6 +22724,16 @@ 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" @@ -22724,11 +22842,6 @@ 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)" msgstr "hash tidak cocok untuk %s (diharapkan %s)" @@ -24215,6 +24328,11 @@ 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" msgstr "nama bidang rusak: %.*s" @@ -24502,6 +24620,15 @@ msgstr "" "tidak dapat mengunci referensi '%s': diharapkan referensi simbolik dengan " "target '%s': tetapi bukan referensi reguler" +#: 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" @@ -25290,12 +25417,16 @@ 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 @@ -25319,6 +25450,11 @@ 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'" msgstr "tidak dapat menyetel '%s'" @@ -26608,6 +26744,11 @@ 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 "" "detected dubious ownership in repository at '%s'\n" "%sTo add an exception for this directory, call:\n" @@ -27181,6 +27322,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" @@ -28630,6 +28795,10 @@ 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" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000000..d7154b6395 --- /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] @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git 2.46.0\n" +"Project-Id-Version: git 2.47.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: 2024-09-19 02:06+0000\n" +"PO-Revision-Date: 2024-09-28 15:45+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 @@ -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" @@ -2440,9 +2452,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" @@ -3414,9 +3423,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" @@ -3765,6 +3779,10 @@ 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”" @@ -4521,7 +4539,7 @@ msgstr "git commit-tree: misslyckades läsa" 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" @@ -4531,7 +4549,7 @@ msgid "" msgstr "" "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" @@ -5022,12 +5040,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>] [--" @@ -5056,6 +5072,15 @@ 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>" msgstr "" @@ -5853,8 +5878,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 +5916,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" @@ -6568,6 +6593,9 @@ 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" @@ -6664,6 +6692,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" @@ -7521,9 +7552,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" @@ -8080,15 +8108,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>" @@ -8553,6 +8572,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" @@ -10546,6 +10568,9 @@ 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 verify [--strict] [--verbose]" +msgstr "git refs verify [--strict] [--verbose]" + msgid "specify the reference format to convert to" msgstr "ange referensformatet att konvertera till" @@ -10559,6 +10584,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>" @@ -11978,11 +12009,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" @@ -12034,6 +12065,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" @@ -12485,8 +12520,8 @@ 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" @@ -17031,13 +17066,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'" @@ -17586,6 +17624,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 +17663,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 +17751,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)" @@ -17704,10 +17789,6 @@ 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" - msgid "multi-pack-index file exists, but failed to parse" msgstr "multi-pack-indexfilen finns, men kunde inte tolkas" @@ -19219,6 +19300,10 @@ 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" @@ -19451,6 +19536,13 @@ msgstr "" "men är en vanlig referens" #, 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" @@ -20077,12 +20169,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'" @@ -20101,6 +20196,10 @@ 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”" @@ -21162,6 +21261,10 @@ 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" "%sTo add an exception for this directory, call:\n" @@ -21624,6 +21727,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”" @@ -22793,6 +22914,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 utelsutande\n" + msgid "" "fatal: found configuration options for 'sendmail'\n" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -23093,3 +23217,10 @@ msgstr "" #, perl-format msgid "Do you really want to send %s? [y|N]: " msgstr "Vill du verkligen sända %s? [y=ja, n=nej]: " + +#~ msgid "revision walk setup failed\n" +#~ msgstr "misslyckades starta revisionstraversering\n" + +#, c-format +#~ msgid "unable to parse contact: %s" +#~ msgstr "kan inte tolka kontakt: %s" @@ -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: 2024-10-03 06:52+0300\n" +"PO-Revision-Date: 2024-10-03 07: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 @@ -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,9 @@ msgstr "geçerli bir nesne adı değil: %s" msgid "not a tree object: %s" msgstr "bir ağaç nesnesi değil: %s" +msgid "unable to checkout working tree" +msgstr "çalışma ağacı çıkış yapılamıyor" + #, c-format msgid "File not found: %s" msgstr "Dosya bulunamadı: %s" @@ -2531,9 +2546,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ı" @@ -3508,9 +3520,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" @@ -3858,6 +3875,10 @@ 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" @@ -4334,9 +4355,6 @@ 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" @@ -4622,7 +4640,7 @@ msgstr "git commit-tree: okunamadı" 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" @@ -4631,14 +4649,14 @@ msgid "" " [--] [<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" -" [-F <dosya> | -m <ileti>] [--reset-author] [--allow-empty]\n" +" [--dry-run] [(-c | -C | --squash) <işleme> | --fixup\n" +" [(amend|reword):]<işleme>] [-F <dosya> | -m <ileti>] [--" +"reset-author] [--allow-empty]\n" " [--allow-empty-message] [--no-verify] [-e] [--author=<author>]\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 +5149,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>] [--" @@ -5165,6 +5181,15 @@ 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>" msgstr "" @@ -5966,8 +5991,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 +6029,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" @@ -6678,6 +6703,9 @@ 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" @@ -6773,6 +6801,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" @@ -7635,9 +7666,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 +8227,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>" @@ -8670,6 +8689,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" @@ -10678,6 +10700,9 @@ 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 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" @@ -10691,6 +10716,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>" @@ -12121,11 +12152,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 +12208,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 +12660,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" @@ -17177,13 +17212,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'" @@ -17739,6 +17777,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 +17816,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 +17901,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 +17939,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ı" @@ -18065,6 +18147,14 @@ 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" @@ -18149,10 +18239,6 @@ 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)" @@ -19362,6 +19448,10 @@ 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" @@ -19597,6 +19687,13 @@ msgstr "" "bekleniyordu; ancak bu normal bir başvuru" #, 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" @@ -20227,12 +20324,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'" @@ -20251,6 +20351,10 @@ 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ı" @@ -21306,6 +21410,10 @@ 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" "%sTo add an exception for this directory, call:\n" @@ -21768,6 +21876,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" @@ -22934,6 +23060,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" @@ -64,10 +64,10 @@ # +------------------------------------------------------------------+ msgid "" msgstr "" -"Project-Id-Version: git 2.46\n" +"Project-Id-Version: git 2.47\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: 2024-10-05 01:20+0000\n" +"PO-Revision-Date: 2024-10-05 16:48+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 +605,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 +616,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 @@ -1282,6 +1282,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 +1337,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'" @@ -1400,6 +1412,10 @@ 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" @@ -2497,9 +2513,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" @@ -2707,17 +2720,17 @@ msgid "ignore revisions from <file>" msgstr "bỏ qua các điểm xét duyệt 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 điểm xét duyệt (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" @@ -3474,9 +3487,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ạ" @@ -3813,7 +3831,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'" @@ -4585,7 +4607,7 @@ msgstr "git commit-tree: gặp lỗi khi đọ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" @@ -4660,7 +4682,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ý." @@ -5106,12 +5128,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>] [--" @@ -5141,6 +5162,15 @@ 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>" msgstr "" @@ -5941,8 +5971,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 +6009,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" @@ -6652,7 +6682,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" @@ -6751,6 +6784,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ố" @@ -7030,10 +7066,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)" @@ -7519,7 +7555,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 +7639,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" @@ -8174,15 +8207,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>" @@ -8654,6 +8678,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" @@ -10674,6 +10701,9 @@ 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 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" @@ -10687,6 +10717,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>" @@ -12095,11 +12131,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 +12187,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" @@ -12394,7 +12434,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 +12645,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" @@ -14774,7 +14814,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" @@ -17171,13 +17211,16 @@ msgstr "" 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'" @@ -17701,7 +17744,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 +17772,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 +17791,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 +17803,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 +17835,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 +17894,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 +17932,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" @@ -18056,6 +18142,14 @@ 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" @@ -18103,7 +18197,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" @@ -18141,10 +18235,6 @@ 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)" @@ -19079,10 +19169,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" @@ -19352,6 +19442,10 @@ 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" @@ -19586,6 +19680,13 @@ msgstr "" "tham chiếu thường" #, 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" @@ -20144,7 +20245,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 +20313,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'" @@ -20236,6 +20340,10 @@ 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'" @@ -21301,6 +21409,10 @@ 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" "%sTo add an exception for this directory, call:\n" @@ -21762,9 +21874,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 +21902,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" @@ -22962,6 +23092,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" diff --git a/po/zh_CN.po b/po/zh_CN.po index 91b8b79de8..55d2aee627 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -154,8 +154,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-07-27 22:28+0800\n" -"PO-Revision-Date: 2024-07-28 19:52+0800\n" +"POT-Creation-Date: 2024-10-05 03:31+0800\n" +"PO-Revision-Date: 2024-10-05 03:32+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 +784,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 +795,7 @@ msgstr "" "/ - 查找和给定正则表达式匹配的块\n" "s - 拆分当前块为更小的块\n" "e - 手动编辑当前块\n" -"p - 显示当前块\n" +"p - 显示当前块, 'P' 使用分页器\n" "? - 显示帮助\n" #: add-patch.c @@ -1613,6 +1613,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 +1686,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 +1778,10 @@ msgstr "不是一个有效的对象名:%s" msgid "not a tree object: %s" msgstr "不是一个树对象:%s" +#: archive.c builtin/clone.c +msgid "unable to checkout working tree" +msgstr "不能检出工作区" + #: archive.c #, c-format msgid "File not found: %s" @@ -1878,7 +1898,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'" @@ -1949,7 +1969,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 +2106,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 +2353,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 +2833,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 "格式" @@ -3108,10 +3128,6 @@ msgstr "" "支持的选项有:--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" msgstr "无法打开 '%s' 进行追加" @@ -4337,9 +4353,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" @@ -4759,6 +4782,11 @@ 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'" msgstr "'%s' 不能和 '%s' 同时使用" @@ -5223,7 +5251,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 "指定要使用的引用格式" @@ -5320,7 +5348,7 @@ msgstr "无法创建链接 '%s'" msgid "failed to copy file to '%s'" msgstr "无法拷贝文件至 '%s'" -#: builtin/clone.c +#: builtin/clone.c refs/files-backend.c #, c-format msgid "failed to iterate over '%s'" msgstr "无法在 '%s' 上迭代" @@ -5363,10 +5391,6 @@ 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 "无法将参数写入配置文件" @@ -5386,7 +5410,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'" @@ -5724,7 +5749,7 @@ msgstr "git commit-tree:无法读取" 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" @@ -5734,7 +5759,7 @@ msgid "" msgstr "" "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 +6352,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 "" @@ -6367,6 +6391,15 @@ msgstr "git config [<文件选项>] --get-colorbool <名称> [<标准输出为tt #: 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] " "[--value=<value>] [--fixed-value] <name> <value>" msgstr "" @@ -7373,8 +7406,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 +7455,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 @@ -8266,6 +8299,10 @@ 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 正在执行" @@ -8383,6 +8420,10 @@ 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 "频率" @@ -9474,10 +9515,6 @@ 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" msgstr "git show %s: 损坏的文件" @@ -10205,18 +10242,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 "<算法>" @@ -10512,7 +10537,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" @@ -10804,6 +10829,10 @@ 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 "写入只包括给定索引的多包索引" @@ -13206,6 +13235,10 @@ msgid "git refs migrate --ref-format=<format> [--dry-run]" msgstr "git refs migrate --ref-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 "指定要转换的引用格式" @@ -13222,6 +13255,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] [--" @@ -14996,12 +15037,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" @@ -15064,6 +15105,11 @@ 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 +15658,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" @@ -18289,7 +18335,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' 调整共享权限" @@ -19638,7 +19684,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" @@ -21117,6 +21163,7 @@ msgstr "" "\n" "来设置您账号的缺省身份标识。\n" "如果仅在本仓库设置身份标识,则省略 --global 参数。\n" +"\n" #: ident.c msgid "no email was given and auto-detection is disabled" @@ -21237,6 +21284,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 +21295,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 @@ -21879,6 +21930,20 @@ 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 "忽略已存在的多包索引,校验码不匹配" @@ -21915,14 +21980,30 @@ 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 "正在对引用对象计数" @@ -21931,6 +22012,10 @@ 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" @@ -22002,6 +22087,33 @@ 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)" msgstr "错的 pack-int-id:%u(共有 %u 个包)" @@ -22024,11 +22136,6 @@ 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 "多包索引文件存在,但无法解析" @@ -22287,6 +22394,16 @@ 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" @@ -22393,11 +22510,6 @@ 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)" msgstr "%s 的哈希值不匹配(预期 %s)" @@ -23844,6 +23956,11 @@ 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" msgstr "格式错误的字段名:%.*s" @@ -24125,6 +24242,15 @@ 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 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" @@ -24895,12 +25021,16 @@ 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 @@ -24924,6 +25054,11 @@ msgstr "无法在 '%s' 中配置远程" #: scalar.c #, c-format +msgid "could not disable tags in '%s'" +msgstr "无法禁用 '%s' 中的标签" + +#: scalar.c +#, c-format msgid "could not configure '%s'" msgstr "无法配置 '%s'" @@ -26192,6 +26327,11 @@ msgstr "无法获取 '%*s%s%s' 状态(stat)" #: setup.c #, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory '%s' 不是绝对路径" + +#: setup.c +#, c-format msgid "" "detected dubious ownership in repository at '%s'\n" "%sTo add an exception for this directory, call:\n" @@ -26750,6 +26890,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" @@ -28201,6 +28365,10 @@ 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" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" diff --git a/po/zh_TW.po b/po/zh_TW.po index abf7157a99..5e6818f453 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: 2024-10-05 01:20+0000\n" +"PO-Revision-Date: 2024-10-05 15:45+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 @@ -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" @@ -1638,6 +1654,11 @@ msgstr "非樹狀物件:%s" #: archive.c #, c-format +msgid "failed to unpack tree object %s" +msgstr "解包 %s 樹狀物件失敗" + +#: archive.c +#, c-format msgid "File not found: %s" msgstr "找不到檔案:%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 "詳細輸出" @@ -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" @@ -2991,10 +3010,6 @@ msgstr "" "支援的選項有:--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" msgstr "無法開啟「%s」進行附加" @@ -4225,9 +4240,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" @@ -4636,6 +4658,11 @@ 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'" msgstr "「%s」不能與「%s」同時使用" @@ -5101,7 +5128,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 "指定要使用的引用格式" @@ -5198,7 +5225,7 @@ msgstr "建立連結 '%s' 失敗" msgid "failed to copy file to '%s'" msgstr "複製檔案至 '%s' 失敗" -#: builtin/clone.c +#: builtin/clone.c refs/files-backend.c #, c-format msgid "failed to iterate over '%s'" msgstr "無法在 '%s' 上疊代" @@ -5264,7 +5291,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」" @@ -5602,7 +5630,7 @@ msgstr "git commit-tree:讀取失敗" 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" @@ -5612,7 +5640,7 @@ msgid "" msgstr "" "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" @@ -6211,11 +6239,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 "" @@ -6251,6 +6278,15 @@ 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] " "[--value=<value>] [--fixed-value] <name> <value>" msgstr "" @@ -7259,8 +7295,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 +7344,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 @@ -8155,6 +8191,10 @@ 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 正在執行" @@ -8271,6 +8311,10 @@ 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" @@ -8434,7 +8478,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 @@ -9357,10 +9400,6 @@ 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" msgstr "git show %s: 損壞的檔案" @@ -10086,18 +10125,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 "<演算法>" @@ -10393,7 +10420,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" @@ -10685,6 +10712,10 @@ 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 "寫入只包含指定索引的多包索引" @@ -13091,6 +13122,10 @@ msgid "git refs migrate --ref-format=<format> [--dry-run]" msgstr "git refs migrate --ref-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 "指定要轉換成的引用格式" @@ -13107,6 +13142,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] [--" @@ -14877,12 +14920,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" @@ -14945,6 +14988,11 @@ 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 "無法初始化工作區組態" @@ -15496,8 +15544,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" @@ -18167,7 +18215,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」的共用權限" @@ -19504,7 +19552,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" @@ -21100,6 +21148,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 +21159,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 @@ -21744,6 +21796,20 @@ 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 "忽略現有的多包索引:總和檢查碼不符" @@ -21780,14 +21846,30 @@ 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 "正在計算引用物件" @@ -21796,6 +21878,10 @@ 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" @@ -21867,6 +21953,33 @@ 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)" msgstr "錯的 pack-int-id:%u(共有 %u 個包)" @@ -21889,11 +22002,6 @@ 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 檔案,但無法解析" @@ -22152,6 +22260,16 @@ 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" @@ -22258,11 +22376,6 @@ 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)" msgstr "%s 的雜湊值不符合(預期 %s)" @@ -23709,6 +23822,11 @@ 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" msgstr "格式錯誤的欄位名:%.*s" @@ -23991,6 +24109,15 @@ 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 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" @@ -24760,12 +24887,16 @@ 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 @@ -24789,6 +24920,11 @@ msgstr "無法設定「%s」中的遠端" #: scalar.c #, c-format +msgid "could not disable tags in '%s'" +msgstr "無法停用「%s」的標籤" + +#: scalar.c +#, c-format msgid "could not configure '%s'" msgstr "無法設定「%s」" @@ -26061,6 +26197,11 @@ msgstr "取得 '%*s%s%s' 狀態(stat)失敗" #: setup.c #, c-format +msgid "safe.directory '%s' not absolute" +msgstr "safe.directory「%s」不是絕對路徑" + +#: setup.c +#, c-format msgid "" "detected dubious ownership in repository at '%s'\n" "%sTo add an exception for this directory, call:\n" @@ -26617,6 +26758,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" @@ -28068,6 +28233,10 @@ 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" "git-send-email is configured with the sendemail.* options - note the 'e'.\n" @@ -28413,6 +28582,13 @@ msgstr "略過 %s 含備份後綴 '%s'。\n" msgid "Do you really want to send %s? [y|N]: " msgstr "您真的要傳送 %s?[y|N]: " +#~ 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." @@ -28434,10 +28610,6 @@ msgstr "您真的要傳送 %s?[y|N]: " #~ 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 63fd35d64b..7926eb09a6 100644 --- a/preload-index.c +++ b/preload-index.c @@ -1,6 +1,9 @@ /* * Copyright (C) 2008 Linus Torvalds */ + +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "pathspec.h" #include "dir.h" @@ -2032,6 +2032,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, @@ -2205,7 +2206,7 @@ static void strbuf_add_tabexpand(struct strbuf *sb, struct grep_opt *opt, } /* - * pp_handle_indent() prints out the intendation, and + * pp_handle_indent() prints out the indentation, and * the whole line (without the final newline), after * de-tabifying. */ diff --git a/promisor-remote.c b/promisor-remote.c index 317e1b127f..c714f4f007 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -154,6 +154,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 +190,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); } @@ -281,7 +283,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])); } @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "parse.h" #include "environment.h" diff --git a/prune-packed.c b/prune-packed.c index e54daf740a..d1c65ab10e 100644 --- a/prune-packed.c +++ b/prune-packed.c @@ -1,10 +1,12 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" -#include "environment.h" #include "gettext.h" #include "object-store-ll.h" #include "packfile.h" #include "progress.h" #include "prune-packed.h" +#include "repository.h" static struct progress *progress; @@ -22,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 +39,7 @@ void prune_packed_objects(int opts) if (opts & PRUNE_PACKED_VERBOSE) progress = start_delayed_progress(_("Removing duplicate objects"), 256); - for_each_loose_file_in_objdir(get_object_directory(), + for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), prune_object, NULL, prune_subdir, &opts); /* Ensure we show 100% before finishing progress */ diff --git a/pseudo-merge.c b/pseudo-merge.c index 10ebd9a4e9..bb59965ed2 100644 --- a/pseudo-merge.c +++ b/pseudo-merge.c @@ -87,7 +87,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 +97,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 +275,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); } diff --git a/pseudo-merge.h b/pseudo-merge.h index 4b5febaa63..29df8a32ec 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; diff --git a/range-diff.c b/range-diff.c index bbb0952264..10885ba301 100644 --- a/range-diff.c +++ b/range-diff.c @@ -480,7 +480,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 +508,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); /* diff --git a/reachable.c b/reachable.c index 3e9b3dd0a4..ecf7ccf504 100644 --- a/reachable.c +++ b/reachable.c @@ -239,7 +239,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 +324,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 e0e39607ef..71b49d9af4 100644 --- a/read-cache-ll.h +++ b/read-cache-ll.h @@ -151,7 +151,7 @@ enum sparse_index_mode { /* * The index has already been collapsed to sparse directories - * whereever possible. + * wherever possible. */ INDEX_COLLAPSED, @@ -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 4e67dc182e..01d0b3ad22 100644 --- a/read-cache.c +++ b/read-cache.c @@ -31,6 +31,7 @@ #include "path.h" #include "preload-index.h" #include "read-cache.h" +#include "repository.h" #include "resolve-undo.h" #include "revision.h" #include "strbuf.h" @@ -2187,6 +2188,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; } @@ -3123,6 +3125,7 @@ out: if (f) free_hashfile(f); strbuf_release(&sb); + free(eoie_c); free(ieot); return ret; } @@ -3238,10 +3241,11 @@ static int should_delete_shared_index(const char *shared_index_path) static int clean_shared_index_files(const char *current_hex) { struct dirent *de; - DIR *dir = opendir(get_git_dir()); + DIR *dir = opendir(repo_get_git_dir(the_repository)); if (!dir) - return error_errno(_("unable to open git dir: %s"), get_git_dir()); + return error_errno(_("unable to open git dir: %s"), + repo_get_git_dir(the_repository)); while ((de = readdir(dir)) != NULL) { const char *sha1_hex; @@ -3331,8 +3335,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) @@ -11,7 +11,7 @@ * The callers that care if (any) rebase is requested should say * if (REBASE_TRUE <= rebase_parse_value(string)) * - * The callers that want to differenciate an unrecognised value and + * The callers that want to differentiate an unrecognised value and * false can do so by treating _INVALID and _FALSE differently. */ enum rebase_type rebase_parse_value(const char *value) diff --git a/ref-filter.c b/ref-filter.c index b6c6c10127..84c6036107 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -13,6 +13,7 @@ #include "object-name.h" #include "object-store-ll.h" #include "oid-array.h" +#include "repo-settings.h" #include "repository.h" #include "commit.h" #include "mailmap.h" @@ -75,11 +76,11 @@ struct refname_atom { int lstrip, rstrip; }; -static struct ref_trailer_buf { +struct ref_trailer_buf { struct string_list filter_list; struct strbuf sepbuf; struct strbuf kvsepbuf; -} ref_trailer_buf = {STRING_LIST_INIT_NODUP, STRBUF_INIT, STRBUF_INIT}; +}; static struct expand_data { struct object_id oid; @@ -201,6 +202,7 @@ static struct used_atom { enum { C_BARE, C_BODY, C_BODY_DEP, C_LENGTH, C_LINES, C_SIG, C_SUB, C_SUB_SANITIZE, C_TRAILERS } option; struct process_trailer_options trailer_opts; + struct ref_trailer_buf *trailer_buf; unsigned int nlines; } contents; struct { @@ -232,7 +234,7 @@ static struct used_atom { enum { S_BARE, S_GRADE, S_SIGNER, S_KEY, S_FINGERPRINT, S_PRI_KEY_FP, S_TRUST_LEVEL } option; } signature; - const char **describe_args; + struct strvec describe_args; struct refname_atom refname; char *head; } u; @@ -566,21 +568,36 @@ static int trailers_atom_parser(struct ref_format *format UNUSED, atom->u.contents.trailer_opts.no_divider = 1; if (arg) { - const char *argbuf = xstrfmt("%s)", arg); + char *argbuf = xstrfmt("%s)", arg); + const char *arg = argbuf; char *invalid_arg = NULL; + struct ref_trailer_buf *tb; + + /* + * Do not inline these directly into the used_atom struct! + * When we parse them in format_set_trailers_options(), + * we will make pointer references directly to them, + * which will not survive a realloc() of the used_atom list. + * They must be allocated in a separate, stable struct. + */ + atom->u.contents.trailer_buf = tb = xmalloc(sizeof(*tb)); + string_list_init_dup(&tb->filter_list); + strbuf_init(&tb->sepbuf, 0); + strbuf_init(&tb->kvsepbuf, 0); if (format_set_trailers_options(&atom->u.contents.trailer_opts, - &ref_trailer_buf.filter_list, - &ref_trailer_buf.sepbuf, - &ref_trailer_buf.kvsepbuf, - &argbuf, &invalid_arg)) { + &tb->filter_list, + &tb->sepbuf, &tb->kvsepbuf, + &arg, &invalid_arg)) { if (!invalid_arg) strbuf_addf(err, _("expected %%(trailers:key=<value>)")); else strbuf_addf(err, _("unknown %%(trailers) argument: %s"), invalid_arg); - free((char *)invalid_arg); + free(invalid_arg); + free(argbuf); return -1; } + free(argbuf); } atom->u.contents.option = C_TRAILERS; return 0; @@ -677,7 +694,7 @@ static int describe_atom_parser(struct ref_format *format UNUSED, struct used_atom *atom, const char *arg, struct strbuf *err) { - struct strvec args = STRVEC_INIT; + strvec_init(&atom->u.describe_args); for (;;) { int found = 0; @@ -686,13 +703,12 @@ static int describe_atom_parser(struct ref_format *format UNUSED, if (!arg || !*arg) break; - found = describe_atom_option_parser(&args, &arg, err); + found = describe_atom_option_parser(&atom->u.describe_args, &arg, err); if (found < 0) return found; if (!found) return err_bad_arg(err, "describe", bad_arg); } - atom->u.describe_args = strvec_detach(&args); return 0; } @@ -986,6 +1002,7 @@ struct ref_formatting_stack { struct ref_formatting_stack *prev; struct strbuf output; void (*at_end)(struct ref_formatting_stack **stack); + void (*at_end_data_free)(void *data); void *at_end_data; }; @@ -1154,6 +1171,8 @@ static void pop_stack_element(struct ref_formatting_stack **stack) if (prev) strbuf_addbuf(&prev->output, ¤t->output); strbuf_release(¤t->output); + if (current->at_end_data_free) + current->at_end_data_free(current->at_end_data); free(current); *stack = prev; } @@ -1213,15 +1232,13 @@ static void if_then_else_handler(struct ref_formatting_stack **stack) } *stack = cur; - free(if_then_else); } static int if_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state, struct strbuf *err UNUSED) { struct ref_formatting_stack *new_stack; - struct if_then_else *if_then_else = xcalloc(1, - sizeof(struct if_then_else)); + struct if_then_else *if_then_else = xcalloc(1, sizeof(*if_then_else)); if_then_else->str = atomv->atom->u.if_then_else.str; if_then_else->cmp_status = atomv->atom->u.if_then_else.cmp_status; @@ -1230,6 +1247,7 @@ static int if_atom_handler(struct atom_value *atomv, struct ref_formatting_state new_stack = state->stack; new_stack->at_end = if_then_else_handler; new_stack->at_end_data = if_then_else; + new_stack->at_end_data_free = free; return 0; } @@ -1833,16 +1851,10 @@ static void find_subpos(const char *buf, size_t *nonsiglen, const char **sig, size_t *siglen) { - struct strbuf payload = STRBUF_INIT; - struct strbuf signature = STRBUF_INIT; const char *eol; const char *end = buf + strlen(buf); const char *sigstart; - /* parse signature first; we might not even have a subject line */ - parse_signature(buf, end - buf, &payload, &signature); - strbuf_release(&payload); - /* skip past header until we hit empty line */ while (*buf && *buf != '\n') { eol = strchrnul(buf, '\n'); @@ -1853,8 +1865,10 @@ static void find_subpos(const char *buf, /* skip any empty lines */ while (*buf == '\n') buf++; - *sig = strbuf_detach(&signature, siglen); + /* parse signature first; we might not even have a subject line */ sigstart = buf + parse_signed_buffer(buf, strlen(buf)); + *sig = sigstart; + *siglen = end - *sig; /* subject is first non-empty line */ *sub = buf; @@ -1929,7 +1943,7 @@ static void grab_describe_values(struct atom_value *val, int deref, cmd.git_cmd = 1; strvec_push(&cmd.args, "describe"); - strvec_pushv(&cmd.args, atom->u.describe_args); + strvec_pushv(&cmd.args, atom->u.describe_args.v); strvec_push(&cmd.args, oid_to_hex(&commit->object.oid)); if (pipe_command(&cmd, NULL, 0, &out, 0, &err, 0) < 0) { error(_("failed to run 'describe'")); @@ -2012,16 +2026,23 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct exp v->s = strbuf_detach(&s, NULL); } else if (atom->u.contents.option == C_TRAILERS) { struct strbuf s = STRBUF_INIT; + const char *msg; + char *to_free = NULL; + + if (siglen) + msg = to_free = xmemdupz(subpos, sigpos - subpos); + else + msg = subpos; /* Format the trailer info according to the trailer_opts given */ - format_trailers_from_commit(&atom->u.contents.trailer_opts, subpos, &s); + format_trailers_from_commit(&atom->u.contents.trailer_opts, msg, &s); + free(to_free); v->s = strbuf_detach(&s, NULL); } else if (atom->u.contents.option == C_BARE) v->s = xstrdup(subpos); } - free((void *)sigpos); } /* @@ -2160,7 +2181,7 @@ static const char *show_ref(struct refname_atom *atom, const char *refname) if (atom->option == R_SHORT) return refs_shorten_unambiguous_ref(get_main_ref_store(the_repository), refname, - warn_ambiguous_refs); + repo_settings_get_warn_ambiguous_refs(the_repository)); else if (atom->option == R_LSTRIP) return lstrip_ref_components(refname, atom->lstrip); else if (atom->option == R_RSTRIP) @@ -2219,7 +2240,7 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname, const char *merge; merge = remote_ref_for_branch(branch, atom->u.remote_ref.push); - *s = xstrdup(merge ? merge : ""); + *s = merge ? merge : xstrdup(""); } else BUG("unhandled RR_* enum"); } @@ -2364,7 +2385,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) CALLOC_ARRAY(ref->value, used_atom_cnt); /** - * NEEDSWORK: The following code might be unncessary if all codepaths + * NEEDSWORK: The following code might be unnecessary if all codepaths * that call populate_value() populates the symref member of ref_array_item * like in apply_ref_filter(). Currently pretty_print_ref() is the only codepath * that calls populate_value() without first populating symref. @@ -2985,6 +3006,19 @@ void ref_array_clear(struct ref_array *array) struct used_atom *atom = &used_atom[i]; if (atom->atom_type == ATOM_HEAD) free(atom->u.head); + else if (atom->atom_type == ATOM_DESCRIBE) + strvec_clear(&atom->u.describe_args); + else if (atom->atom_type == ATOM_TRAILERS || + (atom->atom_type == ATOM_CONTENTS && + atom->u.contents.option == C_TRAILERS)) { + struct ref_trailer_buf *tb = atom->u.contents.trailer_buf; + if (tb) { + string_list_clear(&tb->filter_list, 0); + strbuf_release(&tb->sepbuf); + strbuf_release(&tb->kvsepbuf); + free(tb); + } + } free((char *)atom->name); } FREE_AND_NULL(used_atom); @@ -3210,21 +3244,40 @@ 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) { /* + * 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); } @@ -3282,12 +3335,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; @@ -3590,3 +3637,16 @@ 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 e794b8a676..754038ab07 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -221,4 +221,7 @@ void filter_is_base(struct repository *r, 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 */ @@ -210,7 +210,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 +265,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; } @@ -24,7 +24,7 @@ #include "submodule.h" #include "worktree.h" #include "strvec.h" -#include "repository.h" +#include "repo-settings.h" #include "setup.h" #include "sigchain.h" #include "date.h" @@ -318,9 +318,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 +698,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) { @@ -730,7 +778,7 @@ int expand_ref(struct repository *repo, const char *str, int len, if (r) { if (!refs_found++) *ref = xstrdup(r); - if (!warn_ambiguous_refs) + if (!repo_settings_get_warn_ambiguous_refs(repo)) break; } else if ((flag & REF_ISSYMREF) && strcmp(fullref.buf, "HEAD")) { warning(_("ignoring dangling symref %s"), fullref.buf); @@ -775,7 +823,7 @@ int repo_dwim_log(struct repository *r, const char *str, int len, if (oid) oidcpy(oid, &hash); } - if (!warn_ambiguous_refs) + if (!repo_settings_get_warn_ambiguous_refs(r)) break; } strbuf_release(&path); @@ -918,7 +966,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) || @@ -958,7 +1006,8 @@ static char *normalize_reflog_message(const char *msg) return strbuf_detach(&sb, NULL); } -int should_autocreate_reflog(const char *refname) +int should_autocreate_reflog(enum log_refs_config log_all_ref_updates, + const char *refname) { switch (log_all_ref_updates) { case LOG_REFS_ALWAYS: @@ -1115,6 +1164,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; @@ -1122,6 +1172,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; } @@ -1185,8 +1236,9 @@ 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->msg = normalize_reflog_message(msg); - update->msg = normalize_reflog_message(msg); return update; } @@ -1308,7 +1360,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) || @@ -1787,7 +1839,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); @@ -2115,19 +2167,53 @@ 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); @@ -2184,6 +2270,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)) @@ -2312,7 +2401,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; } @@ -2321,6 +2410,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; @@ -2329,8 +2419,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; /* @@ -2360,7 +2448,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); @@ -2385,21 +2474,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; - if (ok != ITER_DONE) - BUG("error while iterating over references"); + 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"); + } extra_refname = find_descendant_ref(dirname.buf, extras, skip); if (extra_refname) @@ -2483,14 +2577,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) @@ -2526,7 +2612,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; @@ -2832,7 +2918,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; @@ -2857,13 +2944,6 @@ 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. - */ ret = ref_transaction_commit(transaction, errbuf); if (ret < 0) goto done; @@ -2947,4 +3027,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); } - @@ -3,6 +3,7 @@ #include "commit.h" #include "repository.h" +#include "repo-settings.h" struct fsck_options; struct object_id; @@ -16,7 +17,7 @@ enum ref_storage_format ref_storage_format_by_name(const char *name); const char *ref_storage_format_to_name(enum ref_storage_format ref_storage_format); /* - * Resolve a reference, recursively following symbolic refererences. + * Resolve a reference, recursively following symbolic references. * * Return the name of the non-symbolic reference that ultimately pointed * at the resolved object name. The return value, if not NULL, is a @@ -82,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); @@ -100,18 +112,22 @@ 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); -int should_autocreate_reflog(const char *refname); +int should_autocreate_reflog(enum log_refs_config log_all_ref_updates, + const char *refname); int is_branch(const char *refname); @@ -179,6 +195,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. * @@ -212,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. @@ -232,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(...) || @@ -488,7 +531,7 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname); * from UTC. Its absolute value is formed by multiplying the hour * part by 100 and adding the minute part. For example, 1 hour ahead * of UTC, CET == "+0100", is represented as positive one hundred (not - * postiive sixty). + * positive sixty). * * The msg parameter is a single complete line; a reflog message given * to refs_delete_ref, refs_update_ref, etc. is returned to the @@ -547,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 @@ -571,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); /* @@ -756,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 @@ -796,20 +862,6 @@ 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 * `NULL` pointers depending on whether the update has these object IDs set or @@ -995,7 +1047,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt); /* * Some of the names specified by refs have special meaning to Git. - * Organize these namespaces in a comon 'ref_namespace' array for + * Organize these namespaces in a common 'ref_namespace' array for * reference from multiple places in the codebase. */ diff --git a/refs/debug.c b/refs/debug.c index 45e2e784a0..a893ae0c90 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -118,18 +118,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 +408,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 +432,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 c7f3f4e591..4e3545de49 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -1,4 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "../git-compat-util.h" +#include "../abspath.h" +#include "../config.h" #include "../copy.h" #include "../environment.h" #include "../gettext.h" @@ -6,6 +10,7 @@ #include "../hex.h" #include "../fsck.h" #include "../refs.h" +#include "../repo-settings.h" #include "refs-internal.h" #include "ref-cache.h" #include "packed-backend.h" @@ -19,6 +24,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" @@ -72,6 +78,8 @@ struct files_ref_store { unsigned int store_flags; char *gitcommondir; + enum log_refs_config log_all_ref_updates; + int prefer_symlink_refs; struct ref_cache *loose; @@ -104,6 +112,8 @@ static struct ref_store *files_ref_store_init(struct repository *repo, refs->gitcommondir = strbuf_detach(&sb, NULL); refs->packed_ref_store = packed_ref_store_init(repo, refs->gitcommondir, flags); + refs->log_all_ref_updates = repo_settings_get_log_all_ref_updates(repo); + repo_config_get_bool(repo, "core.prefersymlinkrefs", &refs->prefer_symlink_refs); chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir); chdir_notify_reparent("files-backend $GIT_COMMONDIR", @@ -560,7 +570,7 @@ stat_ref: 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) @@ -588,16 +598,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)) { @@ -619,6 +628,10 @@ int parse_loose_ref_contents(const struct git_hash_algo *algop, *failure_errno = EINVAL; return -1; } + + if (trailing) + *trailing = p; + return 0; } @@ -698,7 +711,7 @@ retry: * 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 @@ -805,7 +818,7 @@ retry: 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. @@ -842,7 +855,7 @@ retry: */ if (refs_verify_refname_available( refs->packed_ref_store, refname, - extras, NULL, err)) { + extras, NULL, 0, err)) { ret = TRANSACTION_NAME_CONFLICT; goto error_return; } @@ -1151,7 +1164,7 @@ 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); @@ -1244,7 +1257,7 @@ 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( @@ -1388,7 +1401,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; @@ -1506,6 +1520,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs, static int commit_ref_update(struct files_ref_store *refs, struct ref_lock *lock, const struct object_id *oid, const char *logmsg, + int flags, struct strbuf *err); /* @@ -1528,7 +1543,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); @@ -1649,7 +1664,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, oidcpy(&lock->old_oid, &orig_oid); if (write_ref_to_lockfile(refs, lock, &orig_oid, 0, &err) || - commit_ref_update(refs, lock, &orig_oid, logmsg, &err)) { + commit_ref_update(refs, lock, &orig_oid, logmsg, 0, &err)) { error("unable to write current sha1 into %s: %s", newrefname, err.buf); strbuf_release(&err); goto rollback; @@ -1666,14 +1681,11 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store, goto rollbacklog; } - flag = log_all_ref_updates; - log_all_ref_updates = LOG_REFS_NONE; if (write_ref_to_lockfile(refs, lock, &orig_oid, 0, &err) || - commit_ref_update(refs, lock, &orig_oid, NULL, &err)) { + commit_ref_update(refs, lock, &orig_oid, NULL, REF_SKIP_CREATE_REFLOG, &err)) { error("unable to write current sha1 into %s: %s", oldrefname, err.buf); strbuf_release(&err); } - log_all_ref_updates = flag; rollbacklog: if (logmoved && rename(sb_newref.buf, sb_oldref.buf)) @@ -1768,13 +1780,17 @@ static int log_ref_setup(struct files_ref_store *refs, const char *refname, int force_create, int *logfd, struct strbuf *err) { + enum log_refs_config log_refs_cfg = refs->log_all_ref_updates; struct strbuf logfile_sb = STRBUF_INIT; char *logfile; + if (log_refs_cfg == LOG_REFS_UNSET) + log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + files_reflog_path(refs, &logfile_sb, refname); logfile = strbuf_detach(&logfile_sb, NULL); - if (force_create || should_autocreate_reflog(refname)) { + if (force_create || should_autocreate_reflog(log_refs_cfg, refname)) { if (raceproof_create_file(logfile, open_or_create_logfile, logfd)) { if (errno == ENOENT) strbuf_addf(err, "unable to create directory for '%s': " @@ -1863,9 +1879,6 @@ static int files_log_ref_write(struct files_ref_store *refs, if (flags & REF_SKIP_CREATE_REFLOG) return 0; - if (log_all_ref_updates == LOG_REFS_UNSET) - log_all_ref_updates = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; - result = log_ref_setup(refs, refname, flags & REF_FORCE_CREATE_REFLOG, &logfd, err); @@ -1954,6 +1967,7 @@ static int write_ref_to_lockfile(struct files_ref_store *refs, static int commit_ref_update(struct files_ref_store *refs, struct ref_lock *lock, const struct object_id *oid, const char *logmsg, + int flags, struct strbuf *err) { files_assert_main_repository(refs, "commit_ref_update"); @@ -1961,7 +1975,7 @@ static int commit_ref_update(struct files_ref_store *refs, clear_loose_ref_cache(refs); if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, oid, - logmsg, 0, err)) { + logmsg, flags, err)) { char *old_msg = strbuf_detach(err, NULL); strbuf_addf(err, "cannot update the ref '%s': %s", lock->ref_name, old_msg); @@ -1994,7 +2008,7 @@ static int commit_ref_update(struct files_ref_store *refs, struct strbuf log_err = STRBUF_INIT; if (files_log_ref_write(refs, "HEAD", &lock->old_oid, oid, - logmsg, 0, &log_err)) { + logmsg, flags, &log_err)) { error("%s", log_err.buf); strbuf_release(&log_err); } @@ -2494,14 +2508,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", @@ -2514,7 +2532,7 @@ 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; } /* @@ -2594,9 +2612,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 { /* @@ -2627,9 +2647,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; + } } /* @@ -2772,6 +2794,8 @@ 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; @@ -2859,7 +2883,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; @@ -2965,6 +2990,127 @@ 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++) + 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 and root refs, so we + * have to queue these references via the loose transaction. + */ + if (update->new_target || is_root_ref(update->refname)) { + if (!loose_transaction) { + loose_transaction = ref_store_transaction_begin(&refs->base, 0, err); + if (!loose_transaction) { + ret = TRANSACTION_GENERIC_ERROR; + goto cleanup; + } + } + + 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, NULL); + } else { + 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) || + 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) @@ -2980,6 +3126,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; @@ -3005,7 +3153,7 @@ static int files_transaction_finish(struct ref_store *ref_store, * We try creating a symlink, if that succeeds we continue to the * next update. If not, we try and create a regular symref. */ - if (update->new_target && prefer_symlink_refs) + if (update->new_target && refs->prefer_symlink_refs) if (!create_ref_symlink(lock, update->new_target)) continue; @@ -3113,106 +3261,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; @@ -3493,12 +3541,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; @@ -3511,11 +3700,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"); @@ -3529,8 +3720,10 @@ cleanup: 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; @@ -3549,11 +3742,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 { @@ -3570,30 +3770,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 = { @@ -3606,7 +3810,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/packed-backend.c b/refs/packed-backend.c index 07c57fd541..3406f1e71d 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -13,6 +13,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 +1731,6 @@ cleanup: 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 +1748,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 +1768,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 35bae7e05d..02f09e4df8 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 2313c830d8..66e66e0fc1 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -193,6 +193,7 @@ struct ref_transaction { size_t nr; enum ref_transaction_state state; void *backend_data; + unsigned int flags; }; /* @@ -653,7 +654,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 +667,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 +674,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 +721,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 9c2c695b13..8a2a5b847c 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -15,13 +15,16 @@ #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" #include "../reftable/reftable-iterator.h" +#include "../repo-settings.h" #include "../setup.h" #include "../strmap.h" #include "../trace2.h" +#include "../write-or-die.h" #include "parse.h" #include "refs-internal.h" @@ -31,27 +34,115 @@ */ #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; + enum log_refs_config log_all_ref_updates; int err; }; @@ -93,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 @@ -121,58 +216,74 @@ 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 ref_store *refs, const char *refname) +static int should_write_log(struct reftable_ref_store *refs, const char *refname) { - if (log_all_ref_updates == LOG_REFS_UNSET) - log_all_ref_updates = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; + enum log_refs_config log_refs_cfg = refs->log_all_ref_updates; + if (log_refs_cfg == LOG_REFS_UNSET) + log_refs_cfg = is_bare_repository() ? LOG_REFS_NONE : LOG_REFS_NORMAL; - switch (log_all_ref_updates) { + switch (log_refs_cfg) { case LOG_REFS_NONE: - return refs_reflog_exists(refs, refname); + return refs_reflog_exists(&refs->base, refname); case LOG_REFS_ALWAYS: return 1; case LOG_REFS_NORMAL: - if (should_autocreate_reflog(refname)) + if (should_autocreate_reflog(log_refs_cfg, refname)) return 1; - return refs_reflog_exists(refs, refname); + return refs_reflog_exists(&refs->base, refname); default: - BUG("unhandled core.logAllRefUpdates value %d", log_all_ref_updates); + BUG("unhandled core.logAllRefUpdates value %d", log_refs_cfg); } } @@ -202,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) @@ -257,11 +336,23 @@ static int reftable_be_config(const char *var, const char *value, if (factor > UINT8_MAX) die("reftable geometric factor cannot exceed %u", (unsigned)UINT8_MAX); opts->auto_compaction_factor = factor; + } else if (!strcmp(var, "reftable.locktimeout")) { + int64_t lock_timeout = git_config_int64(var, value, ctx->kvi); + if (lock_timeout > LONG_MAX) + die("reftable lock timeout cannot exceed %"PRIdMAX, (intmax_t)LONG_MAX); + if (lock_timeout < 0 && lock_timeout != -1) + die("reftable lock timeout does not support negative values other than -1"); + opts->lock_timeout_ms = lock_timeout; } 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) @@ -275,13 +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; + 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(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); @@ -308,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; @@ -325,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; } @@ -345,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, @@ -752,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); /* @@ -760,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); @@ -782,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) { @@ -809,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; } @@ -834,7 +936,7 @@ 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; @@ -869,27 +971,38 @@ 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) strbuf_addstr(err, "cannot lock references"); @@ -900,7 +1013,7 @@ 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; @@ -955,6 +1068,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; @@ -1001,8 +1115,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; @@ -1010,10 +1139,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) && @@ -1069,8 +1206,8 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store, 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)) { @@ -1084,7 +1221,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; @@ -1193,10 +1332,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"), @@ -1208,7 +1350,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; } @@ -1271,7 +1412,7 @@ static int transaction_update_cmp(const void *a, const void *b) 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; @@ -1307,7 +1448,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data struct reftable_log_record log = {0}; struct reftable_iterator it = {0}; - ret = reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->be->stack, &it); if (ret < 0) goto done; @@ -1347,7 +1488,7 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data } else if (!(u->flags & REF_SKIP_CREATE_REFLOG) && (u->flags & REF_HAVE_NEW) && (u->flags & REF_FORCE_CREATE_REFLOG || - should_write_log(&arg->refs->base, u->refname))) { + should_write_log(arg->refs, u->refname))) { struct reftable_log_record *log; int create_reflog = 1; @@ -1477,13 +1618,6 @@ done: 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) { @@ -1495,9 +1629,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); @@ -1528,7 +1662,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; @@ -1553,7 +1687,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; } @@ -1578,7 +1712,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; @@ -1592,7 +1726,7 @@ 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); @@ -1635,8 +1769,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); @@ -1679,7 +1813,7 @@ 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. */ - ret = reftable_stack_init_log_iterator(arg->stack, &it); + ret = reftable_stack_init_log_iterator(arg->be->stack, &it); if (ret < 0) goto done; @@ -1752,10 +1886,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, @@ -1767,10 +1899,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); @@ -1784,10 +1916,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, @@ -1798,10 +1928,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); @@ -1922,11 +2052,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); @@ -1965,15 +2095,23 @@ 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; - ret = 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; @@ -2005,16 +2143,24 @@ 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; - ret = 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; @@ -2054,20 +2200,20 @@ 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(stack, &it); + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; @@ -2118,7 +2264,7 @@ static int write_reflog_existence_table(struct reftable_writer *writer, reftable_writer_set_limits(writer, ts, ts); /* - * 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. */ @@ -2139,10 +2285,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; @@ -2151,11 +2296,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; @@ -2213,17 +2359,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; @@ -2322,26 +2469,27 @@ 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; - ret = reftable_stack_init_log_iterator(stack, &it); + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; @@ -2349,16 +2497,13 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_new_addition(&add, stack); + 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) { @@ -2425,15 +2570,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) @@ -2451,18 +2595,19 @@ done: 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; } @@ -2477,7 +2622,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, @@ -153,6 +153,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 +168,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 +181,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; + rs->items[rs->nr] = item; - ALLOC_GROW(rs->raw, rs->raw_nr + 1, rs->raw_alloc); - rs->raw[rs->raw_nr++] = refspec; -} - -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 +224,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; } @@ -26,6 +26,8 @@ struct refspec_item { char *src; char *dst; + + char *raw; }; #define REFSPEC_FETCH 1 @@ -43,10 +45,6 @@ struct refspec { int alloc; int nr; - const char **raw; - int raw_alloc; - int raw_nr; - int fetch; }; diff --git a/reftable/basics.c b/reftable/basics.c index eab5553d93..70b1091d14 100644 --- a/reftable/basics.c +++ b/reftable/basics.c @@ -9,6 +9,7 @@ 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); @@ -76,6 +77,79 @@ void reftable_set_alloc(void *(*malloc)(size_t), 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) { + char *reallocated = buf->buf; + REFTABLE_ALLOC_GROW(reallocated, newlen + 1, buf->alloc); + if (!reallocated) + return REFTABLE_OUT_OF_MEMORY_ERROR; + buf->buf = reallocated; + } + + 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) { out[0] = (uint8_t)((i >> 16) & 0xff); @@ -193,7 +267,7 @@ int names_equal(const char **a, const char **b) return a[i] == b[i]; } -int common_prefix_size(struct strbuf *a, struct strbuf *b) +int common_prefix_size(struct reftable_buf *a, struct reftable_buf *b) { int p = 0; for (; p < a->len && p < b->len; p++) { @@ -204,14 +278,15 @@ int common_prefix_size(struct strbuf *a, struct strbuf *b) return p; } -int hash_size(uint32_t id) +int hash_size(enum reftable_hash id) { + if (!id) + return REFTABLE_HASH_SIZE_SHA1; switch (id) { - case 0: - case GIT_SHA1_FORMAT_ID: - return GIT_SHA1_RAWSZ; - case GIT_SHA256_FORMAT_ID: - return GIT_SHA256_RAWSZ; + 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 4c9ef0fe6c..36beda2c25 100644 --- a/reftable/basics.h +++ b/reftable/basics.h @@ -16,6 +16,64 @@ https://developers.google.com/open-source/licenses/bsd #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 */ void put_be24(uint8_t *out, uint32_t i); @@ -88,9 +146,16 @@ char *reftable_strdup(const char *str); #endif /* Find the longest shared prefix size of `a` and `b` */ -struct strbuf; -int common_prefix_size(struct strbuf *a, struct strbuf *b); +int common_prefix_size(struct reftable_buf *a, struct reftable_buf *b); -int hash_size(uint32_t id); +int 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 8d41a2f99e..0198078485 100644 --- a/reftable/block.c +++ b/reftable/block.c @@ -38,9 +38,11 @@ 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; + int rlen, err; + + rlen = w->restart_len; if (rlen >= MAX_RESTARTS) { is_restart = 0; } @@ -59,20 +61,23 @@ static int block_writer_register_restart(struct block_writer *w, int n, 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; } -int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf, +int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *block, uint32_t block_size, uint32_t header_off, int 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; @@ -90,7 +95,7 @@ int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf, 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 @@ -98,42 +103,45 @@ 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; - reftable_record_key(rec, &key); - if (!key.len) { + err = reftable_record_key(rec, &w->scratch); + if (err < 0) + goto done; + + 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; } @@ -141,13 +149,13 @@ 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]); + 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 @@ -176,7 +184,7 @@ int block_writer_finish(struct block_writer *w) 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; /* @@ -194,7 +202,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; } @@ -325,7 +333,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 = { @@ -334,7 +342,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) @@ -355,13 +363,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; }; @@ -433,7 +441,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; @@ -442,12 +450,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, @@ -522,6 +530,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 @@ -536,8 +548,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; } @@ -554,7 +565,8 @@ void block_writer_release(struct block_writer *bw) REFTABLE_FREE_AND_NULL(bw->zstream); REFTABLE_FREE_AND_NULL(bw->restarts); REFTABLE_FREE_AND_NULL(bw->compressed); - strbuf_release(&bw->last_key); + 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 18d7ea0337..0431e8591f 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. */ @@ -38,14 +38,16 @@ 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. */ -int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *buf, + * 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, int hash_size); /* returns the block type (eg. 'r' for ref records. */ @@ -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 { @@ -109,13 +111,13 @@ struct block_iter { int 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); diff --git a/reftable/blocksource.c b/reftable/blocksource.c index a2a6a196d5..52e0915a67 100644 --- a/reftable/blocksource.c +++ b/reftable/blocksource.c @@ -13,21 +13,21 @@ https://developers.google.com/open-source/licenses/bsd #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 int 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) @@ -37,23 +37,23 @@ static int strbuf_read_block(void *v, struct reftable_block *dest, uint64_t off, 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; } diff --git a/reftable/blocksource.h b/reftable/blocksource.h index 659a27b406..a84a3ccd89 100644 --- a/reftable/blocksource.h +++ b/reftable/blocksource.h @@ -12,9 +12,10 @@ https://developers.google.com/open-source/licenses/bsd #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/iter.c b/reftable/iter.c index d926db653b..86e801ca9f 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) @@ -197,7 +197,10 @@ int indexed_table_ref_iter_new(struct indexed_table_ref_iter **dest, *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; diff --git a/reftable/iter.h b/reftable/iter.h index b3225bc7ad..40f98893b8 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,7 +75,7 @@ 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, diff --git a/reftable/merged.c b/reftable/merged.c index 5ff4bc35c2..e72b39e178 100644 --- a/reftable/merged.c +++ b/reftable/merged.c @@ -66,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); @@ -181,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; @@ -295,7 +297,7 @@ int reftable_merged_table_init_log_iterator(struct reftable_merged_table *mt, 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 89bd0c4b35..0b7d939e92 100644 --- a/reftable/merged.h +++ b/reftable/merged.h @@ -10,11 +10,12 @@ https://developers.google.com/open-source/licenses/bsd #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. */ diff --git a/reftable/reader.c b/reftable/reader.c index 8d37253922..ea82955c9b 100644 --- a/reftable/reader.c +++ b/reftable/reader.c @@ -67,7 +67,7 @@ static int reader_get_block(struct reftable_reader *r, return block_source_read_block(&r->source, dest, off, sz); } -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 +107,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 +352,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 +405,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 +426,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 +435,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 @@ -765,7 +771,10 @@ static int reftable_reader_refs_for_unindexed(struct reftable_reader *r, } *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); diff --git a/reftable/reader.h b/reftable/reader.h index 02d10c5d37..d2b48a4849 100644 --- a/reftable/reader.h +++ b/reftable/reader.h @@ -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; diff --git a/reftable/record.c b/reftable/record.c index 30d563e16d..fb5652ed57 100644 --- a/reftable/record.c +++ b/reftable/record.c @@ -98,19 +98,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; @@ -133,7 +138,7 @@ 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; @@ -183,13 +188,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,19 +205,25 @@ 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 int reftable_ref_record_copy_from(void *rec, const void *src_rec, @@ -350,9 +361,9 @@ 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) + int hash_size, struct reftable_buf *scratch) { struct reftable_ref_record *r = rec; struct string_view start = in; @@ -415,7 +426,7 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key, 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: @@ -465,12 +476,12 @@ 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) @@ -547,10 +558,10 @@ 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) + struct reftable_buf *scratch UNUSED) { struct string_view start = in; struct reftable_obj_record *r = rec; @@ -664,19 +675,27 @@ 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 int reftable_log_record_copy_from(void *rec, const void *src_rec, @@ -807,9 +826,9 @@ 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) + int hash_size, struct reftable_buf *scratch) { struct string_view start = in; struct reftable_log_record *r = rec; @@ -1027,11 +1046,11 @@ 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 int reftable_index_record_copy_from(void *rec, const void *src_rec, @@ -1039,9 +1058,12 @@ static int reftable_index_record_copy_from(void *rec, const void *src_rec, { 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; @@ -1050,7 +1072,7 @@ static int reftable_index_record_copy_from(void *rec, const void *src_rec, 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) @@ -1074,18 +1096,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) + 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) @@ -1101,14 +1125,14 @@ static int reftable_index_record_equal(const void *a, const void *b, 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 = { @@ -1124,9 +1148,9 @@ 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, @@ -1151,9 +1175,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, +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) + struct reftable_buf *scratch) { return reftable_record_vtable(rec)->decode(reftable_record_data(rec), key, extra, src, hash_size, @@ -1294,7 +1318,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 0f53ba5443..25aa908c85 100644 --- a/reftable/record.h +++ b/reftable/record.h @@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd #ifndef RECORD_H #define RECORD_H +#include "basics.h" #include "system.h" #include <stdint.h> @@ -38,8 +39,8 @@ 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; @@ -54,9 +55,9 @@ struct reftable_record_vtable { int (*encode)(const void *rec, struct string_view dest, int hash_size); /* decode data from `src` into the record. */ - int (*decode)(void *rec, struct strbuf key, uint8_t extra, + int (*decode)(void *rec, struct reftable_buf key, uint8_t extra, struct string_view src, int hash_size, - struct strbuf *scratch); + struct reftable_buf *scratch); /* deallocate and null the record. */ void (*release)(void *rec); @@ -83,7 +84,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 +97,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. */ @@ -136,15 +137,15 @@ 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); +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, int 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, +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); + int 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 index 6e8e636b71..e0397ed583 100644 --- a/reftable/reftable-basics.h +++ b/reftable/reftable-basics.h @@ -11,6 +11,19 @@ #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 *)); diff --git a/reftable/reftable-merged.h b/reftable/reftable-merged.h index a970d5dd89..f2d01c3ef8 100644 --- a/reftable/reftable-merged.h +++ b/reftable/reftable-merged.h @@ -34,7 +34,7 @@ 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. */ int reftable_merged_table_init_ref_iterator(struct reftable_merged_table *mt, @@ -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 6a2d0b693f..0085fbb903 100644 --- a/reftable/reftable-reader.h +++ b/reftable/reftable-reader.h @@ -54,7 +54,7 @@ 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 2d42463c58..ddd48eb579 100644 --- a/reftable/reftable-record.h +++ b/reftable/reftable-record.h @@ -9,7 +9,7 @@ https://developers.google.com/open-source/licenses/bsd #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; @@ -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; diff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h index e958f911b4..ae14270ea7 100644 --- a/reftable/reftable-stack.h +++ b/reftable/reftable-stack.h @@ -37,12 +37,21 @@ uint64_t reftable_stack_next_update_index(struct reftable_stack *st); /* holds a transaction to add tables at the top of a stack. */ struct reftable_addition; +enum { + /* + * Reload the stack when the stack is out-of-date after locking it. + */ + REFTABLE_STACK_NEW_ADDITION_RELOAD = (1 << 0), +}; + /* * returns a new transaction to add reftables to the given stack. As a side - * effect, the ref database is locked. + * effect, the ref database is locked. Accepts REFTABLE_STACK_NEW_ADDITION_* + * flags. */ int reftable_stack_new_addition(struct reftable_addition **dest, - struct reftable_stack *st); + struct reftable_stack *st, + unsigned int flags); /* Adds a reftable to transaction. */ int reftable_addition_add(struct reftable_addition *add, @@ -140,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 43623dc7c3..5f9afa620b 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; @@ -51,6 +51,32 @@ struct reftable_write_options { * tables to compact. Defaults to 2 if unset. */ uint8_t auto_compaction_factor; + + /* + * The number of milliseconds to wait when trying to lock "tables.list". + * Note that this does not apply to locking individual tables, as these + * should only ever be locked when already holding the "tables.list" + * lock. + * + * Passing 0 will fail immediately when the file is locked, passing a + * 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 */ diff --git a/reftable/stack.c b/reftable/stack.c index f51d3ec9d9..634f0c5425 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -8,7 +8,6 @@ https://developers.google.com/open-source/licenses/bsd #include "stack.h" -#include "../write-or-die.h" #include "system.h" #include "constants.h" #include "merged.h" @@ -17,7 +16,6 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable-record.h" #include "reftable-merged.h" #include "writer.h" -#include "tempfile.h" static int stack_try_add(struct reftable_stack *st, int (*write_table)(struct reftable_writer *wr, @@ -31,32 +29,46 @@ 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 strbuf list_file_name = STRBUF_INIT; + struct reftable_buf list_file_name = REFTABLE_BUF_INIT; struct reftable_write_options opts = { 0 }; struct reftable_stack *p; int err; @@ -70,15 +82,16 @@ int reftable_new_stack(struct reftable_stack **dest, const char *dir, 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->opts = opts; p->reftable_dir = reftable_strdup(dir); @@ -208,21 +221,24 @@ void reftable_stack_destroy(struct reftable_stack *st) if (st->readers) { int i = 0; - struct strbuf filename = STRBUF_INIT; + struct reftable_buf filename = REFTABLE_BUF_INIT; for (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; REFTABLE_FREE_AND_NULL(st->readers); } @@ -260,7 +276,7 @@ static int reftable_stack_reload_once(struct reftable_stack *st, 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; @@ -314,7 +330,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); @@ -345,7 +364,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); } @@ -378,7 +401,7 @@ done: reftable_free(new_readers); reftable_free(reused); reftable_free(cur); - strbuf_release(&table_path); + reftable_buf_release(&table_path); return err; } @@ -529,6 +552,10 @@ out: 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; } @@ -627,18 +654,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(); 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; @@ -649,15 +676,16 @@ struct reftable_addition { #define REFTABLE_ADDITION_INIT {0} static int reftable_stack_init_addition(struct reftable_addition *add, - struct reftable_stack *st) + 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(&add->tables_list_lock, st->list_file, - LOCK_NO_DEREF); + 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; @@ -667,7 +695,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; @@ -677,6 +705,11 @@ static int reftable_stack_init_addition(struct reftable_addition *add, err = stack_uptodate(st); if (err < 0) goto done; + if (err > 0 && flags & REFTABLE_STACK_NEW_ADDITION_RELOAD) { + err = reftable_stack_reload_maybe_reuse(add->stack, 1); + if (err) + goto done; + } if (err > 0) { err = REFTABLE_OUTDATED_ERROR; goto done; @@ -684,21 +717,20 @@ static int reftable_stack_init_addition(struct reftable_addition *add, add->next_update_index = reftable_stack_next_update_index(st); done: - if (err) { + 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; } @@ -707,8 +739,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) @@ -722,8 +754,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; @@ -731,28 +762,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; @@ -790,7 +823,8 @@ done: } int reftable_stack_new_addition(struct reftable_addition **dest, - struct reftable_stack *st) + struct reftable_stack *st, + unsigned int flags) { int err = 0; struct reftable_addition empty = REFTABLE_ADDITION_INIT; @@ -800,7 +834,7 @@ int reftable_stack_new_addition(struct reftable_addition **dest, return REFTABLE_OUT_OF_MEMORY_ERROR; **dest = empty; - err = reftable_stack_init_addition(*dest, st); + err = reftable_stack_init_addition(*dest, st, flags); if (err) { reftable_free(*dest); *dest = NULL; @@ -814,7 +848,7 @@ static int stack_try_add(struct reftable_stack *st, void *arg) { struct reftable_addition add = REFTABLE_ADDITION_INIT; - int err = reftable_stack_init_addition(&add, st); + int err = reftable_stack_init_addition(&add, st, 0); if (err < 0) goto done; @@ -833,36 +867,44 @@ 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); - err = reftable_writer_new(&wr, 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; @@ -878,30 +920,34 @@ 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(add->new_tables, add->new_tables_len + 1, add->new_tables_cap); @@ -909,13 +955,13 @@ int reftable_addition_add(struct reftable_addition *add, err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; } - add->new_tables[add->new_tables_len++] = strbuf_detach(&next_name, NULL); + add->new_tables[add->new_tables_len++] = reftable_buf_detach(&next_name); 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; } @@ -932,35 +978,43 @@ 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; } - err = reftable_writer_new(&wr, 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; @@ -972,18 +1026,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; } @@ -1107,13 +1161,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; @@ -1130,8 +1184,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(&tables_list_lock, st->list_file, - LOCK_NO_DEREF); + err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) err = REFTABLE_LOCK_ERROR; @@ -1154,17 +1207,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 @@ -1200,7 +1256,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; @@ -1212,7 +1268,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; @@ -1235,8 +1291,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(&tables_list_lock, st->list_file, - LOCK_NO_DEREF); + err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); if (err < 0) { if (errno == EEXIST) err = REFTABLE_LOCK_ERROR; @@ -1246,7 +1301,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; @@ -1362,16 +1417,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; - } } /* @@ -1379,14 +1440,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; @@ -1394,14 +1464,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); @@ -1422,23 +1492,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); - reftable_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) @@ -1537,7 +1612,7 @@ 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; @@ -1655,8 +1730,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) @@ -1673,7 +1751,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) @@ -1708,7 +1786,7 @@ static int reftable_stack_clean_locked(struct reftable_stack *st) int reftable_stack_clean(struct reftable_stack *st) { struct reftable_addition *add = NULL; - int err = reftable_stack_new_addition(&add, st); + int err = reftable_stack_new_addition(&add, st, 0); if (err < 0) { goto done; } @@ -1724,3 +1802,8 @@ done: 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 0000000000..adf8e4d30b --- /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 d0cabd5d17..7d5f803eeb 100644 --- a/reftable/system.h +++ b/reftable/system.h @@ -12,12 +12,90 @@ https://developers.google.com/open-source/licenses/bsd /* 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.*/ -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/writer.c b/reftable/writer.c index b032a47dec..9efeab13e1 100644 --- a/reftable/writer.c +++ b/reftable/writer.c @@ -79,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; @@ -88,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; } @@ -103,8 +103,22 @@ 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)); } @@ -115,7 +129,7 @@ static int writer_reinit_block_writer(struct reftable_writer *w, uint8_t typ) if (w->next == 0) block_start = header_size(writer_version(w)); - strbuf_reset(&w->last_key); + 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)); @@ -146,8 +160,9 @@ int reftable_writer_new(struct reftable_writer **out, 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); @@ -179,7 +194,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); } } @@ -190,7 +206,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; @@ -198,16 +214,16 @@ 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 int 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 }; @@ -217,6 +233,7 @@ static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash) 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; + int err; key = reftable_malloc(sizeof(*key)); if (!key) @@ -224,8 +241,10 @@ static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash) *key = empty; - strbuf_reset(&key->hash); - strbuf_addbuf(&key->hash, hash); + 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 { @@ -246,17 +265,22 @@ static int writer_index_hash(struct reftable_writer *w, struct strbuf *hash) 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); + 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) @@ -303,7 +327,6 @@ static int writer_add_record(struct reftable_writer *w, } done: - strbuf_release(&key); return err; } @@ -316,7 +339,6 @@ int reftable_writer_add_ref(struct reftable_writer *w, .ref = *ref }, }; - struct strbuf buf = STRBUF_INIT; int err; if (!ref->refname || @@ -331,20 +353,25 @@ int reftable_writer_add_ref(struct reftable_writer *w, goto out; if (!w->opts.skip_index_objects && reftable_ref_record_val1(ref)) { - strbuf_add(&buf, (char *)reftable_ref_record_val1(ref), - hash_size(w->opts.hash_id)); + 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, &buf); + err = writer_index_hash(w, &w->scratch); if (err < 0) goto out; } if (!w->opts.skip_index_objects && reftable_ref_record_val2(ref)) { - strbuf_reset(&buf); - strbuf_add(&buf, reftable_ref_record_val2(ref), - hash_size(w->opts.hash_id)); + 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, &buf); + err = writer_index_hash(w, &w->scratch); if (err < 0) goto out; } @@ -352,7 +379,6 @@ int reftable_writer_add_ref(struct reftable_writer *w, err = 0; out: - strbuf_release(&buf); return err; } @@ -393,7 +419,7 @@ 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) @@ -404,24 +430,34 @@ int reftable_writer_add_log(struct reftable_writer *w, 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; } @@ -504,7 +540,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); } @@ -521,13 +557,13 @@ 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; + struct reftable_buf *last; int max; }; @@ -594,7 +630,7 @@ static void object_record_free(void *void_arg UNUSED, void *key) struct obj_index_tree_node *entry = key; REFTABLE_FREE_AND_NULL(entry->offsets); - strbuf_release(&entry->hash); + reftable_buf_release(&entry->hash); reftable_free(entry); } @@ -708,7 +744,7 @@ done: 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); + reftable_buf_release(&w->index[i].last_key); REFTABLE_FREE_AND_NULL(w->index); w->index_len = 0; w->index_cap = 0; @@ -717,7 +753,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; @@ -777,8 +813,11 @@ static int writer_flush_nonempty_block(struct reftable_writer *w) 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 8d0df9cc52..1f4788a430 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 4adcf25ed6..9a71e04301 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -347,7 +347,7 @@ static struct ref *parse_info_refs(struct discovery *heads) ref->next = refs; refs = ref; } else { - free(ref); + free_one_ref(ref); } return refs; @@ -24,6 +24,7 @@ #include "advice.h" #include "connect.h" #include "parse-options.h" +#include "transport.h" enum map_direction { FROM_SRC, FROM_DST }; @@ -143,6 +144,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 +168,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) @@ -508,6 +511,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; } @@ -632,7 +656,7 @@ const char *pushremote_for_branch(struct branch *branch, int *explicit) static struct remote *remotes_remote_get(struct remote_state *remote_state, const char *name); -const char *remote_ref_for_branch(struct branch *branch, int for_push) +char *remote_ref_for_branch(struct branch *branch, int for_push) { read_config(the_repository, 0); die_on_missing_branch(the_repository, branch); @@ -640,11 +664,11 @@ const char *remote_ref_for_branch(struct branch *branch, int for_push) if (branch) { if (!for_push) { if (branch->merge_nr) { - return branch->merge_name[0]; + return xstrdup(branch->merge_name[0]); } } else { - const char *dst, - *remote_name = remotes_pushremote_for_branch( + char *dst; + const char *remote_name = remotes_pushremote_for_branch( the_repository->remote_state, branch, NULL); struct remote *remote = remotes_remote_get( @@ -868,6 +892,20 @@ struct strvec *push_url_of_remote(struct remote *remote) return remote->pushurl.nr ? &remote->pushurl : &remote->url; } +void ref_push_report_free(struct ref_push_report *report) +{ + while (report) { + struct ref_push_report *next = report->next; + + free(report->ref_name); + free(report->old_oid); + free(report->new_oid); + free(report); + + report = next; + } +} + static int match_name_with_pattern(const char *key, const char *name, const char *value, char **result) { @@ -1122,7 +1160,9 @@ 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); free(ref); } @@ -2543,7 +2583,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; @@ -2620,8 +2660,10 @@ static int remote_tracking(struct remote *remote, const char *refname, dst = apply_refspecs(&remote->fetch, refname); if (!dst) return -1; /* no tracking ref for refname at remote */ - if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) + if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) { + free(dst); return -1; /* we know what the tracking ref is but we cannot read it */ + } *dst_refname = dst; return 0; @@ -2771,6 +2813,7 @@ static void check_if_includes_upstream(struct ref *remote) if (is_reachable_in_reflog(local->name, remote) <= 0) remote->unreachable = 1; + free_one_ref(local); } static void apply_cas(struct push_cas_option *cas, @@ -4,6 +4,7 @@ #include "hash.h" #include "hashmap.h" #include "refspec.h" +#include "string-list.h" #include "strvec.h" struct option; @@ -58,6 +59,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 +112,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 +139,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; @@ -329,7 +344,7 @@ struct branch { struct branch *branch_get(const char *name); const char *remote_for_branch(struct branch *branch, int *explicit); const char *pushremote_for_branch(struct branch *branch, int *explicit); -const char *remote_ref_for_branch(struct branch *branch, int for_push); +char *remote_ref_for_branch(struct branch *branch, int for_push); /* returns true if the given branch has merge configuration given. */ int branch_has_merge_config(struct branch *branch); @@ -409,6 +424,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 *); diff --git a/repo-settings.c b/repo-settings.c index 2b4e68731b..9d16d5399e 100644 --- a/repo-settings.c +++ b/repo-settings.c @@ -1,7 +1,9 @@ #include "git-compat-util.h" #include "config.h" +#include "repo-settings.h" #include "repository.h" #include "midx.h" +#include "pack-objects.h" static void repo_cfg_bool(struct repository *r, const char *key, int *dest, int def) @@ -19,22 +21,22 @@ 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"); - if (r->settings.initialized++) + if (r->settings.initialized) return; - /* Defaults */ - r->settings.index_version = -1; - r->settings.core_untracked_cache = UNTRACKED_CACHE_KEEP; - r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_CONSECUTIVE; + memcpy(&r->settings, &defaults, sizeof(defaults)); + r->settings.initialized++; /* Booleans config or default, cascades to other settings */ repo_cfg_bool(r, "feature.manyfiles", &manyfiles, 0); @@ -123,4 +125,45 @@ 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; +} + +enum log_refs_config repo_settings_get_log_all_ref_updates(struct repository *repo) +{ + const char *value; + + if (!repo_config_get_string_tmp(repo, "core.logallrefupdates", &value)) { + if (value && !strcasecmp(value, "always")) + return LOG_REFS_ALWAYS; + else if (git_config_bool("core.logallrefupdates", value)) + return LOG_REFS_NORMAL; + else + return LOG_REFS_NONE; + } + + return LOG_REFS_UNSET; +} + +int repo_settings_get_warn_ambiguous_refs(struct repository *repo) +{ + prepare_repo_settings(repo); + if (repo->settings.warn_ambiguous_refs < 0) + repo_cfg_bool(repo, "core.warnambiguousrefs", + &repo->settings.warn_ambiguous_refs, 1); + return repo->settings.warn_ambiguous_refs; } diff --git a/repo-settings.h b/repo-settings.h new file mode 100644 index 0000000000..93ea0c3274 --- /dev/null +++ b/repo-settings.h @@ -0,0 +1,82 @@ +#ifndef REPO_SETTINGS_H +#define REPO_SETTINGS_H + +struct fsmonitor_settings; +struct repository; + +enum untracked_cache_setting { + UNTRACKED_CACHE_KEEP, + UNTRACKED_CACHE_REMOVE, + UNTRACKED_CACHE_WRITE, +}; + +enum fetch_negotiation_setting { + FETCH_NEGOTIATION_CONSECUTIVE, + FETCH_NEGOTIATION_SKIPPING, + FETCH_NEGOTIATION_NOOP, +}; + +enum log_refs_config { + LOG_REFS_UNSET = -1, + LOG_REFS_NONE = 0, + LOG_REFS_NORMAL, + LOG_REFS_ALWAYS +}; + +struct repo_settings { + int initialized; + + int core_commit_graph; + int commit_graph_generation_version; + int commit_graph_changed_paths_version; + int gc_write_commit_graph; + int fetch_write_commit_graph; + int command_requires_full_index; + int sparse_index; + int pack_read_reverse_index; + int pack_use_bitmap_boundary_traversal; + int pack_use_multi_pack_reuse; + + /* + * Does this repository have core.useReplaceRefs=true (on by + * default)? This provides a repository-scoped version of this + * config, though it could be disabled process-wide via some Git + * builtins or the --no-replace-objects option. See + * replace_refs_enabled() for more details. + */ + int read_replace_refs; + + struct fsmonitor_settings *fsmonitor; /* lazily loaded */ + + int index_version; + int index_skip_hash; + enum untracked_cache_setting core_untracked_cache; + + int pack_use_sparse; + enum fetch_negotiation_setting fetch_negotiation_algorithm; + + 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; +}; +#define REPO_SETTINGS_INIT { \ + .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); + +/* 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); + +#endif /* REPO_SETTINGS_H */ diff --git a/repository.c b/repository.c index 9825a30899..1a6a62bbd0 100644 --- a/repository.c +++ b/repository.c @@ -54,7 +54,7 @@ void initialize_repository(struct repository *repo) { repo->objects = raw_object_store_new(); repo->remote_state = remote_state_new(); - repo->parsed_objects = parsed_object_pool_new(); + repo->parsed_objects = parsed_object_pool_new(repo); ALLOC_ARRAY(repo->index, 1); index_state_init(repo->index, repo); @@ -91,6 +91,46 @@ static void expand_base_dir(char **out, const char *in, *out = xstrfmt("%s/%s", base_dir, def_in); } +const char *repo_get_git_dir(struct repository *repo) +{ + if (!repo->gitdir) + BUG("repository hasn't been set up"); + return repo->gitdir; +} + +const char *repo_get_common_dir(struct repository *repo) +{ + if (!repo->commondir) + BUG("repository hasn't been set up"); + return repo->commondir; +} + +const char *repo_get_object_directory(struct repository *repo) +{ + if (!repo->objects->odb) + BUG("repository hasn't been set up"); + return repo->objects->odb->path; +} + +const char *repo_get_index_file(struct repository *repo) +{ + if (!repo->index_file) + BUG("repository hasn't been set up"); + return repo->index_file; +} + +const char *repo_get_graft_file(struct repository *repo) +{ + if (!repo->graft_file) + BUG("repository hasn't been set up"); + return repo->graft_file; +} + +const char *repo_get_work_tree(struct repository *repo) +{ + return repo->worktree; +} + static void repo_set_commondir(struct repository *repo, const char *commondir) { @@ -243,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; diff --git a/repository.h b/repository.h index af6ea0a62c..c4c92b2ab9 100644 --- a/repository.h +++ b/repository.h @@ -2,9 +2,9 @@ #define REPOSITORY_H #include "strmap.h" +#include "repo-settings.h" struct config_set; -struct fsmonitor_settings; struct git_hash_algo; struct index_state; struct lock_file; @@ -14,59 +14,12 @@ struct submodule_cache; struct promisor_remote_config; struct remote_state; -enum untracked_cache_setting { - UNTRACKED_CACHE_KEEP, - UNTRACKED_CACHE_REMOVE, - UNTRACKED_CACHE_WRITE, -}; - -enum fetch_negotiation_setting { - FETCH_NEGOTIATION_CONSECUTIVE, - FETCH_NEGOTIATION_SKIPPING, - FETCH_NEGOTIATION_NOOP, -}; - enum ref_storage_format { REF_STORAGE_FORMAT_UNKNOWN, REF_STORAGE_FORMAT_FILES, REF_STORAGE_FORMAT_REFTABLE, }; -struct repo_settings { - int initialized; - - int core_commit_graph; - int commit_graph_generation_version; - int commit_graph_changed_paths_version; - int gc_write_commit_graph; - int fetch_write_commit_graph; - int command_requires_full_index; - int sparse_index; - int pack_read_reverse_index; - int pack_use_bitmap_boundary_traversal; - int pack_use_multi_pack_reuse; - - /* - * Does this repository have core.useReplaceRefs=true (on by - * default)? This provides a repository-scoped version of this - * config, though it could be disabled process-wide via some Git - * builtins or the --no-replace-objects option. See - * replace_refs_enabled() for more details. - */ - int read_replace_refs; - - struct fsmonitor_settings *fsmonitor; /* lazily loaded */ - - int index_version; - int index_skip_hash; - enum untracked_cache_setting core_untracked_cache; - - int pack_use_sparse; - enum fetch_negotiation_setting fetch_negotiation_algorithm; - - int core_multi_pack_index; -}; - struct repo_path_cache { char *squash_msg; char *merge_msg; @@ -197,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; @@ -206,6 +160,13 @@ struct repository { extern struct repository *the_repository; #endif +const char *repo_get_git_dir(struct repository *repo); +const char *repo_get_common_dir(struct repository *repo); +const char *repo_get_object_directory(struct repository *repo); +const char *repo_get_index_file(struct repository *repo); +const char *repo_get_graft_file(struct repository *repo); +const char *repo_get_work_tree(struct repository *repo); + /* * Define a custom repository layout. Any field can be NULL, which * will default back to the path according to the default layout. @@ -266,8 +227,6 @@ int repo_read_index_unmerged(struct repository *); */ void repo_update_index_if_able(struct repository *, struct lock_file *); -void prepare_repo_settings(struct repository *r); - /* * Return 1 if upgrade repository format to target_version succeeded, * 0 if no upgrade is necessary, and -1 when upgrade is not possible. diff --git a/revision.c b/revision.c index 2d7ad2bddf..57ca521c55 100644 --- a/revision.c +++ b/revision.c @@ -51,8 +51,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 +390,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 +433,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 +1072,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 +1108,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 +1212,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; @@ -3222,6 +3228,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 +3256,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 +3921,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 +4012,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 +4109,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 +4213,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/revision.h b/revision.h index 0e470d1df1..71e984c452 100644 --- a/revision.h +++ b/revision.h @@ -549,7 +549,7 @@ int rewrite_parents(struct rev_info *revs, * The log machinery saves the original parent list so that * get_saved_parents() can later tell what the real parents of the * commits are, when commit->parents has been modified by history - * simpification. + * simplification. * * get_saved_parents() will transparently return commit->parents if * history simplification is off. diff --git a/run-command.h b/run-command.h index 03e7222d8b..0df25e445f 100644 --- a/run-command.h +++ b/run-command.h @@ -535,7 +535,7 @@ enum start_bg_result { /* timeout expired waiting for child to become "ready" */ SBGR_TIMEOUT, - /* child process exited or was signalled before becomming "ready" */ + /* child process exited or was signalled before becoming "ready" */ SBGR_DIED, }; @@ -732,6 +732,10 @@ 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; loop_end: if (!succeeded) { diff --git a/send-pack.c b/send-pack.c index 5d0c23772a..6677c44e8a 100644 --- a/send-pack.c +++ b/send-pack.c @@ -353,7 +353,8 @@ static int generate_push_cert(struct strbuf *req_buf, { const struct ref *ref; struct string_list_item *item; - char *signing_key_id = xstrdup(get_signing_key_id()); + char *signing_key_id = get_signing_key_id(); + char *signing_key = get_signing_key(); const char *cp, *np; struct strbuf cert = STRBUF_INIT; int update_seen = 0; @@ -386,7 +387,7 @@ static int generate_push_cert(struct strbuf *req_buf, if (!update_seen) goto free_return; - if (sign_buffer(&cert, &cert, get_signing_key())) + if (sign_buffer(&cert, &cert, signing_key)) die(_("failed to sign the push certificate")); packet_buf_write(req_buf, "push-cert%c%s", 0, cap_string); @@ -399,6 +400,7 @@ static int generate_push_cert(struct strbuf *req_buf, free_return: free(signing_key_id); + free(signing_key); strbuf_release(&cert); return update_seen; } @@ -506,14 +508,15 @@ int send_pack(struct send_pack_args *args, unsigned cmds_sent = 0; int ret; struct async demux; - const char *push_cert_nonce = NULL; + char *push_cert_nonce = NULL; struct packet_reader reader; int use_bitmaps; if (!remote_refs) { fprintf(stderr, "No refs in common and none specified; doing nothing.\n" "Perhaps you should specify a branch.\n"); - return 0; + ret = 0; + goto out; } git_config_get_bool("push.negotiate", &push_negotiate); @@ -557,10 +560,11 @@ int send_pack(struct send_pack_args *args, if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) { size_t len; - push_cert_nonce = server_feature_value("push-cert", &len); - if (push_cert_nonce) { - reject_invalid_nonce(push_cert_nonce, len); - push_cert_nonce = xmemdupz(push_cert_nonce, len); + const char *nonce = server_feature_value("push-cert", &len); + + if (nonce) { + reject_invalid_nonce(nonce, len); + push_cert_nonce = xmemdupz(nonce, len); } else if (args->push_cert == SEND_PACK_PUSH_CERT_ALWAYS) { die(_("the receiving end does not support --signed push")); } else if (args->push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) { @@ -623,12 +627,11 @@ int send_pack(struct send_pack_args *args, * atomically, abort the whole operation. */ if (use_atomic) { - strbuf_release(&req_buf); - strbuf_release(&cap_buf); reject_atomic_push(remote_refs, args->send_mirror); error("atomic push failed for ref %s. status: %d", ref->name, ref->status); - return args->porcelain ? 0 : -1; + ret = args->porcelain ? 0 : -1; + goto out; } /* else fallthrough */ default: @@ -692,8 +695,6 @@ int send_pack(struct send_pack_args *args, write_or_die(out, req_buf.buf, req_buf.len); packet_flush(out); } - strbuf_release(&req_buf); - strbuf_release(&cap_buf); if (use_sideband && cmds_sent) { memset(&demux, 0, sizeof(demux)); @@ -731,7 +732,9 @@ int send_pack(struct send_pack_args *args, finish_async(&demux); } fd[1] = -1; - return -1; + + ret = -1; + goto out; } if (!args->stateless_rpc) /* Closed by pack_objects() via start_command() */ @@ -756,10 +759,12 @@ int send_pack(struct send_pack_args *args, } if (ret < 0) - return ret; + goto out; - if (args->porcelain) - return 0; + if (args->porcelain) { + ret = 0; + goto out; + } for (ref = remote_refs; ref; ref = ref->next) { switch (ref->status) { @@ -768,8 +773,17 @@ int send_pack(struct send_pack_args *args, case REF_STATUS_OK: break; default: - return -1; + ret = -1; + goto out; } } - return 0; + + ret = 0; + +out: + oid_array_clear(&commons); + strbuf_release(&req_buf); + strbuf_release(&cap_buf); + free(push_cert_nonce); + return ret; } diff --git a/sequencer.c b/sequencer.c index 8d01cd50ac..459066e43b 100644 --- a/sequencer.c +++ b/sequencer.c @@ -662,7 +662,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 +1297,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 +1941,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 +1963,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 +2345,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 +2356,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) { @@ -3890,7 +3895,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 +5824,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 +5847,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 +5908,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 +5927,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 +5947,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 +6055,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 +6387,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 +6418,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 +6426,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/server-info.c b/server-info.c index 1508fa6f82..c5af4cd98a 100644 --- a/server-info.c +++ b/server-info.c @@ -2,7 +2,6 @@ #include "git-compat-util.h" #include "dir.h" -#include "environment.h" #include "hex.h" #include "repository.h" #include "refs.h" @@ -342,7 +341,8 @@ static int write_pack_info_file(struct update_info_ctx *uic) static int update_info_packs(int force) { - char *infofile = mkpathdup("%s/info/packs", get_object_directory()); + char *infofile = mkpathdup("%s/info/packs", + repo_get_object_directory(the_repository)); int ret; init_pack_info(infofile, force); @@ -7,16 +7,22 @@ #include "exec-cmd.h" #include "gettext.h" #include "hex.h" +#include "object-file.h" #include "object-name.h" #include "refs.h" +#include "replace-object.h" #include "repository.h" #include "config.h" #include "dir.h" #include "setup.h" +#include "shallow.h" #include "string-list.h" +#include "strvec.h" #include "chdir-notify.h" #include "path.h" #include "quote.h" +#include "tmp-objdir.h" +#include "trace.h" #include "trace2.h" #include "worktree.h" #include "exec-cmd.h" @@ -51,7 +57,7 @@ static int abspath_part_inside_repo(char *path) size_t wtlen; char *path0; int off; - const char *work_tree = precompose_string_if_needed(get_git_work_tree()); + const char *work_tree = precompose_string_if_needed(repo_get_work_tree(the_repository)); struct strbuf realpath = STRBUF_INIT; if (!work_tree) @@ -147,9 +153,9 @@ char *prefix_path(const char *prefix, int len, const char *path) { char *r = prefix_path_gently(prefix, len, NULL, path); if (!r) { - const char *hint_path = get_git_work_tree(); + const char *hint_path = repo_get_work_tree(the_repository); if (!hint_path) - hint_path = get_git_dir(); + hint_path = repo_get_git_dir(the_repository); die(_("'%s' is outside repository at '%s'"), path, absolute_path(hint_path)); } @@ -468,14 +474,14 @@ int is_nonbare_repository_dir(struct strbuf *path) int is_inside_git_dir(void) { if (inside_git_dir < 0) - inside_git_dir = is_inside_dir(get_git_dir()); + inside_git_dir = is_inside_dir(repo_get_git_dir(the_repository)); return inside_git_dir; } int is_inside_work_tree(void) { if (inside_work_tree < 0) - inside_work_tree = is_inside_dir(get_git_work_tree()); + inside_work_tree = is_inside_dir(repo_get_work_tree(the_repository)); return inside_work_tree; } @@ -490,7 +496,7 @@ void setup_work_tree(void) if (work_tree_config_is_bogus) die(_("unable to set up work tree using invalid config")); - work_tree = get_git_work_tree(); + work_tree = repo_get_work_tree(the_repository); if (!work_tree || chdir_notify(work_tree)) die(_("this operation must be run in a work tree")); @@ -518,7 +524,7 @@ static void setup_original_cwd(void) * directory we inherited from our parent process, which is a * directory we want to avoid removing. * - * For convience, we would like to have the path relative to the + * For convenience, we would like to have the path relative to the * worktree instead of an absolute path. * * Yes, startup_info->original_cwd is usually the same as 'prefix', @@ -547,7 +553,7 @@ static void setup_original_cwd(void) * Get our worktree; we only protect the current working directory * if it's in the worktree. */ - worktree = get_git_work_tree(); + worktree = repo_get_work_tree(the_repository); if (!worktree) goto no_prevention_needed; @@ -677,6 +683,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; } @@ -1062,9 +1071,9 @@ static const char *setup_explicit_git_dir(const char *gitdirenv, set_git_work_tree("."); /* set_git_work_tree() must have been called by now */ - worktree = get_git_work_tree(); + worktree = repo_get_work_tree(the_repository); - /* both get_git_work_tree() and cwd are already normalized */ + /* both repo_get_work_tree() and cwd are already normalized */ if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */ set_git_dir(gitdirenv, 0); free(gitfile); @@ -1613,6 +1622,106 @@ enum discovery_result discover_git_directory_reason(struct strbuf *commondir, return result; } +void setup_git_env(const char *git_dir) +{ + char *git_replace_ref_base; + const char *shallow_file; + const char *replace_ref_base; + struct set_gitdir_args args = { NULL }; + struct strvec to_free = STRVEC_INIT; + + args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT); + args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT); + args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT); + args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT); + args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT); + if (getenv(GIT_QUARANTINE_ENVIRONMENT)) { + args.disable_ref_updates = 1; + } + + repo_set_gitdir(the_repository, git_dir, &args); + strvec_clear(&to_free); + + if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT)) + disable_replace_refs(); + replace_ref_base = getenv(GIT_REPLACE_REF_BASE_ENVIRONMENT); + git_replace_ref_base = xstrdup(replace_ref_base ? replace_ref_base + : "refs/replace/"); + update_ref_namespace(NAMESPACE_REPLACE, git_replace_ref_base); + + shallow_file = getenv(GIT_SHALLOW_FILE_ENVIRONMENT); + if (shallow_file) + set_alternate_shallow_file(the_repository, shallow_file, 0); + + if (git_env_bool(NO_LAZY_FETCH_ENVIRONMENT, 0)) + fetch_if_missing = 0; +} + +static void set_git_dir_1(const char *path) +{ + xsetenv(GIT_DIR_ENVIRONMENT, path, 1); + setup_git_env(path); +} + +static void update_relative_gitdir(const char *name UNUSED, + const char *old_cwd, + const char *new_cwd, + void *data UNUSED) +{ + char *path = reparent_relative_path(old_cwd, new_cwd, + repo_get_git_dir(the_repository)); + struct tmp_objdir *tmp_objdir = tmp_objdir_unapply_primary_odb(); + + trace_printf_key(&trace_setup_key, + "setup: move $GIT_DIR to '%s'", + path); + set_git_dir_1(path); + if (tmp_objdir) + tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd); + free(path); +} + +void set_git_dir(const char *path, int make_realpath) +{ + struct strbuf realpath = STRBUF_INIT; + + if (make_realpath) { + strbuf_realpath(&realpath, path, 1); + path = realpath.buf; + } + + set_git_dir_1(path); + if (!is_absolute_path(path)) + chdir_notify_register(NULL, update_relative_gitdir, NULL); + + strbuf_release(&realpath); +} + +static int git_work_tree_initialized; + +/* + * Note. This works only before you used a work tree. This was added + * primarily to support git-clone to work in a new repository it just + * created, and is not meant to flip between different work trees. + */ +void set_git_work_tree(const char *new_work_tree) +{ + if (git_work_tree_initialized) { + struct strbuf realpath = STRBUF_INIT; + + strbuf_realpath(&realpath, new_work_tree, 1); + new_work_tree = realpath.buf; + if (strcmp(new_work_tree, the_repository->worktree)) + die("internal error: work tree has already been set\n" + "Current worktree: %s\nNew worktree: %s", + the_repository->worktree, new_work_tree); + strbuf_release(&realpath); + return; + } + git_work_tree_initialized = 1; + repo_set_worktree(the_repository, new_work_tree); +} + const char *setup_git_directory_gently(int *nongit_ok) { static struct strbuf cwd = STRBUF_INIT; @@ -1748,6 +1857,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; @@ -1836,7 +1947,7 @@ void check_repository_format(struct repository_format *fmt) struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT; if (!fmt) fmt = &repo_fmt; - check_repository_format_gently(get_git_dir(), fmt, NULL); + check_repository_format_gently(repo_get_git_dir(the_repository), fmt, NULL); startup_info->have_repository = 1; repo_set_hash_algo(the_repository, fmt->hash_algo); repo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo); @@ -1844,6 +1955,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); @@ -2068,7 +2181,7 @@ static void copy_templates(const char *option_template) goto close_free_return; } - strbuf_addstr(&path, get_git_common_dir()); + strbuf_addstr(&path, repo_get_common_dir(the_repository)); strbuf_complete(&path, '/'); copy_templates_1(&path, &template_path, dir); close_free_return: @@ -2098,8 +2211,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 @@ -2110,12 +2223,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", @@ -2128,6 +2236,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; + + strbuf_git_common_path(&config, the_repository, "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) @@ -2192,7 +2319,7 @@ static int create_default_files(const char *template_path, char *path; int reinit; int filemode; - const char *work_tree = get_git_work_tree(); + const char *work_tree = repo_get_work_tree(the_repository); /* * First copy the templates -- we might have the default @@ -2224,10 +2351,10 @@ static int create_default_files(const char *template_path, * shared-repository settings, we would need to fix them up. */ if (get_shared_repository()) { - adjust_shared_perm(get_git_dir()); + adjust_shared_perm(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"); @@ -2248,7 +2375,7 @@ static int create_default_files(const char *template_path, else { git_config_set("core.bare", "false"); /* allow template config file to override the default */ - if (log_all_ref_updates == LOG_REFS_UNSET) + if (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET) git_config_set("core.logallrefupdates", "true"); if (needs_work_tree_config(original_git_dir, work_tree)) git_config_set("core.worktree", work_tree); @@ -2282,7 +2409,7 @@ static void create_object_directory(void) struct strbuf path = STRBUF_INIT; size_t baselen; - strbuf_addstr(&path, get_object_directory()); + strbuf_addstr(&path, repo_get_object_directory(the_repository)); baselen = path.len; safe_create_dir(path.buf, 1); @@ -2314,7 +2441,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); @@ -2434,12 +2561,12 @@ int init_db(const char *git_dir, const char *real_git_dir, die(_("%s already exists"), real_git_dir); set_git_dir(real_git_dir, 1); - git_dir = get_git_dir(); + git_dir = repo_get_git_dir(the_repository); separate_git_dir(git_dir, original_git_dir); } else { set_git_dir(git_dir, 1); - git_dir = get_git_dir(); + git_dir = repo_get_git_dir(the_repository); } startup_info->have_repository = 1; @@ -94,6 +94,9 @@ static inline int discover_git_directory(struct strbuf *commondir, return 0; } +void set_git_dir(const char *path, int make_realpath); +void set_git_work_tree(const char *tree); + const char *setup_git_directory_gently(int *); const char *setup_git_directory(void); char *prefix_path(const char *prefix, int len, const char *path); @@ -126,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; @@ -176,7 +180,7 @@ int verify_repository_format(const struct repository_format *format, struct strbuf *err); /* - * Check the repository format version in the path found in get_git_dir(), + * Check the repository format version in the path found in repo_get_git_dir(the_repository), * and die if it is a version we don't understand. Generally one would * set_git_dir() before calling this, and use it only for "are we in a valid * repo?". diff --git a/sha1/openssl.h b/sha1/openssl.h index 006c1f4ba5..1038af47da 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 60e3ce8439..f6f880cabe 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 @@ -51,6 +51,7 @@ int unregister_shallow(const struct object_id *oid) int pos = commit_graft_pos(the_repository, oid); if (pos < 0) return -1; + 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, @@ -97,7 +98,7 @@ static void reset_repository_shallow(struct repository *r) { r->parsed_objects->is_shallow = -1; stat_validity_clear(r->parsed_objects->shallow_stat); - reset_commit_grafts(r); + parsed_object_pool_reset_commit_grafts(r->parsed_objects); } int commit_shallow_file(struct repository *r, struct shallow_lock *lk) @@ -487,6 +488,15 @@ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) void clear_shallow_info(struct shallow_info *info) { + if (info->used_shallow) { + for (size_t i = 0; i < info->shallow->nr; i++) + free(info->used_shallow[i]); + free(info->used_shallow); + } + + free(info->need_reachability_test); + free(info->reachable); + free(info->shallow_ref); free(info->ours); free(info->theirs); } @@ -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 4e816be4e9..02805573fa 100644 --- a/sideband.c +++ b/sideband.c @@ -191,7 +191,7 @@ int demultiplex_sideband(const char *me, int status, int linelen = brk - b; /* - * For message accross packet boundary, there would have + * For message across packet boundary, there would have * a nonempty "scratch" buffer from last call of this * function, and there may have a leading CR/LF in "buf". * For this case we should add a clear-to-eol suffix to diff --git a/simple-ipc.h b/simple-ipc.h index a849d9f841..3916eaf70d 100644 --- a/simple-ipc.h +++ b/simple-ipc.h @@ -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 9958656ded..2107840bfc 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -1,5 +1,8 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "environment.h" +#include "ewah/ewok.h" #include "gettext.h" #include "name-hash.h" #include "read-cache-ll.h" @@ -19,9 +22,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" \ @@ -239,7 +243,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; @@ -435,7 +440,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 a16f3e67d7..727034be7c 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 120c8190b1..cfbc773e6c 100644 --- a/split-index.c +++ b/split-index.c @@ -97,7 +97,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/statinfo.c b/statinfo.c index 3c6bc049c1..30a164b0e6 100644 --- a/statinfo.c +++ b/statinfo.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "environment.h" #include "statinfo.h" @@ -637,28 +637,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, @@ -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; @@ -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 c8f2bb2bdd..9c8c37b259 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -95,7 +95,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 +901,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 +931,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 +946,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 b6133af71b..f55d4e3b61 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 97516b0fec..7ec564854d 100644 --- a/submodule.c +++ b/submodule.c @@ -175,11 +175,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 +424,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) { @@ -1169,8 +1174,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 +1209,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; @@ -1883,6 +1888,8 @@ int fetch_submodules(struct repository *r, out: free_submodules_data(&spf.changed_submodule_names); string_list_clear(&spf.seen_submodule_names, 0); + strbuf_release(&spf.submodules_with_errors); + free(spf.oid_fetch_tasks); return spf.result; } @@ -2462,7 +2469,7 @@ void absorb_git_dir_into_superproject(const char *path, } else { /* Is it already absorbed into the superprojects git dir? */ char *real_sub_git_dir = real_pathdup(sub_git_dir, 1); - char *real_common_git_dir = real_pathdup(get_git_common_dir(), 1); + char *real_common_git_dir = real_pathdup(repo_get_common_dir(the_repository), 1); if (!starts_with(real_sub_git_dir, real_common_git_dir)) relocate_single_git_dir_into_superproject(path, super_prefix); diff --git a/submodule.h b/submodule.h index b50d29eba4..4deb1b5f84 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, diff --git a/subprojects/.gitignore b/subprojects/.gitignore new file mode 100644 index 0000000000..63ea916ef5 --- /dev/null +++ b/subprojects/.gitignore @@ -0,0 +1 @@ +/*/ diff --git a/subprojects/curl.wrap b/subprojects/curl.wrap new file mode 100644 index 0000000000..f7e384b85c --- /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 0000000000..2e0427dcfd --- /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 0000000000..873d55106e --- /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 0000000000..7e18447254 --- /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 0000000000..aa14de1774 --- /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/t/Makefile b/t/Makefile index 4c30e7c06f..131ffd778f 100644 --- a/t/Makefile +++ b/t/Makefile @@ -48,6 +48,7 @@ CHAINLINTTESTS = $(sort $(patsubst chainlint/%.test,%,$(wildcard chainlint/*.tes CHAINLINT = '$(PERL_PATH_SQ)' chainlint.pl UNIT_TEST_SOURCES = $(wildcard unit-tests/t-*.c) UNIT_TEST_PROGRAMS = $(patsubst unit-tests/%.c,unit-tests/bin/%$(X),$(UNIT_TEST_SOURCES)) +UNIT_TEST_PROGRAMS += unit-tests/bin/unit-tests$(X) UNIT_TESTS = $(sort $(UNIT_TEST_PROGRAMS)) UNIT_TESTS_NO_DIR = $(notdir $(UNIT_TESTS)) @@ -68,7 +69,8 @@ failed: test -z "$$failed" || $(MAKE) $$failed prove: pre-clean check-chainlint $(TEST_LINT) - @echo "*** prove (shell & unit tests) ***"; $(CHAINLINTSUPPRESS) TEST_SHELL_PATH='$(TEST_SHELL_PATH_SQ)' $(PROVE) --exec ./run-test.sh $(GIT_PROVE_OPTS) $(T) $(UNIT_TESTS) :: $(GIT_TEST_OPTS) + @echo "*** prove (shell & unit tests) ***" + @$(CHAINLINTSUPPRESS) TEST_OPTIONS='$(GIT_TEST_OPTS)' TEST_SHELL_PATH='$(TEST_SHELL_PATH_SQ)' $(PROVE) --exec ./run-test.sh $(GIT_PROVE_OPTS) $(T) $(UNIT_TESTS) $(MAKE) clean-except-prove-cache $(T): @@ -368,24 +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_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version' default to n. @@ -462,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. diff --git a/t/chainlint.pl b/t/chainlint.pl index 5361f23b1d..f0598e3934 100755 --- a/t/chainlint.pl +++ b/t/chainlint.pl @@ -9,9 +9,9 @@ # Input arguments are pathnames of shell scripts containing test definitions, # or globs referencing a collection of scripts. For each problem discovered, # the pathname of the script containing the test is printed along with the test -# name and the test body with a `?!FOO?!` annotation at the location of each -# detected problem, where "FOO" is a tag such as "AMP" which indicates a broken -# &&-chain. Returns zero if no problems are discovered, otherwise non-zero. +# name and the test body with a `?!LINT: ...?!` annotation at the location of +# each detected problem, where "..." is an explanation of the problem. Returns +# zero if no problems are discovered, otherwise non-zero. use warnings; use strict; @@ -181,7 +181,7 @@ sub swallow_heredocs { $self->{lineno} += () = $body =~ /\n/sg; next; } - push(@{$self->{parser}->{problems}}, ['UNCLOSED-HEREDOC', $tag]); + push(@{$self->{parser}->{problems}}, ['HEREDOC', $tag]); $$b =~ /(?:\G|\n).*\z/gc; # consume rest of input my $body = substr($$b, $start, pos($$b) - $start); $self->{lineno} += () = $body =~ /\n/sg; @@ -238,6 +238,7 @@ sub new { stop => [], output => [], heredocs => {}, + insubshell => 0, } => $class; $self->{lexer} = Lexer->new($self, $s); return $self; @@ -296,8 +297,11 @@ sub parse_group { sub parse_subshell { my $self = shift @_; - return ($self->parse(qr/^\)$/), - $self->expect(')')); + $self->{insubshell}++; + my @tokens = ($self->parse(qr/^\)$/), + $self->expect(')')); + $self->{insubshell}--; + return @tokens; } sub parse_case_pattern { @@ -528,7 +532,7 @@ sub parse_loop_body { return @tokens if ends_with(\@tokens, [qr/^\|\|$/, "\n", qr/^echo$/, qr/^.+$/]); # flag missing "return/exit" handling explicit failure in loop body my $n = find_non_nl(\@tokens); - push(@{$self->{problems}}, ['LOOP', $tokens[$n]]); + push(@{$self->{problems}}, [$self->{insubshell} ? 'LOOPEXIT' : 'LOOPRETURN', $tokens[$n]]); return @tokens; } @@ -587,6 +591,7 @@ sub new { my $class = shift @_; my $self = $class->SUPER::new(@_); $self->{ntests} = 0; + $self->{nerrs} = 0; return $self; } @@ -619,6 +624,15 @@ sub unwrap { return $s } +sub format_problem { + local $_ = shift; + /^AMP$/ && return "missing '&&'"; + /^LOOPRETURN$/ && return "missing '|| return 1'"; + /^LOOPEXIT$/ && return "missing '|| exit 1'"; + /^HEREDOC$/ && return 'unclosed heredoc'; + die("unrecognized problem type '$_'\n"); +} + sub check_test { my $self = shift @_; my $title = unwrap(shift @_); @@ -634,22 +648,26 @@ sub check_test { my $parser = TestParser->new(\$body); my @tokens = $parser->parse(); my $problems = $parser->{problems}; + $self->{nerrs} += @$problems; return unless $emit_all || @$problems; my $c = main::fd_colors(1); + my ($erropen, $errclose) = -t 1 ? ("$c->{rev}$c->{red}", $c->{reset}) : ('?!', '?!'); my $start = 0; my $checked = ''; for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) { my ($label, $token) = @$_; my $pos = $token->[2]; - $checked .= substr($body, $start, $pos - $start) . " ?!$label?! "; + my $err = format_problem($label); + $checked .= substr($body, $start, $pos - $start); + $checked .= ' ' unless $checked =~ /\s$/; + $checked .= "${erropen}LINT: $err$errclose"; + $checked .= ' ' unless $pos >= length($body) || + substr($body, $pos, 1) =~ /^\s/; $start = $pos; } $checked .= substr($body, $start); $checked =~ s/^/$lineno++ . ' '/mge; $checked =~ s/^\d+ \n//; - $checked =~ s/(\s) \?!/$1?!/mg; - $checked =~ s/\?! (\s)/?!$1/mg; - $checked =~ s/(\?![^?]+\?!)/$c->{rev}$c->{red}$1$c->{reset}/mg; $checked =~ s/^\d+/$c->{dim}$&$c->{reset}/mg; $checked .= "\n" unless $checked =~ /\n$/; push(@{$self->{output}}, "$c->{blue}# chainlint: $title$c->{reset}\n$checked"); @@ -791,9 +809,9 @@ sub check_script { my $c = fd_colors(1); my $s = join('', @{$parser->{output}}); $emit->("$c->{bold}$c->{blue}# chainlint: $path$c->{reset}\n" . $s); - $nerrs += () = $s =~ /\?![^?]+\?!/g; } $ntests += $parser->{ntests}; + $nerrs += $parser->{nerrs}; } return [$id, $nscripts, $ntests, $nerrs]; } diff --git a/t/chainlint/arithmetic-expansion.expect b/t/chainlint/arithmetic-expansion.expect index 338ecd5861..5677e16cad 100644 --- a/t/chainlint/arithmetic-expansion.expect +++ b/t/chainlint/arithmetic-expansion.expect @@ -4,6 +4,6 @@ 5 baz 6 ) && 7 ( -8 bar=$((42 + 1)) ?!AMP?! +8 bar=$((42 + 1)) ?!LINT: missing '&&'?! 9 baz 10 ) diff --git a/t/chainlint/block.expect b/t/chainlint/block.expect index b62e3d58c3..3d3f854c0d 100644 --- a/t/chainlint/block.expect +++ b/t/chainlint/block.expect @@ -1,20 +1,20 @@ 2 ( 3 foo && 4 { -5 echo a ?!AMP?! +5 echo a ?!LINT: missing '&&'?! 6 echo b 7 } && 8 bar && 9 { 10 echo c -11 } ?!AMP?! +11 } ?!LINT: missing '&&'?! 12 baz 13 ) && 14 15 { -16 echo a; ?!AMP?! echo b +16 echo a; ?!LINT: missing '&&'?! echo b 17 } && -18 { echo a; ?!AMP?! echo b; } && +18 { echo a; ?!LINT: missing '&&'?! echo b; } && 19 20 { 21 echo "${var}9" && diff --git a/t/chainlint/broken-chain.expect b/t/chainlint/broken-chain.expect index 9a1838736f..b7b1ce8509 100644 --- a/t/chainlint/broken-chain.expect +++ b/t/chainlint/broken-chain.expect @@ -1,6 +1,6 @@ 2 ( 3 foo && -4 bar ?!AMP?! +4 bar ?!LINT: missing '&&'?! 5 baz && 6 wop 7 ) diff --git a/t/chainlint/case.expect b/t/chainlint/case.expect index c04c61ff36..0a3b09e470 100644 --- a/t/chainlint/case.expect +++ b/t/chainlint/case.expect @@ -9,11 +9,11 @@ 10 case "$x" in 11 x) foo ;; 12 *) bar ;; -13 esac ?!AMP?! +13 esac ?!LINT: missing '&&'?! 14 foobar 15 ) && 16 ( 17 case "$x" in 1) true;; esac && -18 case "$y" in 2) false;; esac ?!AMP?! +18 case "$y" in 2) false;; esac ?!LINT: missing '&&'?! 19 foobar 20 ) diff --git a/t/chainlint/chain-break-false.expect b/t/chainlint/chain-break-false.expect index 4f815f8e14..f6a0a301e9 100644 --- a/t/chainlint/chain-break-false.expect +++ b/t/chainlint/chain-break-false.expect @@ -4,6 +4,6 @@ 5 echo failed! 6 false 7 else -8 echo it went okay ?!AMP?! +8 echo it went okay ?!LINT: missing '&&'?! 9 congratulate user 10 fi diff --git a/t/chainlint/chained-block.expect b/t/chainlint/chained-block.expect index a546b714a6..f2501bba90 100644 --- a/t/chainlint/chained-block.expect +++ b/t/chainlint/chained-block.expect @@ -1,5 +1,5 @@ 2 echo nobody home && { -3 test the doohicky ?!AMP?! +3 test the doohicky ?!LINT: missing '&&'?! 4 right now 5 } && 6 diff --git a/t/chainlint/chained-subshell.expect b/t/chainlint/chained-subshell.expect index f78b268291..93fb1a6578 100644 --- a/t/chainlint/chained-subshell.expect +++ b/t/chainlint/chained-subshell.expect @@ -1,10 +1,10 @@ 2 mkdir sub && ( 3 cd sub && -4 foo the bar ?!AMP?! +4 foo the bar ?!LINT: missing '&&'?! 5 nuff said 6 ) && 7 8 cut "-d " -f actual | (read s1 s2 s3 && -9 test -f $s1 ?!AMP?! +9 test -f $s1 ?!LINT: missing '&&'?! 10 test $(cat $s2) = tree2path1 && 11 test $(cat $s3) = tree3path1) diff --git a/t/chainlint/command-substitution.expect b/t/chainlint/command-substitution.expect index 5e31b36db6..73809fd585 100644 --- a/t/chainlint/command-substitution.expect +++ b/t/chainlint/command-substitution.expect @@ -4,6 +4,6 @@ 5 baz 6 ) && 7 ( -8 bar=$(gobble blocks) ?!AMP?! +8 bar=$(gobble blocks) ?!LINT: missing '&&'?! 9 baz 10 ) diff --git a/t/chainlint/complex-if-in-cuddled-loop.expect b/t/chainlint/complex-if-in-cuddled-loop.expect index 3a740103db..e66bb2d5d0 100644 --- a/t/chainlint/complex-if-in-cuddled-loop.expect +++ b/t/chainlint/complex-if-in-cuddled-loop.expect @@ -4,6 +4,6 @@ 5 : 6 else 7 echo >file -8 fi ?!LOOP?! +8 fi ?!LINT: missing '|| exit 1'?! 9 done) && 10 test ! -f file diff --git a/t/chainlint/cuddled.expect b/t/chainlint/cuddled.expect index b06d638311..1864b3fc8b 100644 --- a/t/chainlint/cuddled.expect +++ b/t/chainlint/cuddled.expect @@ -2,7 +2,7 @@ 3 bar 4 ) && 5 -6 (cd foo ?!AMP?! +6 (cd foo ?!LINT: missing '&&'?! 7 bar 8 ) && 9 @@ -13,5 +13,5 @@ 14 (cd foo && 15 bar) && 16 -17 (cd foo ?!AMP?! +17 (cd foo ?!LINT: missing '&&'?! 18 bar) diff --git a/t/chainlint/for-loop.expect b/t/chainlint/for-loop.expect index 908aeedf96..5029eacce3 100644 --- a/t/chainlint/for-loop.expect +++ b/t/chainlint/for-loop.expect @@ -1,14 +1,14 @@ 2 ( 3 for i in a b c 4 do -5 echo $i ?!AMP?! -6 cat <<-\EOF ?!LOOP?! +5 echo $i ?!LINT: missing '&&'?! +6 cat <<-\EOF ?!LINT: missing '|| exit 1'?! 7 bar 8 EOF -9 done ?!AMP?! +9 done ?!LINT: missing '&&'?! 10 11 for i in a b c; do 12 echo $i && -13 cat $i ?!LOOP?! +13 cat $i ?!LINT: missing '|| exit 1'?! 14 done 15 ) diff --git a/t/chainlint/function.expect b/t/chainlint/function.expect index c226246b25..9e46a3554a 100644 --- a/t/chainlint/function.expect +++ b/t/chainlint/function.expect @@ -4,8 +4,8 @@ 5 6 remove_object() { 7 file=$(sha1_file "$*") && -8 test -e "$file" ?!AMP?! +8 test -e "$file" ?!LINT: missing '&&'?! 9 rm -f "$file" -10 } ?!AMP?! +10 } ?!LINT: missing '&&'?! 11 12 sha1_file arg && remove_object arg diff --git a/t/chainlint/here-doc-body-indent.expect b/t/chainlint/here-doc-body-indent.expect index 4323acc93d..4306faee86 100644 --- a/t/chainlint/here-doc-body-indent.expect +++ b/t/chainlint/here-doc-body-indent.expect @@ -1,2 +1,2 @@ -2 echo "we should find this" ?!AMP?! +2 echo "we should find this" ?!LINT: missing '&&'?! 3 echo "even though our heredoc has its indent stripped" diff --git a/t/chainlint/here-doc-body-pathological.expect b/t/chainlint/here-doc-body-pathological.expect index a93a1fa3aa..2f8ea03a47 100644 --- a/t/chainlint/here-doc-body-pathological.expect +++ b/t/chainlint/here-doc-body-pathological.expect @@ -1,7 +1,7 @@ -2 echo "outer here-doc does not allow indented end-tag" ?!AMP?! +2 echo "outer here-doc does not allow indented end-tag" ?!LINT: missing '&&'?! 3 cat >file <<-\EOF && 4 but this inner here-doc 5 does allow indented EOF 6 EOF -7 echo "missing chain after" ?!AMP?! +7 echo "missing chain after" ?!LINT: missing '&&'?! 8 echo "but this line is OK because it's the end" diff --git a/t/chainlint/here-doc-body.expect b/t/chainlint/here-doc-body.expect index ddf1c412af..df8d79bc0a 100644 --- a/t/chainlint/here-doc-body.expect +++ b/t/chainlint/here-doc-body.expect @@ -1,7 +1,7 @@ -2 echo "missing chain before" ?!AMP?! +2 echo "missing chain before" ?!LINT: missing '&&'?! 3 cat >file <<-\EOF && 4 inside inner here-doc 5 these are not shell commands 6 EOF -7 echo "missing chain after" ?!AMP?! +7 echo "missing chain after" ?!LINT: missing '&&'?! 8 echo "but this line is OK because it's the end" diff --git a/t/chainlint/here-doc-double.expect b/t/chainlint/here-doc-double.expect index 20dba4b452..e5e981889f 100644 --- a/t/chainlint/here-doc-double.expect +++ b/t/chainlint/here-doc-double.expect @@ -1,2 +1,2 @@ -8 echo "actual test commands" ?!AMP?! +8 echo "actual test commands" ?!LINT: missing '&&'?! 9 echo "that should be checked" diff --git a/t/chainlint/here-doc-indent-operator.expect b/t/chainlint/here-doc-indent-operator.expect index 277a11202d..ec0e61505b 100644 --- a/t/chainlint/here-doc-indent-operator.expect +++ b/t/chainlint/here-doc-indent-operator.expect @@ -4,7 +4,7 @@ 5 chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data 6 EOF 7 -8 cat >expect << -EOF ?!AMP?! +8 cat >expect << -EOF ?!LINT: missing '&&'?! 9 this is not indented 10 -EOF 11 diff --git a/t/chainlint/here-doc-multi-line-command-subst.expect b/t/chainlint/here-doc-multi-line-command-subst.expect index 41b55f6437..8128f15b92 100644 --- a/t/chainlint/here-doc-multi-line-command-subst.expect +++ b/t/chainlint/here-doc-multi-line-command-subst.expect @@ -3,6 +3,6 @@ 4 fossil 5 vegetable 6 END -7 wiffle) ?!AMP?! +7 wiffle) ?!LINT: missing '&&'?! 8 echo $x 9 ) diff --git a/t/chainlint/here-doc-multi-line-string.expect b/t/chainlint/here-doc-multi-line-string.expect index c71828589e..a03a04ff3d 100644 --- a/t/chainlint/here-doc-multi-line-string.expect +++ b/t/chainlint/here-doc-multi-line-string.expect @@ -1,6 +1,6 @@ 2 ( 3 cat <<-\TXT && echo "multi-line -4 string" ?!AMP?! +4 string" ?!LINT: missing '&&'?! 5 fizzle 6 TXT 7 bap diff --git a/t/chainlint/if-condition-split.expect b/t/chainlint/if-condition-split.expect index 9daf3d294a..6d2a03dfdb 100644 --- a/t/chainlint/if-condition-split.expect +++ b/t/chainlint/if-condition-split.expect @@ -2,6 +2,6 @@ 3 marcia || 4 kevin 5 then -6 echo "nomads" ?!AMP?! +6 echo "nomads" ?!LINT: missing '&&'?! 7 echo "for sure" 8 fi diff --git a/t/chainlint/if-in-loop.expect b/t/chainlint/if-in-loop.expect index ff8c60dbdb..7e3ba740de 100644 --- a/t/chainlint/if-in-loop.expect +++ b/t/chainlint/if-in-loop.expect @@ -5,8 +5,8 @@ 6 then 7 echo "err" 8 exit 1 -9 fi ?!AMP?! +9 fi ?!LINT: missing '&&'?! 10 foo -11 done ?!AMP?! +11 done ?!LINT: missing '&&'?! 12 bar 13 ) diff --git a/t/chainlint/if-then-else.expect b/t/chainlint/if-then-else.expect index 965d7e41a2..924caa2e4e 100644 --- a/t/chainlint/if-then-else.expect +++ b/t/chainlint/if-then-else.expect @@ -1,7 +1,7 @@ 2 ( 3 if test -n "" 4 then -5 echo very ?!AMP?! +5 echo very ?!LINT: missing '&&'?! 6 echo empty 7 elif test -z "" 8 then @@ -11,7 +11,7 @@ 12 cat <<-\EOF 13 bar 14 EOF -15 fi ?!AMP?! +15 fi ?!LINT: missing '&&'?! 16 echo poodle 17 ) && 18 ( diff --git a/t/chainlint/inline-comment.expect b/t/chainlint/inline-comment.expect index 0285c0b22c..4b4080124e 100644 --- a/t/chainlint/inline-comment.expect +++ b/t/chainlint/inline-comment.expect @@ -1,6 +1,6 @@ 2 ( 3 foobar && # comment 1 -4 barfoo ?!AMP?! # wrong position for && +4 barfoo ?!LINT: missing '&&'?! # wrong position for && 5 flibble "not a # comment" 6 ) && 7 diff --git a/t/chainlint/loop-detect-failure.expect b/t/chainlint/loop-detect-failure.expect index 40c06f0d53..7d846b878d 100644 --- a/t/chainlint/loop-detect-failure.expect +++ b/t/chainlint/loop-detect-failure.expect @@ -11,5 +11,5 @@ 12 do 13 printf "%"$n"s" X > r2/large.$n && 14 git -C r2 add large.$n && -15 git -C r2 commit -m "$n" ?!LOOP?! +15 git -C r2 commit -m "$n" ?!LINT: missing '|| return 1'?! 16 done diff --git a/t/chainlint/loop-in-if.expect b/t/chainlint/loop-in-if.expect index 4e8c67c914..32e076ad1b 100644 --- a/t/chainlint/loop-in-if.expect +++ b/t/chainlint/loop-in-if.expect @@ -3,10 +3,10 @@ 4 then 5 while true 6 do -7 echo "pop" ?!AMP?! -8 echo "glup" ?!LOOP?! -9 done ?!AMP?! +7 echo "pop" ?!LINT: missing '&&'?! +8 echo "glup" ?!LINT: missing '|| exit 1'?! +9 done ?!LINT: missing '&&'?! 10 foo -11 fi ?!AMP?! +11 fi ?!LINT: missing '&&'?! 12 bar 13 ) diff --git a/t/chainlint/multi-line-string.expect b/t/chainlint/multi-line-string.expect index 62c54e3a5e..9d33297525 100644 --- a/t/chainlint/multi-line-string.expect +++ b/t/chainlint/multi-line-string.expect @@ -3,7 +3,7 @@ 4 line 2 5 line 3" && 6 y="line 1 -7 line2" ?!AMP?! +7 line2" ?!LINT: missing '&&'?! 8 foobar 9 ) && 10 ( diff --git a/t/chainlint/negated-one-liner.expect b/t/chainlint/negated-one-liner.expect index a6ce52a1da..0a6f3c29b2 100644 --- a/t/chainlint/negated-one-liner.expect +++ b/t/chainlint/negated-one-liner.expect @@ -1,5 +1,5 @@ 2 ! (foo && bar) && 3 ! (foo && bar) >baz && 4 -5 ! (foo; ?!AMP?! bar) && -6 ! (foo; ?!AMP?! bar) >baz +5 ! (foo; ?!LINT: missing '&&'?! bar) && +6 ! (foo; ?!LINT: missing '&&'?! bar) >baz diff --git a/t/chainlint/nested-cuddled-subshell.expect b/t/chainlint/nested-cuddled-subshell.expect index 0191c9c294..fec2c74274 100644 --- a/t/chainlint/nested-cuddled-subshell.expect +++ b/t/chainlint/nested-cuddled-subshell.expect @@ -5,7 +5,7 @@ 6 7 (cd foo && 8 bar -9 ) ?!AMP?! +9 ) ?!LINT: missing '&&'?! 10 11 ( 12 cd foo && @@ -13,13 +13,13 @@ 14 15 ( 16 cd foo && -17 bar) ?!AMP?! +17 bar) ?!LINT: missing '&&'?! 18 19 (cd foo && 20 bar) && 21 22 (cd foo && -23 bar) ?!AMP?! +23 bar) ?!LINT: missing '&&'?! 24 25 foobar 26 ) diff --git a/t/chainlint/nested-here-doc.expect b/t/chainlint/nested-here-doc.expect index 70d9b68dc9..571f4c9514 100644 --- a/t/chainlint/nested-here-doc.expect +++ b/t/chainlint/nested-here-doc.expect @@ -18,7 +18,7 @@ 19 toink 20 INPUT_END 21 -22 cat <<-\EOT ?!AMP?! +22 cat <<-\EOT ?!LINT: missing '&&'?! 23 text goes here 24 data <<EOF 25 data goes here diff --git a/t/chainlint/nested-loop-detect-failure.expect b/t/chainlint/nested-loop-detect-failure.expect index c13c4d2f90..b4aaa621a2 100644 --- a/t/chainlint/nested-loop-detect-failure.expect +++ b/t/chainlint/nested-loop-detect-failure.expect @@ -2,8 +2,8 @@ 3 do 4 for j in 0 1 2 3 4 5 6 7 8 9; 5 do -6 echo "$i$j" >"path$i$j" ?!LOOP?! -7 done ?!LOOP?! +6 echo "$i$j" >"path$i$j" ?!LINT: missing '|| return 1'?! +7 done ?!LINT: missing '|| return 1'?! 8 done && 9 10 for i in 0 1 2 3 4 5 6 7 8 9; @@ -18,7 +18,7 @@ 19 do 20 for j in 0 1 2 3 4 5 6 7 8 9; 21 do -22 echo "$i$j" >"path$i$j" ?!LOOP?! +22 echo "$i$j" >"path$i$j" ?!LINT: missing '|| return 1'?! 23 done || return 1 24 done && 25 diff --git a/t/chainlint/nested-subshell-comment.expect b/t/chainlint/nested-subshell-comment.expect index f89a8d03a8..078c6f275f 100644 --- a/t/chainlint/nested-subshell-comment.expect +++ b/t/chainlint/nested-subshell-comment.expect @@ -6,6 +6,6 @@ 7 # minor numbers of cows (or do they?) 8 baz && 9 snaff -10 ) ?!AMP?! +10 ) ?!LINT: missing '&&'?! 11 fuzzy 12 ) diff --git a/t/chainlint/nested-subshell.expect b/t/chainlint/nested-subshell.expect index 811e8a7912..a8d85d5d5b 100644 --- a/t/chainlint/nested-subshell.expect +++ b/t/chainlint/nested-subshell.expect @@ -7,7 +7,7 @@ 8 9 cd foo && 10 ( -11 echo a ?!AMP?! +11 echo a ?!LINT: missing '&&'?! 12 echo b 13 ) >file 14 ) diff --git a/t/chainlint/not-heredoc.expect b/t/chainlint/not-heredoc.expect index 611b7b75cb..5d51705a7a 100644 --- a/t/chainlint/not-heredoc.expect +++ b/t/chainlint/not-heredoc.expect @@ -9,6 +9,6 @@ 10 echo ourside && 11 echo "=======" && 12 echo theirside && -13 echo ">>>>>>> theirs" ?!AMP?! +13 echo ">>>>>>> theirs" ?!LINT: missing '&&'?! 14 poodle 15 ) >merged diff --git a/t/chainlint/one-liner-for-loop.expect b/t/chainlint/one-liner-for-loop.expect index 49dcf065ef..e1fcbd3639 100644 --- a/t/chainlint/one-liner-for-loop.expect +++ b/t/chainlint/one-liner-for-loop.expect @@ -3,7 +3,7 @@ 4 cd dir-rename-and-content && 5 test_write_lines 1 2 3 4 5 >foo && 6 mkdir olddir && -7 for i in a b c; do echo $i >olddir/$i; ?!LOOP?! done ?!AMP?! +7 for i in a b c; do echo $i >olddir/$i; ?!LINT: missing '|| exit 1'?! done ?!LINT: missing '&&'?! 8 git add foo olddir && 9 git commit -m "original" && 10 ) diff --git a/t/chainlint/one-liner.expect b/t/chainlint/one-liner.expect index 9861811283..5deeb05070 100644 --- a/t/chainlint/one-liner.expect +++ b/t/chainlint/one-liner.expect @@ -2,8 +2,8 @@ 3 (foo && bar) | 4 (foo && bar) >baz && 5 -6 (foo; ?!AMP?! bar) && -7 (foo; ?!AMP?! bar) | -8 (foo; ?!AMP?! bar) >baz && +6 (foo; ?!LINT: missing '&&'?! bar) && +7 (foo; ?!LINT: missing '&&'?! bar) | +8 (foo; ?!LINT: missing '&&'?! bar) >baz && 9 10 (foo "bar; baz") diff --git a/t/chainlint/pipe.expect b/t/chainlint/pipe.expect index 1bbe5a2ce1..d947c76584 100644 --- a/t/chainlint/pipe.expect +++ b/t/chainlint/pipe.expect @@ -4,7 +4,7 @@ 5 baz && 6 7 fish | -8 cow ?!AMP?! +8 cow ?!LINT: missing '&&'?! 9 10 sunder 11 ) diff --git a/t/chainlint/semicolon.expect b/t/chainlint/semicolon.expect index 866438310c..2b499fbe70 100644 --- a/t/chainlint/semicolon.expect +++ b/t/chainlint/semicolon.expect @@ -1,19 +1,19 @@ 2 ( -3 cat foo ; ?!AMP?! echo bar ?!AMP?! -4 cat foo ; ?!AMP?! echo bar +3 cat foo ; ?!LINT: missing '&&'?! echo bar ?!LINT: missing '&&'?! +4 cat foo ; ?!LINT: missing '&&'?! echo bar 5 ) && 6 ( -7 cat foo ; ?!AMP?! echo bar && -8 cat foo ; ?!AMP?! echo bar +7 cat foo ; ?!LINT: missing '&&'?! echo bar && +8 cat foo ; ?!LINT: missing '&&'?! echo bar 9 ) && 10 ( 11 echo "foo; bar" && -12 cat foo; ?!AMP?! echo bar +12 cat foo; ?!LINT: missing '&&'?! echo bar 13 ) && 14 ( 15 foo; 16 ) && 17 (cd foo && 18 for i in a b c; do -19 echo; ?!LOOP?! +19 echo; ?!LINT: missing '|| exit 1'?! 20 done) diff --git a/t/chainlint/subshell-here-doc.expect b/t/chainlint/subshell-here-doc.expect index 5647500c82..e450caf948 100644 --- a/t/chainlint/subshell-here-doc.expect +++ b/t/chainlint/subshell-here-doc.expect @@ -6,7 +6,7 @@ 7 nevermore... 8 EOF 9 -10 cat <<EOF >bip ?!AMP?! +10 cat <<EOF >bip ?!LINT: missing '&&'?! 11 fish fly high 12 EOF 13 diff --git a/t/chainlint/subshell-one-liner.expect b/t/chainlint/subshell-one-liner.expect index 214316c6a0..265d996a21 100644 --- a/t/chainlint/subshell-one-liner.expect +++ b/t/chainlint/subshell-one-liner.expect @@ -3,17 +3,17 @@ 4 (foo && bar) | 5 (foo && bar) >baz && 6 -7 (foo; ?!AMP?! bar) && -8 (foo; ?!AMP?! bar) | -9 (foo; ?!AMP?! bar) >baz && +7 (foo; ?!LINT: missing '&&'?! bar) && +8 (foo; ?!LINT: missing '&&'?! bar) | +9 (foo; ?!LINT: missing '&&'?! bar) >baz && 10 11 (foo || exit 1) && 12 (foo || exit 1) | 13 (foo || exit 1) >baz && 14 -15 (foo && bar) ?!AMP?! +15 (foo && bar) ?!LINT: missing '&&'?! 16 -17 (foo && bar; ?!AMP?! baz) ?!AMP?! +17 (foo && bar; ?!LINT: missing '&&'?! baz) ?!LINT: missing '&&'?! 18 19 foobar 20 ) diff --git a/t/chainlint/token-pasting.expect b/t/chainlint/token-pasting.expect index 64f3235d26..387189b6de 100644 --- a/t/chainlint/token-pasting.expect +++ b/t/chainlint/token-pasting.expect @@ -2,13 +2,13 @@ 3 git config filter.rot13.clean ./rot13.sh && 4 5 { -6 echo "*.t filter=rot13" ?!AMP?! +6 echo "*.t filter=rot13" ?!LINT: missing '&&'?! 7 echo "*.i ident" 8 } >.gitattributes && 9 10 { -11 echo a b c d e f g h i j k l m ?!AMP?! -12 echo n o p q r s t u v w x y z ?!AMP?! +11 echo a b c d e f g h i j k l m ?!LINT: missing '&&'?! +12 echo n o p q r s t u v w x y z ?!LINT: missing '&&'?! 13 echo '$Id$' 14 } >test && 15 cat test >test.t && @@ -19,7 +19,7 @@ 20 git checkout -- test test.t test.i && 21 22 echo "content-test2" >test2.o && -23 echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?! +23 echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!LINT: missing '&&'?! 24 25 downstream_url_for_sed=$( 26 printf "%sn" "$downstream_url" | diff --git a/t/chainlint/unclosed-here-doc-indent.expect b/t/chainlint/unclosed-here-doc-indent.expect index f78e23cb63..156906c85a 100644 --- a/t/chainlint/unclosed-here-doc-indent.expect +++ b/t/chainlint/unclosed-here-doc-indent.expect @@ -1,4 +1,4 @@ 2 command_which_is_run && -3 cat >expect <<-\EOF ?!UNCLOSED-HEREDOC?! && +3 cat >expect <<-\EOF ?!LINT: unclosed heredoc?! && 4 we forget to end the here-doc 5 command_which_is_gobbled diff --git a/t/chainlint/unclosed-here-doc.expect b/t/chainlint/unclosed-here-doc.expect index 51304672cf..752c608862 100644 --- a/t/chainlint/unclosed-here-doc.expect +++ b/t/chainlint/unclosed-here-doc.expect @@ -1,5 +1,5 @@ 2 command_which_is_run && -3 cat >expect <<\EOF ?!UNCLOSED-HEREDOC?! && +3 cat >expect <<\EOF ?!LINT: unclosed heredoc?! && 4 we try to end the here-doc below, 5 but the indentation throws us off 6 since the operator is not "<<-". diff --git a/t/chainlint/while-loop.expect b/t/chainlint/while-loop.expect index 5ffabd5a93..2ba5582165 100644 --- a/t/chainlint/while-loop.expect +++ b/t/chainlint/while-loop.expect @@ -1,14 +1,14 @@ 2 ( 3 while true 4 do -5 echo foo ?!AMP?! -6 cat <<-\EOF ?!LOOP?! +5 echo foo ?!LINT: missing '&&'?! +6 cat <<-\EOF ?!LINT: missing '|| exit 1'?! 7 bar 8 EOF -9 done ?!AMP?! +9 done ?!LINT: missing '&&'?! 10 11 while true; do 12 echo foo && -13 cat bar ?!LOOP?! +13 cat bar ?!LINT: missing '|| exit 1'?! 14 done 15 ) diff --git a/t/helper/meson.build b/t/helper/meson.build new file mode 100644 index 0000000000..5e83884246 --- /dev/null +++ b/t/helper/meson.build @@ -0,0 +1,91 @@ +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-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-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, common_main], +) +bin_wrappers += test_tool +test_dependencies += test_tool + +test_fake_ssh = executable('test-fake-ssh', + sources: 'test-fake-ssh.c', + dependencies: [libgit, common_main], +) +bin_wrappers += test_fake_ssh +test_dependencies += test_fake_ssh diff --git a/t/helper/test-config.c b/t/helper/test-config.c index e193079ed5..33247f0e92 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -96,7 +96,8 @@ int cmd__config(int argc, const char **argv) struct config_set cs; if (argc == 3 && !strcmp(argv[1], "read_early_config")) { - read_early_config(early_config_cb, (void *)argv[2]); + read_early_config(the_repository, early_config_cb, + (void *)argv[2]); return 0; } diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c index 4f010d5324..b2e70837a9 100644 --- a/t/helper/test-dump-untracked-cache.c +++ b/t/helper/test-dump-untracked-cache.c @@ -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 14b2b0c12c..85a69a4e55 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-parse-options.c b/t/helper/test-parse-options.c index 5250913d99..5da359486c 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -282,14 +282,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 +321,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 0ead529167..a1af9710c3 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 fd6e6cc4a5..3129aa28fd 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "test-tool.h" #include "abspath.h" #include "environment.h" diff --git a/t/helper/test-proc-receive.c b/t/helper/test-proc-receive.c index 29361c7aab..3703f734f3 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-reach.c b/t/helper/test-reach.c index 995e382863..84deee604a 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -127,10 +127,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,6 +155,7 @@ 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; @@ -176,7 +179,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 d285c656bd..e277dde8e7 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 9018c9f541..811dde1cb3 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 438fb9fc61..fc63236961 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 65346dee55..240f6fc29d 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -199,7 +199,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 5c8849d115..3c72ed985b 100644 --- a/t/helper/test-reftable.c +++ b/t/helper/test-reftable.c @@ -156,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--) @@ -167,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 7e1d9e0ee4..ff407b575c 100644 --- a/t/helper/test-rot13-filter.c +++ b/t/helper/test-rot13-filter.c @@ -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-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c index 6ca069ce63..6dce957153 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/interop/README b/t/interop/README index 72d42bd856..4e0608f857 100644 --- a/t/interop/README +++ b/t/interop/README @@ -83,3 +83,10 @@ You can then use test_expect_success as usual, with a few differences: should create one with the appropriate version of git. At the end of the script, call test_done as usual. + +Some older versions may need a few build knobs tweaked (e.g., ancient +versions of Git no longer build with modern OpenSSL). Your script can +set MAKE_OPTS_A and MAKE_OPTS_B, which will be passed alongside +GIT_INTEROP_MAKE_OPTS. Users can override them per-script by setting +GIT_INTEROP_MAKE_OPTS_{A,B} in the environment, just like they can set +GIT_TEST_VERSION_{A,B}. diff --git a/t/interop/i5500-git-daemon.sh b/t/interop/i5500-git-daemon.sh index 4d22e42f84..88712d1b5d 100755 --- a/t/interop/i5500-git-daemon.sh +++ b/t/interop/i5500-git-daemon.sh @@ -2,6 +2,7 @@ VERSION_A=. VERSION_B=v1.0.0 +MAKE_OPTS_B="NO_OPENSSL=TooOld" : ${LIB_GIT_DAEMON_PORT:=5500} LIB_GIT_DAEMON_COMMAND='git.a daemon' diff --git a/t/interop/interop-lib.sh b/t/interop/interop-lib.sh index 62f4481b6e..1b5864d2a7 100644 --- a/t/interop/interop-lib.sh +++ b/t/interop/interop-lib.sh @@ -45,7 +45,7 @@ build_version () { ( cd "$dir" && - make $GIT_INTEROP_MAKE_OPTS >&2 && + make $2 $GIT_INTEROP_MAKE_OPTS >&2 && touch .built ) || return 1 @@ -76,9 +76,11 @@ generate_wrappers () { VERSION_A=${GIT_TEST_VERSION_A:-$VERSION_A} VERSION_B=${GIT_TEST_VERSION_B:-$VERSION_B} +MAKE_OPTS_A=${GIT_INTEROP_MAKE_OPTS_A:-$MAKE_OPTS_A} +MAKE_OPTS_B=${GIT_INTEROP_MAKE_OPTS_B:-$MAKE_OPTS_B} -if ! DIR_A=$(build_version "$VERSION_A") || - ! DIR_B=$(build_version "$VERSION_B") +if ! DIR_A=$(build_version "$VERSION_A" "$MAKE_OPTS_A") || + ! DIR_B=$(build_version "$VERSION_B" "$MAKE_OPTS_B") then echo >&2 "fatal: unable to build git versions" exit 1 diff --git a/t/lib-bundle.sh b/t/lib-bundle.sh index cf7ed818b2..62b7bb13c8 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-gettext.sh b/t/lib-gettext.sh index cc6bb2cdea..7a734c6973 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_TEST_POPATH" 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 ea28971e8e..2fde2353fd 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 1f32ca66ea..7f9808ec20 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 } diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh index add11e88fc..3845b6ac44 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 11d2dc9fe3..0dd764310d 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 b4d7788f4e..477e0fdc04 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 22232247ef..aed0a4dd44 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 0000000000..13fe854ba0 --- /dev/null +++ b/t/meson.build @@ -0,0 +1,1114 @@ +clar_test_suites = [ + 'unit-tests/ctype.c', + 'unit-tests/strvec.c', +] + +clar_sources = [ + 'unit-tests/clar/clar.c', + 'unit-tests/unit-test.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, common_main], +) +test('unit-tests', clar_unit_tests) + +unit_test_programs = [ + 'unit-tests/t-example-decorate.c', + 'unit-tests/t-hash.c', + 'unit-tests/t-hashmap.c', + 'unit-tests/t-mem-pool.c', + 'unit-tests/t-oid-array.c', + 'unit-tests/t-oidmap.c', + 'unit-tests/t-oidtree.c', + 'unit-tests/t-prio-queue.c', + '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-reftable-tree.c', + 'unit-tests/t-strbuf.c', + 'unit-tests/t-strcmp-offset.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-oid.c', + 'unit-tests/lib-reftable.c', + unit_test_program, + ], + dependencies: [libgit, common_main], + ) + 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', + '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', + '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', + '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', + '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', +] + +# 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/p5311-pack-bitmaps-fetch.sh b/t/perf/p5311-pack-bitmaps-fetch.sh index 426fab87e3..047efb995d 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/p5332-multi-pack-reuse.sh b/t/perf/p5332-multi-pack-reuse.sh index 5c6c575d62..d1c89a8b7d 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 0000000000..069f91ce49 --- /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 c3f9a4caa4..90164327e8 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 ab0c763411..8ab6d9c469 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/run-test.sh b/t/run-test.sh index 13c353b91b..63328ac630 100755 --- a/t/run-test.sh +++ b/t/run-test.sh @@ -10,7 +10,7 @@ case "$1" in echo >&2 "ERROR: TEST_SHELL_PATH is empty or not set" exit 1 fi - exec "${TEST_SHELL_PATH}" "$@" + exec "${TEST_SHELL_PATH}" "$@" ${TEST_OPTIONS} ;; *) exec "$@" diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 98b81e4d63..35c5c2b4f9 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 0178aa62a4..72a0c2e7d4 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' ' diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index bf3bf604ab..dfbcdddbcc 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 66ccb5889d..3c98b622f2 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 8114fac73b..3bdafbae0f 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 eba75a2490..afba0fc3fc 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 fd373e1b39..53ced36df4 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 9fc5882387..2b60317758 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 02a18d4fdb..c9376dffb5 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 84172a3739..45229f57b8 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/t0013-sha1dc.sh b/t/t0013-sha1dc.sh index 08814173cb..ce3d81227a 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 f3a16859cc..32fe848179 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 fac52322a7..f68e08d0b1 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 19a730c29e..3a4e1cc7e3 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 81946e87cc..fd1cae09ed 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 eeb2714d9d..3f6433d304 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 9fe9891251..9bd863a970 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 575805513a..f9bbb91f64 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 a7f4de4a43..44958cb2c2 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 f7202c192e..2e28feb69c 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 f426a185bb..493b01a0e7 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 2f57c8669c..49dbf09da7 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 ad151a3467..50b3b4649b 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 4e8e90dd98..baa1b7e85b 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 f10f42ff1e..43155f6bd8 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 e97a84764f..e103fe7109 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 d3cb2a1cb9..ae7ef092ab 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 45a773642f..2fe3522305 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 1464294bd1..a0f6f134c7 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 325eb1c3cd..5c9dc90d0b 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 1a36a53574..ff98be31a5 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 c3eb1158ef..d0740038b8 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 752aa8c945..2630e756da 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 0afa3d0d31..dbb2e73bcd 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() { diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 20986b693c..76d4936a87 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 b9480c8178..8e215867b8 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 1fee6d9010..aac63ba506 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 7d0a0da8c0..df3e9f5fa5 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 0188d0423a..7bab49f361 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 95019e01ed..f2f3e50031 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 0ecec2ba71..6b9dcf984b 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 ba8ad1d1ca..2236a7e956 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 3c369c88e2..3db10f095c 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 67b11216a3..5a628bf735 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 d8e2fc42e1..ab80c9ef13 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 fca39048fe..e11d819b62 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' ' diff --git a/t/t0092-diagnose.sh b/t/t0092-diagnose.sh index 133e5747d6..6cabd6e67b 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 c8d84ab606..8f0c3b7325 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 70a3223f21..dd5d9b4e5e 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 878aadd64c..023b4c6f0b 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 522fb2ae69..8853d8afb9 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 8724ce1052..6c74df0dc6 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 5a6f28051b..b15cb65d5d 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 47d96a2a13..5085a0eda5 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 86cff324ff..0ce1f22eff 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 310a450012..28d92bb9b7 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 b9adc94aab..eff9a59dbd 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. diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index 070fe7a5da..bac9046540 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. @@ -337,7 +336,8 @@ test_expect_success 'expect def_params for query command' ' # remote-curl.c rather than git.c. Confirm that we get def_param # events from both layers. # -test_expect_success 'expect def_params for remote-curl and _run_dashed_' ' +test_expect_success LIBCURL \ + 'expect def_params for remote-curl and _run_dashed_' ' test_when_finished "rm prop.perf actual" && test_config_global "trace2.configParams" "cfg.prop.*" && @@ -366,7 +366,8 @@ test_expect_success 'expect def_params for remote-curl and _run_dashed_' ' # an executable built from http-fetch.c. Confirm that we get # def_param events from both layers. # -test_expect_success 'expect def_params for http-fetch and _run_dashed_' ' +test_expect_success LIBCURL \ + 'expect def_params for http-fetch and _run_dashed_' ' test_when_finished "rm prop.perf actual" && test_config_global "trace2.configParams" "cfg.prop.*" && diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh index 147643d582..1211db9f46 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 30a9f51e9f..7146476c69 100644 --- a/t/t0212/parse_events.perl +++ b/t/t0212/parse_events.perl @@ -204,7 +204,7 @@ while (<>) { } # 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 6a76b7fdbd..17952e52d6 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 diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh index 5d5b64205f..dc30289f75 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 f83db659e2..c1cd60edd0 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 8aadbe86c4..72ae405c3e 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 34bdb3ab1f..2a5bdbeeb8 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 932bf2067d..196fc61784 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 69917d7b84..853101b86e 100755 --- a/t/t0450-txt-doc-vs-help.sh +++ b/t/t0450-txt-doc-vs-help.sh @@ -5,7 +5,6 @@ test_description='assert (unbuilt) Documentation/*.txt and -h output Run this with --debug to see a summary of where we still fail to make the two versions consistent with one another.' -TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: list of builtins' ' @@ -56,14 +55,11 @@ txt_to_synopsis () { fi && b2t="$(builtin_to_txt "$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; }' \ diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh index 1eb3a8306b..d1a498a216 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 20df336cc3..1e62c791d9 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 d8cbd3f202..aa7f6ecd81 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 71a4d1a5ae..d4a08b823b 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 @@ -18,75 +17,583 @@ test_expect_success 'ref name should be checked' ' 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 37510c2b2a..4618ffc108 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) @@ -423,6 +422,73 @@ test_expect_success 'ref transaction: fails gracefully when auto compaction fail ) ' +test_expect_success 'ref transaction: timeout acquiring tables.list lock' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + >.git/reftable/tables.list.lock && + test_must_fail git update-ref refs/heads/branch HEAD 2>err && + test_grep "cannot lock references" err + ) +' + +test_expect_success 'ref transaction: retry acquiring tables.list lock' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + LOCK=.git/reftable/tables.list.lock && + >$LOCK && + { + ( sleep 1 && rm -f $LOCK ) & + } && + git -c reftable.lockTimeout=5000 update-ref refs/heads/branch HEAD + ) +' + +# 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. 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) && + for i in $(test_seq 100) + do + printf "%s commit\trefs/heads/branch-%s\n" "$head" "$i" || + return 1 + done >expect && + printf "%s commit\trefs/heads/main\n" "$head" >>expect && + + for i in $(test_seq 100) + do + { git update-ref refs/heads/branch-$i HEAD& } || + return 1 + done && + + wait && + git for-each-ref --sort=v:refname >actual && + test_cmp expect actual + ) +' + test_expect_success 'pack-refs: compacts tables' ' test_when_finished "rm -rf repo" && git init repo && diff --git a/t/t0611-reftable-httpd.sh b/t/t0611-reftable-httpd.sh index 2805995cc8..5e05b9c1f2 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 84922153ab..d0d7e80b49 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 b1c6c97524..e2708e11d5 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 0e8c0dfbbe..b9dd21cfb6 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 48a1550371..4a88bb9ef0 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 a7c2ed0d7c..df6ef53725 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 c860c08ecb..66e2bf4aec 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 2b9720b0fe..11bf10424f 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 26be4a2b5a..6b5033d0ce 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 d36cd7c086..ff9bf213aa 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 () { diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh index d73a5cc237..a0481139de 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 ad5936e54d..4512fb0b6e 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 fc179ac5dd..2935f68f8d 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 22875ba598..c291a2b33d 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 595b24c0ad..742f0fa909 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 cde93d22cd..57f0770df1 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 cf8b94ebed..bfc90d4cf2 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 8ea8d36818..0c0e6da5cf 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 da737a32a2..9b965d0294 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 be3206a16f..e88362fbe4 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 45eef9457f..9fdbb2af80 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 69bf9476cb..0b892894eb 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 cca4380e43..d390d7d5f8 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 ed638f6644..c71932b024 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 f6709c9f56..361afb679b 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 5e0f0a334f..502a5ea1c5 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 da0e7714d5..3a14218b24 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 8c5cd651b4..ab3a105fff 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 eb32da2a7f..a4c7c41fc0 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 0f37a43fd3..ae66ba5bab 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 f13277c8f3..51a85e83c2 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 29cf8a9661..630a47af21 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 42caa0d297..69723b88ff 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 0506f3d6bb..d971925ed0 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 31b89dd969..c69ae41306 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 5cde79ef8c..8ff2b0c232 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 @@ -357,4 +356,44 @@ test_expect_success 'include cycles are detected' ' grep "exceeded maximum include depth" stderr ' +test_expect_success 'onbranch with unborn branch' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config set includeIf.onbranch:"*".path config.inc && + git config set -f .git/config.inc foo.bar baz && + git config get foo.bar + ) +' + +test_expect_success 'onbranch with detached HEAD' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config set "includeIf.onbranch:*.path" config.inc && + git config set -f .git/config.inc foo.bar baz && + test_commit initial && + git switch --detach HEAD && + test_must_fail git config get foo.bar + ) +' + +test_expect_success 'onbranch without repository' ' + test_when_finished "rm -f .gitconfig config.inc" && + git config set -f .gitconfig "includeIf.onbranch:**.path" config.inc && + git config set -f config.inc foo.bar baz && + git config get foo.bar && + test_must_fail nongit git config get foo.bar +' + +test_expect_success 'onbranch without repository but explicit nonexistent Git directory' ' + test_when_finished "rm -f .gitconfig config.inc" && + git config set -f .gitconfig "includeIf.onbranch:**.path" config.inc && + git config set -f config.inc foo.bar baz && + git config get foo.bar && + test_must_fail nongit git --git-dir=nonexistent config get foo.bar +' + test_done diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh index 53e5b290b9..40d3c42618 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 b9852fe40e..5cb546dd00 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 3bfec07f1a..e0e49053f0 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 523aa99a1e..9710ee0ca4 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 1a90d31201..69e64c6c86 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 ceeb7ac3a4..45a0492917 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 eb1691860d..e2316f1dd4 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 ' diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 5c60d6f812..a2a7e94716 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 5ed9d7318e..cabc516ae9 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 403f6b8f7d..9d698b3cc3 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 df90112618..28e6c380d7 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 a6bcd62ab6..6d8f401a2a 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 c01f0f14a1..9b9e5d0766 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 48b1c92a41..9d8e1a1343 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 9469c79a58..41ba1f1d7f 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 7748973733..e3c501848a 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 246a3f46ab..388fdf9ae5 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 da581ec19a..975c4ea83a 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 ff30874f94..f7d69b66ff 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 d2a4822d46..934688a1ee 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 eb4eec8bec..51d79bae83 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 5a812ca3c0..8c777f7cf8 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 0eb5e674bc..2f37402536 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 2268bca3c1..d51ecd5e92 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 3256e4462f..c04eeb7211 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 dbe15a0be1..2fb2f44f02 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 0c00118c2b..3ab65f72cd 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 280cbf3e03..8a456b1142 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 3413da40e4..3a3d33f405 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 f7c0783d30..1bfff3a7af 100755 --- a/t/t1460-refs-migrate.sh +++ b/t/t1460-refs-migrate.sh @@ -5,7 +5,6 @@ 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 test_migration () { @@ -237,7 +236,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 30c31918fd..58a4583088 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 ae6528aece..8c94ac2e70 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 5eaa6428c4..3962f1d288 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 79df65ec7f..75a708f9ba 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 c1679e31d8..e04420f436 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 4a5758f08a..2803ca9489 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 ef40511d89..722884e65f 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 b9af6b3ac0..cb9ef7e329 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 e841309d0e..87a4286414 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 591505a39c..bbfe05b8e4 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 e7e78a4028..6ecfed86bc 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 f9d68ce74e..70f1e0a998 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 ba43387bf1..5f437be8c9 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 a835a196aa..d868a08110 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 cdb26a30d7..75e89c4b6e 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 990a036582..dbd8cd6906 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' ' @@ -98,7 +97,7 @@ test_expect_success 'stripspace outside repository' ' nongit git stripspace -s </dev/null ' -test_expect_success 'remote-http outside repository' ' +test_expect_success LIBCURL 'remote-http outside repository' ' test_must_fail git remote-http 2>actual && test_grep "^error: remote-curl" actual && ( diff --git a/t/t1600-index.sh b/t/t1600-index.sh index 62e7fd1596..03239e9faa 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 5dcc101882..a45a8b4eb0 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 d8fa489998..5dc221ef38 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 8b0234cf2d..4feaf0d7be 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 79fc97f1d7..f18616ad2b 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 fc95cf9048..70361c806e 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 f0fd441d81..ff163cf675 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 98e818f09f..b92d96fdc4 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 67d18cfa10..91b08e0371 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 570ba38580..bac231b167 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 bd9e9e7530..6f0b90ce12 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 8a518a44ea..eadb9434ae 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 71195dd28f..b0540636ae 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 82c3bfeac1..3a3d56018e 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 04f53b1ea1..61417c7567 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 4b6372f4c3..1f6c4ed042 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 3c1d663d94..b2bdd1fcb4 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 c138bdde4f..3e757c6e4e 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 fb0e13881c..1820300c62 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 c40b661ac1..c4f9bf09aa 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 a5c7358eea..80ac661815 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 43551cc148..a48ebdbf4d 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 c67261e2b6..1fcef4be95 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 8d90d02850..28bbbe6c05 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 ecfacf0f7f..a5c03d5d4a 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 f1b709d58b..c49ba7f9bd 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 81e772fb4e..7b327b7544 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 2caada3d83..a3b1449ef1 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 246609d54d..dda169bbc4 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 acd55217a6..161da054b6 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 98f16c7239..a397790df5 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 b3f6bc97b5..be3fcdde07 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 1f193cde96..21f4659a9d 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 77b2346291..c91c4db936 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 ac404945d4..16d6348b69 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 42d5522119..27e85be40a 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 86c9c88788..8198a1e578 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 59e5570cb2..5ffe1a41e2 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 6acdb89d12..f6fcfc0c1e 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 aec55496eb..79fb11f139 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 7915e7b821..2df3fdde8b 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 e3c7acdbf9..6c32d42c8c 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 c49cdfb6e5..9b11130ab9 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 e9451cd567..6938ecca86 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 7ec7f30b44..7a0778ed98 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 963ebe77eb..a7f3d47aec 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 95c004dc5c..6b2ccc21a9 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 f0eab13f96..cc72ead79f 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 bc5f2886fa..b31dd8ece5 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 df235ac306..06e83d3333 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 dba62d69c6..687be974d4 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 24c60bfd79..9ee659098c 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 8fa44a92a2..192ad14b5f 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 b7cf1e492c..31eb233df5 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 98265ba1b4..43d950de64 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 b40eeb263f..c8de6d8a19 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 cfc4aeb179..90638fa886 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 71aa9bcd62..fe671d4197 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 33ea9cb21b..8ef1cad7f2 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 901342ea09..0bb33e8b1b 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 842937bfb9..9536d10919 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 1d7f605633..11018f37c7 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 edbf502ec5..f5f19b3169 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 f6835c91dc..57c201869f 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 714feb83be..5c0bf4d21f 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 8af4e8cfe3..f6d8d7d03d 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 11af4552f7..13f66fd649 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 1ed0aa967e..4b67646285 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 4dd24550eb..31462cb441 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 7933dff9b3..ac3c811f46 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 12e41a7b40..a1078f8701 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 fbfa210a50..db13aabf62 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 2aaf91ebc8..22c7256c3a 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 f04bdc8c78..61771eec83 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 51d3dffaa6..85f3704958 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 14218b3424..963f3462b7 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 054178703d..7af4532cd1 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 190e2f6eed..2682b1f43a 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 6e6ea0b6f3..8bdaacd85a 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 133593d23c..ac82c9cee8 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 bd65dfcffc..768d702fbb 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 3884694165..f1f09abdd9 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 5a06732ca7..eb69da61fe 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 4dd42df38c..3da824117c 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 436de44971..8f294d9832 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 5af2dac0e4..ac44525810 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 3942db2290..1e16c6b8ea 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 81c6343962..e7636f6908 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 3adb206a93..a1b2069a25 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 ce2391e28b..8bdf400682 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 ccfa6a720d..a3a21c54cf 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 @@ -1697,7 +1696,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 6e587d27d7..800fc33165 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 3b6dad0c46..a1139f79e2 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 e627f08a17..500c9d0e72 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 diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh index 594e3e43e1..3399344f25 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 0b61da92b3..da1c202fa7 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 86010931ab..d2ca43d6aa 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 diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh index 9cbc34fc58..37b9d26f4b 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 d3ac826283..f5bf16abcd 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 99137fb235..d6c50460d0 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 d0c4d38b4d..bb5fea02a0 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 bc9b791d1b..eac193757b 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 2c3a245266..03dfcd3954 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 1ec1fb6715..fcecdc94ff 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 b6e9f643e3..8f4102ff9e 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 ae316502c4..1aa366a410 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 e1d05ff6bc..202702be1a 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 f55277f499..9bd5dbf341 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 04866b89be..597df5ebc0 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 ce4144db0f..5b675417e9 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 0fd33280cf..96243b7222 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 beca346056..c4a7839540 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 bd8bcc381a..c0c00fbb7b 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 @@ -145,7 +144,9 @@ test_expect_success 'Show verbose error when HEAD could not be detached' ' test_when_finished "rm -f B" && test_must_fail git rebase topic 2>output.err >output.out && test_grep "The following untracked working tree files would be overwritten by checkout:" output.err && - test_grep B output.err + test_grep B output.err && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err ' test_expect_success 'fail when upstream arg is missing and not on branch' ' @@ -428,7 +429,9 @@ test_expect_success 'refuse to switch to branch checked out elsewhere' ' git checkout main && git worktree add wt && test_must_fail git -C wt rebase main main 2>err && - test_grep "already used by worktree at" err + test_grep "already used by worktree at" err && + test_must_fail git -C wt rebase --quit 2>err && + test_grep "no rebase in progress" err ' test_expect_success 'rebase when inside worktree subdirectory' ' @@ -452,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 328c1d3a3f..f18bae9450 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 5c67d07ba3..761de63b6b 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 4f1d6e8ea6..a1911c4a9d 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 f171af3061..ecfc02062c 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,23 @@ 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 'no uncommitted changes when rewording and the todo list is reloaded' ' @@ -1003,8 +1022,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 +1034,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 +1058,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 +1071,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 +1894,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 +1905,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 +1941,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 +2201,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 +2258,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 8979bc3407..2524331861 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 82108b67e6..a1d7fa7f7c 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 2c3f38d45a..9f49c4228b 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 7b4607d72f..cde3562e3a 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 acaf5558db..83ffb39d9f 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 e75b3d0e07..58371d8a54 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 e8456831e8..b4ff614987 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 ' @@ -110,7 +109,9 @@ test_expect_success 'pre-rebase hook stops rebase (1)' ' git reset --hard side && test_must_fail git rebase main && test "z$(git symbolic-ref HEAD)" = zrefs/heads/test && - test 0 = $(git rev-list HEAD...side | wc -l) + test 0 = $(git rev-list HEAD...side | wc -l) && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err ' test_expect_success 'pre-rebase hook stops rebase (2)' ' diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index 22452ff84c..fcc40d6fe1 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 f8c4ed78c9..ea501f2b42 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 22ee3a2045..96f2cf22fa 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 c0d29c2154..127216f722 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 6c61f240cf..7181f176b8 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 63e400b89f..ad3ba6a984 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 ' @@ -82,6 +81,46 @@ testrebase () { type=$1 dotest=$2 + test_expect_success "rebase$type: restore autostash when pre-rebase hook fails" ' + git checkout -f feature-branch && + test_hook pre-rebase <<-\EOF && + exit 1 + EOF + + echo changed >file0 && + test_must_fail git rebase $type --autostash -f HEAD^ && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err && + echo changed >expect && + test_cmp expect file0 + ' + + test_expect_success "rebase$type: restore autostash when checkout onto fails" ' + git checkout -f --detach feature-branch && + echo uncommitted-content >file0 && + echo untracked >file4 && + test_when_finished "rm file4" && + test_must_fail git rebase $type --autostash \ + unrelated-onto-branch && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err && + echo uncommitted-content >expect && + test_cmp expect file0 + ' + + test_expect_success "rebase$type: restore autostash when branch checkout fails" ' + git checkout -f unrelated-onto-branch^ && + echo uncommitted-content >file0 && + echo untracked >file4 && + test_when_finished "rm file4" && + test_must_fail git rebase $type --autostash HEAD \ + unrelated-onto-branch && + test_must_fail git rebase --quit 2>err && + test_grep "no rebase in progress" err && + echo uncommitted-content >expect && + test_cmp expect file0 + ' + test_expect_success "rebase$type: dirty worktree, --no-autostash" ' test_config rebase.autostash true && git reset --hard && diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index 737af80bb3..f5b7807abd 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 b40f26250b..b9408f9ba1 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 2fab703d61..4859bb8f72 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 515c949ae3..1ee6b00fd5 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 a16428bdf5..675491234a 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 94ea88e384..ba069dccbd 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 365436ebfc..6f57aed9fa 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 8e0d03969a..abd66f3602 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 2aa8593f77..2593711fec 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 && diff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh index 0bb284d61d..be09fc78c1 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 7f1a5dd3de..5086e14c02 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 c8172b0852..05df964670 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 26a48d6b10..8c94fdffc4 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 6e329fea7c..6aa2aeb628 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/t3437-rebase-fixup-options.sh b/t/t3437-rebase-fixup-options.sh index 7929e2e2e3..5d306a4769 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 821f08e5af..78d42f4c79 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 61ca87512d..78c3eac54b 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 411027fb58..8025a28cfd 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 1b2c0d6aca..5495eacfec 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 76d393dc8a..95fe4feaee 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 597c98e9c5..18aeba161c 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 ead3fb4680..9748443530 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 b71bad17b8..7e11bd4a4c 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 10e9c91dbb..44596cb1e8 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 afa7727a4a..2d53ce754c 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 171cc6d76b..f4159246e1 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 93c725bac3..66ff9db270 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 dd5d92ef30..98ef13f0a3 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 9387a22a9e..f22d1ddead 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 e178968b40..8bfe3ed246 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 31ac31d4bc..98259e2ada 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 7cef12981c..31bd9960fc 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 fcdefba48c..02c7acd617 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 12bd3db4cb..389670262e 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 839c904745..df580a5806 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 718438ffc7..b8a05d95f3 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 82bfb2fd2a..8bacacbac6 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 d84071038e..3ef525a559 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 3aa59f6f63..b9c96e273f 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 6ae45a788d..53a4782267 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 d3e428ff46..e3cf0ffbe5 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 db7b403bc1..3c930ec202 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 5f0b9afc3f..f03601b49a 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 72a5a565e9..f528008c36 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 c87592ee2f..74666ff3e4 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 aa5019fd6c..ae313e3c70 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 a1733f45c3..1289ae3e07 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 0f61f01ef4..0f7348ec21 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 7a2eb98b86..10914bba7b 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 347a89b030..2b2b366ef9 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 50ae222f08..e2e1251a05 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 8d50331b8c..a51f881b1c 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 cd1931dd55..4f520d600d 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 cb3307010c..e44648e6f3 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 ebe091828c..fd4faee5d2 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 1d70d4d221..faf3465deb 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 5c756dc243..92d1141fbe 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 dbd4c0da21..2299b91fc4 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 b86165cbac..e8faf0dd2e 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 562aaf3a2a..c187c52dab 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 3480781dab..59e71e3acd 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 9d9650eba7..c84c3fa05b 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 bc8ba88719..ac837b6c9e 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 c64d9d2f40..d1d30ac2a9 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 87d248d034..3855d68dbc 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 1c46e963e4..884f83fb8a 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 851cfe4f32..52e3e476ff 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 5a8d887683..876271d682 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 d644310e22..c2863c99b7 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' ' @@ -145,6 +144,14 @@ test_expect_success 'option errors are not confused by --exit-code' ' for option in --exit-code --quiet do + test_expect_success "git diff $option returns 1 for changed binary file" " + test_when_finished 'rm -f .gitattributes' && + git reset --hard && + echo a binary >.gitattributes && + echo 2 >>a && + test_expect_code 1 git diff $option + " + test_expect_success "git diff $option returns 1 for copied file" " git reset --hard && cp a copy && diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 8128c30e7f..e026fac1f4 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 d2b3109c2d..4001dacee3 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 3baa52a9bf..f1efe482a5 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 1219aa226d..9be65fd444 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 e2f0eca4af..b98ac0a0c0 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 5397cb7d42..c39bb07a41 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 b05f2a9b60..08f6805e1c 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 40164ae07d..295da987cc 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 60cb819c42..a06a747926 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 5f8ffef74b..32b6e9a4e7 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 29f6d610c2..daebf9796f 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 7db92d0d9f..bada0cbd32 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 f7be7f5ef0..113304dc59 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 4dcd7e9925..f51d3557f1 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 76f8034c60..0352bf81a9 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 48655bcc78..98d9713d8b 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 b5f96fe23b..f5ce3b29a2 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 78090e6852..0eb0314a8b 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 eec3d73dc2..1b27a0e381 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 8fc40e75eb..28f9d83d4c 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 a179205394..ff0e73531b 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 e486493908..2a2cf91352 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 9f6043daba..8400bfbd3c 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 9b46c4c1be..2c8493fe66 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 afda629c98..7c27f05366 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 7b73462d53..a7ce8d3161 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 f399484bce..0260cf64f5 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 0a4fc735d4..eceb47c859 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 c61b30f96d..fd3e86a74f 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 725278ad19..4838a1df8b 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 7badd72488..740bb97091 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 651ec77660..5e5bad61ca 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 05c88f8cdf..1131431fe0 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 3ea9ae99e0..f7ff234cf9 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 9a7505cbb8..04b8a1542a 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 2501c89c1c..2fce4a9897 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 668f526303..0fe81056d5 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 8ce67442d9..76b83101d3 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 2942e5d9b9..7750b87ca1 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 a90b46b678..8ad3d79957 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 7e6c9d6384..50fdb5ea52 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 846f285f77..e86bba679e 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 647537c12e..b3f510f040 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 0ecb391541..a1de63b77f 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 7af3a08862..581250dd2d 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 4d6565e728..eff63c16b0 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 df342850a0..c6c94aef14 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 d503547732..146e73d8f5 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 @@/' diff --git a/t/t4101-apply-nonl.sh b/t/t4101-apply-nonl.sh index b1169193ef..4df74baa24 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 d1e06fc1ac..e42a31c917 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 144619ab87..d370ecfe0d 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 dc501aac38..71ef4132d1 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 ed814a839e..b59785166d 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 5c150f3b0b..aa2fff7afa 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 ac72eeaf27..94ba6dd4e0 100755 --- a/t/t4107-apply-ignore-whitespace.sh +++ b/t/t4107-apply-ignore-whitespace.sh @@ -3,9 +3,8 @@ # Copyright (c) 2009 Giuseppe Bilotta # -test_description='git-apply --ignore-whitespace. +test_description='git-apply --ignore-whitespace.' -' . ./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 3211e1e65f..f30e85659d 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 () { @@ -82,6 +81,46 @@ test_expect_success 'apply with --3way with merge.conflictStyle = diff3' ' test_apply_with_3way ' +test_apply_with_3way_favoritism () { + apply_arg=$1 + merge_arg=$2 + + # Merging side should be similar to applying this patch + git diff ...side >P.diff && + + # The corresponding conflicted merge + git reset --hard && + git checkout main^0 && + git merge --no-commit $merge_arg side && + git ls-files -s >expect.ls && + print_sanitized_conflicted_diff >expect.diff && + + # should apply successfully + git reset --hard && + git checkout main^0 && + git apply --index --3way $apply_arg P.diff && + git ls-files -s >actual.ls && + print_sanitized_conflicted_diff >actual.diff && + + # The result should resemble the corresponding merge + test_cmp expect.ls actual.ls && + test_cmp expect.diff actual.diff +} + +test_expect_success 'apply with --3way --ours' ' + test_apply_with_3way_favoritism --ours -Xours +' + +test_expect_success 'apply with --3way --theirs' ' + test_apply_with_3way_favoritism --theirs -Xtheirs +' + +test_expect_success 'apply with --3way --union' ' + echo "* merge=union" >.gitattributes && + test_apply_with_3way_favoritism --union && + rm .gitattributes +' + test_expect_success 'apply with --3way with rerere enabled' ' test_config rerere.enabled true && diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh index 4dc6d8e7d3..ac523a5d56 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 266302a182..cc17ff2ab9 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 e9a87d761d..1618a6dbc7 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 d53aa4222e..bb5d529bec 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 2c65c6a169..66fa51591e 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 8ff3640766..da3e64f811 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 cbef0a593f..769b0e4f9d 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 a9f4ddda6c..0784ba033a 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 4d15ccd28e..c86d05a96f 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 69c9c48e72..c1dcbd7d35 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 208c961d37..f3b43e2216 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 f788428540..697e86c0ff 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 a80cec9d11..b45454aaf4 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 2089d84f64..3340ab4370 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 3601c0c5dc..3ef84619f5 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/t4126-apply-empty.sh b/t/t4126-apply-empty.sh index 56210b5609..eff783f8d6 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 aa5cfae2b6..bd516c4aad 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 ed94c90204..f6db5a79dd 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 87ffd2b8e1..2149ad5da4 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 f3ea632742..211ef1c7e7 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 40c92115a6..b1361ce546 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 c1e3049c04..ab1628d27d 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 c21ddb2946..3cab1038cf 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 aceb4c42b0..8cea75cf7b 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 d3502c6fdd..6bc3fb97a7 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 dfec1c5f0f..82f2f2e475 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 ebd0d4ad17..07d5262537 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/t4139-apply-escape.sh b/t/t4139-apply-escape.sh index e5c7439df1..e07fb9ef08 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 b375aca0d7..c614eaf04c 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 20cc1209f6..eac6f7e151 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 232e1394e8..5e2b6c80ea 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 1825a89d6a..edb38da701 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 9f2edba1f8..768495b131 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 dd6ad8f7a8..9bec989a0e 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 213b36fb96..b0a3e84984 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 c20c885724..5f23fc147b 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 2265ff8872..2421491931 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' ' diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index dc8ddb10af..605faea0c7 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -114,46 +114,6 @@ test_expect_success 'patch-id supports git-format-patch output' ' test "$2" = $(git rev-parse HEAD) ' -test_expect_success 'patch-id computes the same for various formats' ' - # This test happens to consider "git log -p -1" output - # the canonical input format, so use it as the norm. - git log -1 -p same >log-p.output && - git patch-id <log-p.output >expect && - - # format-patch begins with "From <commit object name>" - git format-patch -1 --stdout same >format-patch.output && - git patch-id <format-patch.output >actual && - test_cmp actual expect && - - # "diff-tree --stdin -p" begins with "<commit object name>" - same=$(git rev-parse same) && - echo $same | git diff-tree --stdin -p >diff-tree.output && - git patch-id <diff-tree.output >actual && - test_cmp actual expect && - - # "diff-tree --stdin -v -p" begins with "commit <commit object name>" - echo $same | git diff-tree --stdin -p -v >diff-tree-v.output && - git patch-id <diff-tree-v.output >actual && - test_cmp actual expect -' - -hash=$(git rev-parse same:) -for cruft in "$hash" "commit $hash is bad" "From $hash status" -do - test_expect_success "patch-id with <$cruft> in log message" ' - git format-patch -1 --stdout same >patch-0 && - git patch-id <patch-0 >expect && - - { - sed -e "/^$/q" patch-0 && - printf "random message\n%s\n\n" "$cruft" && - sed -e "1,/^$/d" patch-0 - } >patch-cruft && - git patch-id <patch-cruft >actual && - test_cmp actual expect - ' -done - test_expect_success 'whitespace is irrelevant in footer' ' get_patch_id main && git checkout same && diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index eb63ce011f..f81e42a84d 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 9167b0351f..bcab71c8e8 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 73ea9e5155..2e83cc820a 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 2a46eb6bed..806b2809d4 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 b42fdc54fc..a675ace081 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 () { diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index 7120030b5c..26dda0db38 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 02d76dca28..950451cf6a 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 e6b59123a3..64d818bc70 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 590fce95e9..53a4af3244 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 7905597869..f70c46bbbf 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 b877ac7235..28d0779a8c 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 613f0710e9..6e01e2629c 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 5b680dc755..bda8822b3d 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 2bcdd9f34f..0ee69d2a0c 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 661feb6070..ae0a56cf5e 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 04f3ccfc41..a7ba08f728 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 92d8c8b651..ac9db285f3 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 f26d7fd2db..30a565cbea 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 3573c9147f..201915b45a 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 9c197260d5..27fbe193bc 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 37f1cd7364..eea19907b5 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 7abba8a4b2..5465054f17 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 @@ -137,6 +136,8 @@ test_expect_success 'end-of-options is correctly eaten' ' test_expect_success 'populate workdir' ' mkdir a && + echo "a files_named_a" >.gitattributes && + git add .gitattributes && echo simple textfile >a/a && ten=0123456789 && hundred="$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten" && @@ -450,6 +451,16 @@ test_expect_success 'allow pathspecs that resolve to the current directory' ' test_cmp expect actual ' +test_expect_success 'attr pathspec in bare repo' ' + test_expect_code 0 git --git-dir=bare.git archive -v HEAD \ + ":(attr:files_named_a)" >/dev/null 2>actual && + cat >expect <<-\EOF && + a/ + a/a + EOF + test_cmp expect actual +' + # Pull the size and date of each entry in a tarfile using the system tar. # # We'll pull out only the year from the date; that avoids any question of diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh index 7310774af5..e745076441 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 78ab75f1bc..97c93f6c44 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 01f591c99b..961c6aac25 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 9f2c6da80e..50344e17ca 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 065156c1f3..e57e1ae739 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 86bee33160..cb67bac1c4 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 ed9dfd624c..8365907055 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 3b9dae331a..53dc3cbf90 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 && @@ -630,11 +632,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" ' diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 226490d60d..ff6b5159a3 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 d88e6f1691..413c99274c 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 61469ef4a6..de58ca654a 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 e641df0116..1f1f664871 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 dc8fe55c82..44bd9ef45f 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 0d50c6b4bc..805d60ff31 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 1e02c305c4..fa4bc269fe 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 655cafa054..0f84137867 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 4e910c5b9d..60fc710bac 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 a6de7c5764..eabfcd7ff6 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -502,6 +502,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 4fe71fe8cd..012852c156 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 d8d2e30468..c37ef3818d 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 86fc73f9fb..5be01260d7 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 82734b9a3c..9cd18c1e6b 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 c80ea9e8b7..8bacd96275 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 eb4ef3dda4..32cf422745 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 79552d6ef7..501d715b9a 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 2916c07e3c..f68f64cd85 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 fbbc218d04..0f215ad2e8 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 406363381f..2c961c7096 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 70770fe274..51aaca1fcf 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 770695c927..d39958c066 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/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 77e91547ea..a32be3867d 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 431a603ca0..285c8b4a49 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 832b92619c..d27557b9b0 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 fc6a242b56..a766a3e3f8 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 fc5fedbe9b..b71a0aef40 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 5eb28f0512..313eadba98 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 2dcf1eecee..b48c0cbe8f 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 955ea42769..57cad7708f 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/t5334-incremental-multi-pack-index.sh b/t/t5334-incremental-multi-pack-index.sh index c3b08acc73..26257e5660 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 43cbcd5d49..d76eb4be93 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 248c74d8ef..3f81f16e13 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 3c1ea6086e..723d1e17ec 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 ' diff --git a/t/t5402-post-merge-hook.sh b/t/t5402-post-merge-hook.sh index 46ebdfbeeb..915af2de95 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 cfaae54739..978f240cda 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 51737eeafe..cc07889667 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 1686ac13aa..11f03239a0 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 d6a9946633..dcbeb42082 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 e99e728236..ad7f8c6f00 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 c3695a4d4e..526a675045 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 516b22fd96..fa5de4500a 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 7a45d4c311..0b28e4e452 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 0e37535065..78d0b63876 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 b9a05181f1..df5fc212be 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 585ea0ee16..2677cd5faa 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 0c8668a1b8..66f19a4ef2 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 7b3ff21b98..b160f8b7fb 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 5ebbaa4896..195fc64dd4 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: diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 138e6778a4..8212a70be8 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' ' @@ -171,7 +170,7 @@ test_expect_success 'fsck with invalid or bogus skipList input' ' 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)' ' @@ -234,7 +233,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 @@ -263,7 +262,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 532035933f..519f7973e3 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,16 @@ 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 'add --mirror=fetch' ' mkdir mirror-fetch && git init -b main mirror-fetch/parent && @@ -712,8 +808,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 +829,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 +844,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 +876,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 +890,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 +902,7 @@ test_expect_success 'update default' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -806,7 +911,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 +925,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 && diff --git a/t/t5506-remote-groups.sh b/t/t5506-remote-groups.sh index 0e176175a3..16e9a1bc2f 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 c6a6957c50..a41d5b370b 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 f029ae0d28..095df1a753 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 0890b9f61c..2d9587059f 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 @@ -75,6 +74,168 @@ 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 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 +326,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 && diff --git a/t/t5511-refspec.sh b/t/t5511-refspec.sh index fc55681a3f..be025b90f9 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 d64b40e408..5930f55186 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 @@ -406,6 +407,7 @@ test_expect_success 'v0 clients can handle multiple symrefs' ' test_expect_success 'helper with refspec capability fails gracefully' ' mkdir test-bin && write_script test-bin/git-remote-foo <<-EOF && + read capabilities echo import echo refspec ${SQ}*:*${SQ} EOF diff --git a/t/t5513-fetch-track.sh b/t/t5513-fetch-track.sh index c46c4dbaef..65d1e05bd6 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 579872c258..523aff6268 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 c100a809c5..320d26796d 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 () { diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9d693eb57f..041d7d806f 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1394,7 +1394,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 6d4944a728..a448e169bd 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 c13120088f..5c4ac2556e 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 72e97b15fa..20ba604dfd 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 1098cbd0a1..47534f1062 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 db00c4336b..5e420c208c 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 cc5496e28f..9fb73a8c3e 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 4ad36a31e1..22d3e1162c 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 56716e29dd..b2be3605f5 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 3a28f1ded5..45815f7378 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/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh index 98ece27c6a..0de8eb5b6f 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 bc2bada34c..2bd8759a68 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 17d7257892..80b06a0cd2 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 7172780d55..558eedf25a 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 f3fff55744..05debd1134 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -203,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 d664912799..3755822629 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/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh index 7122af7fdb..e8f6d233ff 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 2dcbe79052..23bf696170 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/t5543-atomic-push.sh b/t/t5543-atomic-push.sh index 479d103469..04b47ad84a 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 () { diff --git a/t/t5544-pack-objects-hook.sh b/t/t5544-pack-objects-hook.sh index 1a9e14bbcc..89147a052e 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 9fc9ba552f..f1e61c9f09 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 9f899b8c7d..0798ddab02 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 ecb3877aa4..6282728eaf 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 diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index ea8e48f627..21795a19bf 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -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 7b5ab0eae1..ceb3336a5c 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -186,6 +186,28 @@ test_expect_success 'clone from password-protected repository' ' test_cmp expect actual ' +test_expect_success 'credential.interactive=false skips askpass' ' + set_askpass bogus nonsense && + ( + GIT_TRACE2_EVENT="$(pwd)/interactive-true" && + export GIT_TRACE2_EVENT && + test_must_fail git clone --bare "$HTTPD_URL/auth/smart/repo.git" interactive-true-dir && + test_region credential interactive interactive-true && + + GIT_TRACE2_EVENT="$(pwd)/interactive-false" && + export GIT_TRACE2_EVENT && + test_must_fail git -c credential.interactive=false \ + clone --bare "$HTTPD_URL/auth/smart/repo.git" interactive-false-dir && + test_region ! credential interactive interactive-false && + + GIT_TRACE2_EVENT="$(pwd)/interactive-never" && + export GIT_TRACE2_EVENT && + test_must_fail git -c credential.interactive=never \ + clone --bare "$HTTPD_URL/auth/smart/repo.git" interactive-never-dir && + test_region ! credential interactive interactive-never + ) +' + test_expect_success 'clone from auth-only-for-push repository' ' echo two >expect && set_askpass wrong && diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh index b55a9f65e6..eeddb85b1d 100755 --- a/t/t5552-skipping-fetch-negotiator.sh +++ b/t/t5552-skipping-fetch-negotiator.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='test skipping fetch negotiator' + . ./test-lib.sh test_expect_success 'fetch.negotiationalgorithm config' ' diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh index 33e919a17e..70e3376d31 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 06991e8e8a..17e73b606d 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 3dcb3340a3..e47ea1ad10 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 76a4bbd16a..67fcc23f11 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 cd05321e17..3816ed5058 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 f75068de64..d30cf4f5b8 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 e1d3b8caed..9c57d84315 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 7ee9858a78..f3b158274c 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 9babb9a375..211e29fade 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 ba03f6a09f..317f33af5a 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 4aef99bc28..b27e481f95 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 c5f08b6799..8df4001b72 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 448134c4bf..a11b20e378 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 916e58c166..f7650e8475 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 ab05f38a99..a76b54d7de 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 f7707326ea..5883839a04 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 d7537a162b..65ef1a3628 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 724f610054..cded79c16b 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 7a80e47c2b..ae32f8178a 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 320f49c753..e7e1b6dab6 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 c814afa565..34b3df4027 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 5d7ea147f1..d0c18660e3 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 56329aa160..cbcceab9d5 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 8ca1f09423..80eb4e04f8 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 9b32db8478..470bfb610c 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 d9a320abd2..4605703496 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 e93e0d0cc3..8a15237736 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 7ceaa8194d..82e3621ec5 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 252e1f7c20..f86a674a03 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 022ed3d87c..a7ec21eda5 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 298d4befab..4873089a8c 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 72762de977..3126cfd7e9 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 7708cbafa9..c752804a8e 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 c2a2bb453e..0c85ef834a 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 83513e46a3..9d6aa2187f 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 8415884754..4650451964 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -693,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 5a4d7936a7..6884338249 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 f905db0a3f..2fb6d549d3 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/t5701-git-serve.sh b/t/t5701-git-serve.sh index c48830de8f..de904c1655 100755 --- a/t/t5701-git-serve.sh +++ b/t/t5701-git-serve.sh @@ -5,7 +5,6 @@ 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' ' diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 1ef540f73d..d3df81e785 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 f75fae52c8..191097171b 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 11be64fc03..2b33fced23 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 b8a722ec27..ed38c76c29 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/t5750-bundle-uri-parse.sh b/t/t5750-bundle-uri-parse.sh index 81bdf58b94..80a3f83ffb 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/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 20f43f7b7d..d21877150e 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -344,4 +344,15 @@ test_expect_success 'fetch tag' ' compare_refs local v1.0 server v1.0 ' +test_expect_success 'totally broken helper reports failure message' ' + write_script git-remote-broken <<-\EOF && + read cap_cmd + exit 1 + EOF + test_must_fail \ + env PATH="$PWD:$PATH" \ + git clone broken://example.com/foo.git 2>stderr && + grep aborted stderr +' + test_done diff --git a/t/t5802-connect-helper.sh b/t/t5802-connect-helper.sh index dd3e6235cd..a7be375bce 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 862610256f..96a2c46e7a 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 ed773e7432..b0061e6a37 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 f69959c64c..96187efaa8 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 2e975dc70e..045e2fe6ce 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 6fe1a98b2a..9587a842bc 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 fe899ee82d..081a07cbae 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 a84faac242..923fc90f87 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 f6d17ee902..6289a2e8b0 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 3553bbbfe7..73a2465aa0 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 162cf50778..daa009c9a1 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 5cf2cee74d..0d7055d46d 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 ee0306aeec..6cde997e13 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 f1623b1c06..eb93d68d7d 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 2d337d7287..6f3e543977 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 2cdef6fdf9..a0a070b404 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 91db8fafe8..9c9a8459af 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 f96ea82e78..44c726ea39 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 b2e422cf0f..bad02cf5b8 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/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh index 4128269c1d..39793cbbd6 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 16b8bd1d09..c9bedd29cb 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 a0a40fe55c..4821b90e74 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 3b181f771c..bb55c7e3c3 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 34b5cd62c2..4ce62feaa2 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 @@ -505,6 +504,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 51df02105d..5fe942a293 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 127180e1c9..7553a9cca2 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 diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh index acc281c116..0b719bbae6 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 3946e18089..82013fc903 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 d7702fc756..aa1b535187 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 1a8b64cce1..e6b3e6ec77 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 88ed7bd75a..e934bc239c 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 d20723d627..5f55ab98d3 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 5d28507efc..22dfd6d978 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 ddefc7f24e..13c1da5352 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 a9656a1ec8..902854cbfa 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 44246f8a63..a584522ef2 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 21c4a211b1..3385fe9f13 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 05ed2510d9..3f6160d702 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 && @@ -617,7 +620,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' ' # B # o -# \ +# H \ # o-----o---o----x # A # @@ -627,6 +630,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 +643,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 +663,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 +671,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 +715,14 @@ 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_done diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh index 82de25d549..a7f2603cb4 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 770cce026c..e64d938083 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/t6133-pathspec-rev-dwim.sh b/t/t6133-pathspec-rev-dwim.sh index 6dd4bbbf9f..0f722fb340 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 16ce4cfcc6..9b62a0a65f 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 120dcd74a5..67d8c72147 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='test labels in pathspecs' + . ./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 2db37a6596..1284fe0143 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 5a221f8ef1..011e5df1e6 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -607,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 8d15713cc6..a5c7794385 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -769,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) && @@ -1560,6 +1560,25 @@ test_trailer_option '%(trailers:separator,key_value_separator) changes both sepa Reviewed-by,A U Thor <author@example.com>,Signed-off-by,A U Thor <author@example.com> EOF +test_expect_success 'multiple %(trailers) use their own options' ' + git tag -F - tag-with-trailers <<-\EOF && + body + + one: foo + one: bar + two: baz + two: qux + EOF + t1="%(trailers:key=one,key_value_separator=W,separator=X)" && + t2="%(trailers:key=two,key_value_separator=Y,separator=Z)" && + git for-each-ref --format="$t1%0a$t2" refs/tags/tag-with-trailers >actual && + cat >expect <<-\EOF && + oneWfooXoneWbar + twoYbazZtwoYqux + EOF + test_cmp expect actual +' + test_failing_trailer_option () { title=$1 option=$2 cat >expect @@ -1835,6 +1854,24 @@ sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)" sig_crlf=${sig_crlf%dummy} test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf" +test_expect_success 'set up tag with signature and trailers' ' + git tag -F - fake-sig-trailer <<-\EOF + this is the subject + + this is the body + + My-Trailer: foo + -----BEGIN PGP SIGNATURE----- + + not a real signature, but we just care about the + subject/body/trailer parsing. + -----END PGP SIGNATURE----- + EOF +' + +# use "separator=" here to suppress the terminating newline +test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo' + test_expect_success 'git for-each-ref --stdin: empty' ' >in && git for-each-ref --format="%(refname)" --stdin <in >actual && @@ -2003,8 +2040,7 @@ test_expect_success GPG 'show good signature with custom format' ' --format="$GRADE_FORMAT" >actual && test_cmp expect actual ' -test_expect_success GPGSSH 'show good signature with custom format - with ssh' ' +test_expect_success GPGSSH 'show good signature with custom format with ssh' ' test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && cat >expect.tmpl <<-\EOF && diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh index 83b8a19d94..e06feb06e9 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 163c378cfd..bb02b86c16 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -13,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 @@ -342,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 @@ -378,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 27d6efdc9a..3de4ef6bd9 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 1962310408..c8e5ff28e8 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 729aac9842..2738b50c2a 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 fb872c5a11..06ab4d7aed 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 36215518b6..ae687f2ce5 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 29e2b25ce5..7435fce71e 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 9bf9524934..66e01464b5 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 0753fc95f4..e8a28717ce 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 8a1ba6d23a..7763c1ba98 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/t6411-merge-filemode.sh b/t/t6411-merge-filemode.sh index b6182723aa..6ae2489286 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 d0863a8fb5..ca018d11f5 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 647ea1e838..cd6adf6caa 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 69fc1c9e69..d7e3c1fa6e 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 ae00492c76..2655e295f5 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 5f414abc89..17b54d625d 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 482b73a998..62d1406119 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 48a62cb855..41288a60ce 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 30349a466e..b99f29ef9b 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 80d7b5eaba..62b49c67e2 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/t6425-merge-rename-delete.sh b/t/t6425-merge-rename-delete.sh index b95b064311..c15d031b16 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 62f0180325..b059475ed0 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 a13271b349..dd5fe6a402 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 8a79bc2e92..9919c3fa7c 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 cb1c4ceef7..0f39ed0d08 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 555f00f78a..ca15e6dd6d 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 3fe14cd73e..3824756a02 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 c93538b0c3..db4b77e63d 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 ed7866d3e9..0f611c4003 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 df1d0c156c..a11707835b 100755 --- a/t/t6434-merge-recursive-rename-options.sh +++ b/t/t6434-merge-recursive-rename-options.sh @@ -29,7 +29,6 @@ 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 78628fb248..fde4aa3cd1 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 ccc620477d..4f4376421e 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 7a3f1cb27c..4815559157 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 3594190af8..8df67a0ef9 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 0cbec57cda..55bd744a3f 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/t6501-freshen-objects.sh b/t/t6501-freshen-objects.sh index 4521508b83..ddef1ca391 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/t6700-tree-depth.sh b/t/t6700-tree-depth.sh index 9e70a7c763..0f6a2ad9b5 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 86258f9f43..25334b5062 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 57969ce805..4d3f221224 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 b1316e62f4..10835631ca 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 b9822294fe..5fcf281dfb 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 a0296d6ca4..932c26cb45 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 f908a4d1ab..d6cc69e0f2 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 0ce8fd2c89..93fbc92b8d 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 d9add2162e..520f96d09f 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 4adac5acd5..1ff2714cb4 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 d984200c17..cd5c20fe51 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 effa826744..6f526c37c2 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 20913b3713..80359d48f7 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 aaeb4a5334..0f4344c55e 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 caf372a3d4..73709dbeee 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 06c1301222..8bbc5ce6d9 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 89cf98b30c..33d5d5b76e 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 2add26d768..0503a64d3f 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 18bbd9975e..871e438118 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 cf9697eba9..7948ec392b 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 f4f3b7a677..fced8adabd 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 88d1c8adf4..df20c0f0cc 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 020db201d5..9162f591fb 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 7ee180f81d..61669a2d21 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 ' diff --git a/t/t7111-reset-table.sh b/t/t7111-reset-table.sh index 01b7c3503c..07b919731a 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 b0d3d93b0b..a3e2413bc3 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 58e55a7c77..c10d94fe3d 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 2d984eb4c6..9bcf7c0b40 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 0aae0dee67..00d4070156 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 4afe53c66a..f743e5b8f4 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 098d8833b6..d6a501d453 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 542b3331a7..9c3cc4cf40 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 aa2fdc31d1..25b33a1e87 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 19b6135d11..bf97d4f851 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/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh index d6040e0a33..f860e7bbf4 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 574a6fc526..374ed481e9 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 f778321857..0490499573 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 887d181b72..9509dc18fd 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 24f30e3bf9..e2d75c7f16 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 2ab566e717..0c605fd271 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 dbbb3853dc..5e3051da8b 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 e1d9bf2ee3..dde11ecce8 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 a5d1bc5c54..08ed51d34f 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 479c8fdde1..ce64d8b137 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 ab946ec940..f21e920367 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 @@ -167,4 +166,11 @@ 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)" +' + test_done diff --git a/t/t7423-submodule-symlinks.sh b/t/t7423-submodule-symlinks.sh index f45d806201..3d3c7af3ce 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 b43ef2ba67..559713b607 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 4a9c22c9e2..9367794641 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 52f5e28154..cc12f99f11 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 aa004b70a8..ad1eb64ba0 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 d1255228d5..c0f024eb1e 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 b88383df9e..2128142a61 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 46566d529e..185fe7e78e 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 4c7db19ce7..b53d71c086 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 773383fefb..b2070d4e39 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 fd8c8f8f0b..8e373b566b 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 4ffa45a7bf..b5fdc048a5 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 cdd5f2c697..802f8f704c 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 0f7d8938d9..818a8dafbd 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 03ba0c0e73..075db69b42 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 e3d6bb67bf..9f989be01b 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 bb95f09810..de7c4ca790 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 efc6496e2b..163ae80468 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 b37de0af49..d3ea4d603f 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 3b63c34a30..bcfe15d51d 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 47b2f1dc22..82b5e4aa41 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 a9210d3a3a..d409de1a33 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 c97c550021..3aabbf35a1 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 730f3c7f81..409cd0cd12 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 65fd3d8552..ef54cff4fa 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 diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index a94387a75f..199a1d5db3 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 3669d33bd5..ff085b086c 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 0e85b21ec8..4887ca705b 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 diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index eca7555101..cd4f9607dc 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 62d935d31c..5d56c38546 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 135cb23085..81fb7c474c 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 9001674f2e..89a62ac53b 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 2179938c43..0b908ab2e7 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 8b1c3bd39f..e8e205707e 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_TEST_MERGE_TOOLS_DIR"/vimdiff && run_unit_tests ' diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 22b3a85b3e..c077aba7ce 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 992a8f9874..d6975ca48d 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' ' diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh index 84ddb56851..337fac0d84 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 cf96a35e8e..fee258d4f0 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 9a83be518c..3b1aad0167 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/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh index fe6c3e77a3..5715f4d69a 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= diff --git a/t/t7702-repack-cyclic-alternate.sh b/t/t7702-repack-cyclic-alternate.sh index f3cdb98eec..cd91766e78 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/t7704-repack-cruft.sh b/t/t7704-repack-cruft.sh index 5db9f4e10f..959e6e2648 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 cc917b257e..9b74db5563 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 af2cf2f78a..64ac4f04ee 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 fe38d88a1a..3160be59fd 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 31c66b63c2..ac7be54714 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 1227885737..701e08a8e5 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 ac871287c0..90ebb64f46 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 4353be5adb..0088eaa0c9 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 0ba7817fb7..eb59564565 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 abae7a9754..1909aed95e 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 && @@ -825,6 +842,9 @@ test_expect_success 'start and stop Linux/systemd maintenance' ' test_systemd_analyze_verify "systemd/user/git-maintenance@daily.service" && test_systemd_analyze_verify "systemd/user/git-maintenance@weekly.service" && + grep "core.askPass=true" "systemd/user/git-maintenance@.service" && + grep "credential.interactive=false" "systemd/user/git-maintenance@.service" && + printf -- "--user enable --now git-maintenance@%s.timer\n" hourly daily weekly >expect && test_cmp expect args && @@ -991,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 3596634039..0147de304b 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' diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 6288352f57..731265541a 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 2c2a0b33f9..35414a5336 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 75da219ed1..81847ffb9a 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 42f8be25a3..07a287ffd3 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 c8266f17f1..c3735fb50d 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 fb5d225a67..c12a4196d6 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 30331713b9..c808b81962 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 eb64b766bd..b3be2aa387 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 da1801f4d2..c66494f5ba 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 9a79c109f2..c3a5f6d01f 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 d33788d867..370b768149 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 933222cea1..f5dcbd9e82 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/t9001-send-email.sh b/t/t9001-send-email.sh index df5336bb7e..0c1af43f6f 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 @@ -1324,7 +1323,7 @@ test_expect_success $PREREQ 'cc list is sanitized' ' Reviewed-by: Füñný Nâmé <odd_?=mail@example.com> Reported-by: bugger on Jira Reported-by: Douglas Reporter <doug@example.com> [from Jira profile] - BugID: 12345 + BugID: 12345should-not-appear Co-developed-by: "C. O. Developer" <codev@example.com> Signed-off-by: A. U. Thor <thor.au@example.com> EOF @@ -1337,7 +1336,7 @@ test_expect_success $PREREQ 'cc list is sanitized' ' " <odd_?=mail@example.com>" actual-show-all-headers && test_grep "^(body) Ignoring Reported-by .* bugger on Jira" actual-show-all-headers && test_grep "^(body) Adding cc: Douglas Reporter <doug@example.com>" actual-show-all-headers && - test_grep ! "12345" actual-show-all-headers && + test_grep ! "12345should-not-appear" actual-show-all-headers && test_grep "^(body) Adding cc: \"C. O. Developer\" <codev@example.com>" actual-show-all-headers && test_grep "^(body) Adding cc: \"A. U. Thor\" <thor.au@example.com>" actual-show-all-headers ' diff --git a/t/t9002-column.sh b/t/t9002-column.sh index d5b98e615b..7353815c11 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 14a704d0a8..85a5074b5e 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' ' @@ -65,7 +64,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 52046e60d5..b2ee626b9a 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 3d4842164c..a44eabf0d8 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 e8613990e1..a81662713e 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 && @@ -194,8 +195,11 @@ test_expect_success 'scalar reconfigure' ' scalar reconfigure one && test true = "$(git -C one/src config core.preloadIndex)" && git -C one/src config core.preloadIndex false && - scalar reconfigure -a && - test true = "$(git -C one/src config core.preloadIndex)" + rm one/src/cron.txt && + GIT_TRACE2_EVENT="$(pwd)/reconfigure" scalar reconfigure -a && + test_path_is_file one/src/cron.txt && + test true = "$(git -C one/src config core.preloadIndex)" && + test_subcommand git maintenance start <reconfigure ' test_expect_success 'scalar reconfigure --all with includeIf.onbranch' ' @@ -216,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 7869f45ee6..01f71910f5 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 3b3c371740..b258dbf1df 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 58413221e6..1ae4d7c0d3 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 d8b1f9442e..ec8c8652c6 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 4f5bf40587..f15c8c0213 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 1f776a80f3..6c50adca00 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 1eb035ee4c..40427883ec 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 c0d9d7be75..156a647484 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 a67e6abd49..a34805acdc 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 ccfa415384..7679780fb8 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 c900231079..32814e75df 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 b41ea19331..81d5625557 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 41fcf3606b..5680849218 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 e007669495..116cddba3a 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 3768e3bd8c..e5266c9a87 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 2a387fdbaa..1ee966c256 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 9cf0685d56..57a3bef2ec 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 ccc8212d73..9c9e3b5eb1 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 @@ -45,7 +44,8 @@ test_expect_success 'set up test repository' ' ' test_expect_success 'set up bare repository' ' - git init --bare bare.git + git init --bare bare.git && + git -C bare.git --work-tree=. commit --allow-empty -m "bare commit" ' test_expect_success 'use t9700/test.pl to test Git.pm' ' diff --git a/t/t9700/test.pl b/t/t9700/test.pl index d8e85482ab..58a9b328d5 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; @@ -147,6 +147,11 @@ close TEMPFILE3; unlink $tmpfile3; chdir($abs_repo_dir); +# open alternate bare repo +my $r4 = Git->repository(Directory => "$abs_repo_dir/bare.git"); +is($r4->command_oneline(qw(log --format=%s)), "bare commit", + "log of bare repo works"); + # unquoting paths is(Git::unquote_path('abc'), 'abc', 'unquote unquoted path'); is(Git::unquote_path('"abc def"'), 'abc def', 'unquote simple quoted path'); diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh index 3e6dfce248..0816763e46 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 cdbfacc727..c598011635 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 1bc48305b0..df01a5d338 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 ab7fe16266..2913277013 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 c8963fd398..3236457106 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 72dce3d2b4..90ef647db7 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 e4ce44ebf3..c26d297433 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 342f7f3d4a..58a9b3b71e 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 f33fdea889..9c9710d8c7 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 15e32c9f35..5fe83315ec 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 52a4b0af81..5ac5383fb7 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 46aa5fd56c..254a7c2446 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 0efea28da2..fd018c87a8 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 00df6ebd3b..2a9838f37f 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 92ef9d8c24..c766fd159f 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 e687fbc25f..5e904ac80d 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 3deb334fed..ec3d937c6a 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 091bb72bdb..de591d875c 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 985be20357..b4d93f0c17 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 48e4dfb95c..fa1bba1dd9 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 49691c53da..ef80f1690b 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 e62ed49f51..572d395498 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 98a40d8af3..88b76dc4d6 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 d0b86537dd..6a60b32349 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 54083f842e..fd64afe064 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 3476ea2fd3..d3670bd7a2 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 7c8f9e3930..ca6c2942bd 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 3fc0948d9c..88cfb1fcd3 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 02561a7f0e..3fb6960c18 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 f287f41e37..ff6c0352e6 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 a266775408..6b3cb0414a 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 da1d30c142..e22369ccdf 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 565870fc74..dac67e89d7 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 ad20ffdede..036bf79c66 100755 --- a/t/t9835-git-p4-metadata-encoding-python2.sh +++ b/t/t9835-git-p4-metadata-encoding-python2.sh @@ -6,7 +6,6 @@ This test checks that the import process handles inconsistent text encoding in p4 metadata (author names, commit messages, etc) without failing, and produces maximally sane output in git.' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh python_target_version='2' diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh index 71ae763399..63350dc4b5 100755 --- a/t/t9836-git-p4-metadata-encoding-python3.sh +++ b/t/t9836-git-p4-metadata-encoding-python3.sh @@ -6,7 +6,6 @@ This test checks that the import process handles inconsistent text encoding in p4 metadata (author names, commit messages, etc) without failing, and produces maximally sane output in git.' -TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-p4.sh python_target_version='3' diff --git a/t/t9850-shell.sh b/t/t9850-shell.sh index cfc71c3bd4..36566ace21 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 19f56e5680..de7152f827 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 cc6aa9f0cd..51bd750837 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 95e9955bca..d667dda654 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 fde9bf54fc..78e054ab50 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_empty_ then test_ok_ "$1" else diff --git a/t/test-lib.sh b/t/test-lib.sh index 54247604cb..62dfcc4aaf 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 @@ -92,6 +86,15 @@ 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 +103,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 @@ -322,7 +332,6 @@ 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= TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX" test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY" case "$TRASH_DIRECTORY" in @@ -513,6 +522,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 +588,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 +811,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 +1179,19 @@ 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 - -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" +check_test_results_san_file_empty_ () { + test -z "$TEST_RESULTS_SAN_FILE" || + test "$(nr_san_dir_leaks_)" = 0 } check_test_results_san_file_ () { - if test -z "$TEST_RESULTS_SAN_FILE" + if check_test_results_san_file_empty_ 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 +1222,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 +1420,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 +1486,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,72 +1508,29 @@ 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" - then - 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_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 && test "${GIT_TEST_EXT_CHAIN_LINT:-1}" != 0 then "$PERL_PATH" "$TEST_DIRECTORY/chainlint.pl" "$0" || - BUG "lint error (see '?!...!? annotations above)" + BUG "lint error (see 'LINT' annotations above)" fi # Last-minute variable setup @@ -1763,6 +1687,7 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_CURL" && test_set_prereq LIBCURL +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 diff --git a/t/test-terminal.perl b/t/test-terminal.perl index b8fd6a4f13..862bb8f395 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/.gitignore b/t/unit-tests/.gitignore index 5e56e040ec..d0632ec7f9 100644 --- a/t/unit-tests/.gitignore +++ b/t/unit-tests/.gitignore @@ -1 +1,3 @@ /bin +/clar.suite +/clar-decls.h diff --git a/t/unit-tests/clar/.editorconfig b/t/unit-tests/clar/.editorconfig new file mode 100644 index 0000000000..aa343a4288 --- /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 new file mode 100644 index 0000000000..0065843d17 --- /dev/null +++ b/t/unit-tests/clar/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + strategy: + matrix: + 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.platform.os }} + + steps: + - name: Check out + uses: actions/checkout@v2 + - name: Build + run: | + 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 0000000000..84c048a73c --- /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 0000000000..12d4af114f --- /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/COPYING b/t/unit-tests/clar/COPYING new file mode 100644 index 0000000000..8983817f0c --- /dev/null +++ b/t/unit-tests/clar/COPYING @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2011-2015 Vicent Marti + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/t/unit-tests/clar/README.md b/t/unit-tests/clar/README.md new file mode 100644 index 0000000000..a8961c5f10 --- /dev/null +++ b/t/unit-tests/clar/README.md @@ -0,0 +1,329 @@ +Come out and Clar +================= + +In Catalan, "clar" means clear, easy to perceive. Using clar will make it +easy to test and make clear the quality of your code. + +> _Historical note_ +> +> Originally the clar project was named "clay" because the word "test" has its +> roots in the latin word *"testum"*, meaning "earthen pot", and *"testa"*, +> meaning "piece of burned clay"? +> +> This is because historically, testing implied melting metal in a pot to +> check its quality. Clay is what tests are made of. + +## Quick Usage Overview + +Clar is a minimal C unit testing framework. It's been written to replace the +old framework in [libgit2][libgit2], but it's both very versatile and +straightforward to use. + +Can you count to funk? + +- **Zero: Initialize test directory** + + ~~~~ sh + $ mkdir tests + $ cp -r $CLAR_ROOT/clar* tests + $ cp $CLAR_ROOT/test/clar_test.h tests + $ cp $CLAR_ROOT/test/main.c.sample tests/main.c + ~~~~ + +- **One: Write some tests** + + File: tests/adding.c: + + ~~~~ c + /* adding.c for the "Adding" suite */ + #include "clar.h" + + static int *answer; + + void test_adding__initialize(void) + { + answer = malloc(sizeof(int)); + cl_assert_(answer != NULL, "No memory left?"); + *answer = 42; + } + + void test_adding__cleanup(void) + { + free(answer); + } + + void test_adding__make_sure_math_still_works(void) + { + cl_assert_(5 > 3, "Five should probably be greater than three"); + cl_assert_(-5 < 2, "Negative numbers are small, I think"); + cl_assert_(*answer == 42, "The universe is doing OK. And the initializer too."); + } + ~~~~~ + +- **Two: Build the test executable** + + ~~~~ sh + $ cd tests + $ $CLAR_PATH/generate.py . + Written `clar.suite` (1 suites) + $ gcc -I. clar.c main.c adding.c -o testit + ~~~~ + +- **Funk: Funk it.** + + ~~~~ sh + $ ./testit + ~~~~ + +## The Clar Test Suite + +Writing a test suite is pretty straightforward. Each test suite is a `*.c` +file with a descriptive name: this encourages modularity. + +Each test suite has optional initialize and cleanup methods. These methods +will be called before and after running **each** test in the suite, even if +such test fails. As a rule of thumb, if a test needs a different initializer +or cleanup method than another test in the same module, that means it +doesn't belong in that module. Keep that in mind when grouping tests +together. + +The `initialize` and `cleanup` methods have the following syntax, with +`suitename` being the current suite name, e.g. `adding` for the `adding.c` +suite. + +~~~~ c +void test_suitename__initialize(void) +{ + /* init */ +} + +void test_suitename__cleanup(void) +{ + /* cleanup */ +} +~~~~ + +These methods are encouraged to use static, global variables to store the state +that will be used by all tests inside the suite. + +~~~~ c +static git_repository *_repository; + +void test_status__initialize(void) +{ + create_tmp_repo(STATUS_REPO); + git_repository_open(_repository, STATUS_REPO); +} + +void test_status__cleanup(void) +{ + git_repository_close(_repository); + git_path_rm(STATUS_REPO); +} + +void test_status__simple_test(void) +{ + /* do something with _repository */ +} +~~~~ + +Writing the actual tests is just as straightforward. Tests have the +`void test_suitename__test_name(void)` signature, and they should **not** +be static. Clar will automatically detect and list them. + +Tests are run as they appear on their original suites: they have no return +value. A test is considered "passed" if it doesn't raise any errors. Check +the "Clar API" section to see the various helper functions to check and +raise errors during test execution. + +__Caution:__ If you use assertions inside of `test_suitename__initialize`, +make sure that you do not rely on `__initialize` being completely run +inside your `test_suitename__cleanup` function. Otherwise you might +encounter ressource cleanup twice. + +## How does Clar work? + +To use Clar: + +1. copy the Clar boilerplate to your test directory +2. copy (and probably modify) the sample `main.c` (from + `$CLAR_PATH/test/main.c.sample`) +3. run the Clar mixer (a.k.a. `generate.py`) to scan your test directory and + write out the test suite metadata. +4. compile your test files and the Clar boilerplate into a single test + executable +5. run the executable to test! + +The Clar boilerplate gives you a set of useful test assertions and features +(like accessing or making sandbox copies of fixture data). It consists of +the `clar.c` and `clar.h` files, plus the code in the `clar/` subdirectory. +You should not need to edit these files. + +The sample `main.c` (i.e. `$CLAR_PATH/test/main.c.sample`) file invokes +`clar_test(argc, argv)` to run the tests. Usually, you will edit this file +to perform any framework specific initialization and teardown that you need. + +The Clar mixer (`generate.py`) recursively scans your test directory for +any `.c` files, parses them, and writes the `clar.suite` file with all of +the metadata about your tests. When you build, the `clar.suite` file is +included into `clar.c`. + +The mixer can be run with **Python 2.5, 2.6, 2.7, 3.0, 3.1, 3.2 and PyPy 1.6**. + +Commandline usage of the mixer is as follows: + + $ ./generate.py . + +Where `.` is the folder where all the test suites can be found. The mixer +will automatically locate all the relevant source files and build the +testing metadata. The metadata will be written to `clar.suite`, in the same +folder as all the test suites. This file is included by `clar.c` and so +must be accessible via `#include` when building the test executable. + + $ gcc -I. clar.c main.c suite1.c test2.c -o run_tests + +**Note that the Clar mixer only needs to be ran when adding new tests to a +suite, in order to regenerate the metadata**. As a result, the `clar.suite` +file can be checked into version control if you wish to be able to build +your test suite without having to re-run the mixer. + +This is handy when e.g. generating tests in a local computer, and then +building and testing them on an embedded device or a platform where Python +is not available. + +### Fixtures + +Clar can create sandboxed fixtures for you to use in your test. You'll need to compile *clar.c* with an additional `CFLAG`, `-DCLAR_FIXTURE_PATH`. This should be an absolute path to your fixtures directory. + +Once that's done, you can use the fixture API as defined below. + +## The Clar API + +Clar makes the following methods available from all functions in a test +suite. + +- `cl_must_pass(call)`, `cl_must_pass_(call, message)`: Verify that the given + function call passes, in the POSIX sense (returns a value greater or equal + to 0). + +- `cl_must_fail(call)`, `cl_must_fail_(call, message)`: Verify that the given + function call fails, in the POSIX sense (returns a value less than 0). + +- `cl_assert(expr)`, `cl_assert_(expr, message)`: Verify that `expr` is true. + +- `cl_check_pass(call)`, `cl_check_pass_(call, message)`: Verify that the + given function call passes, in the POSIX sense (returns a value greater or + equal to 0). If the function call doesn't succeed, a test failure will be + logged but the test's execution will continue. + +- `cl_check_fail(call)`, `cl_check_fail_(call, message)`: Verify that the + given function call fails, in the POSIX sense (returns a value less than + 0). If the function call doesn't fail, a test failure will be logged but + the test's execution will continue. + +- `cl_check(expr)`: Verify that `expr` is true. If `expr` is not + true, a test failure will be logged but the test's execution will continue. + +- `cl_fail(message)`: Fail the current test with the given message. + +- `cl_warning(message)`: Issue a warning. This warning will be + logged as a test failure but the test's execution will continue. + +- `cl_set_cleanup(void (*cleanup)(void *), void *opaque)`: Set the cleanup + method for a single test. This method will be called with `opaque` as its + argument before the test returns (even if the test has failed). + If a global cleanup method is also available, the local cleanup will be + called first, and then the global. + +- `cl_assert_equal_i(int,int)`: Verify that two integer values are equal. + The advantage of this over a simple `cl_assert` is that it will format + a much nicer error report if the values are not equal. + +- `cl_assert_equal_s(const char *,const char *)`: Verify that two strings + are equal. The expected value can also be NULL and this will correctly + test for that. + +- `cl_fixture_sandbox(const char *)`: Sets up a sandbox for a fixture + so that you can mutate the file directly. + +- `cl_fixture_cleanup(const char *)`: Tears down the previous fixture + sandbox. + +- `cl_fixture(const char *)`: Gets the full path to a fixture file. + +Please do note that these methods are *always* available whilst running a +test, even when calling auxiliary/static functions inside the same file. + +It's strongly encouraged to perform test assertions in auxiliary methods, +instead of returning error values. This is considered good Clar style. + +Style Example: + +~~~~ c +/* + * Bad style: auxiliary functions return an error code + */ + +static int check_string(const char *str) +{ + const char *aux = process_string(str); + + if (aux == NULL) + return -1; + + return strcmp(my_function(aux), str) == 0 ? 0 : -1; +} + +void test_example__a_test_with_auxiliary_methods(void) +{ + cl_must_pass_( + check_string("foo"), + "String differs after processing" + ); + + cl_must_pass_( + check_string("bar"), + "String differs after processing" + ); +} +~~~~ + +~~~~ c +/* + * Good style: auxiliary functions perform assertions + */ + +static void check_string(const char *str) +{ + const char *aux = process_string(str); + + cl_assert_( + aux != NULL, + "String processing failed" + ); + + cl_assert_( + strcmp(my_function(aux), str) == 0, + "String differs after processing" + ); +} + +void test_example__a_test_with_auxiliary_methods(void) +{ + check_string("foo"); + check_string("bar"); +} +~~~~ + +About Clar +========== + +Clar has been written from scratch by [Vicent Martí](https://github.com/vmg), +to replace the old testing framework in [libgit2][libgit2]. + +Do you know what languages are *in* on the SF startup scene? Node.js *and* +Latin. Follow [@vmg](https://www.twitter.com/vmg) on Twitter to +receive more lessons on word etymology. You can be hip too. + + +[libgit2]: https://github.com/libgit2/libgit2 diff --git a/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c new file mode 100644 index 0000000000..d54e455367 --- /dev/null +++ b/t/unit-tests/clar/clar.c @@ -0,0 +1,857 @@ +/* + * 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. + */ + +#define _BSD_SOURCE +#define _DARWIN_C_SOURCE +#define _DEFAULT_SOURCE + +#include <errno.h> +#include <setjmp.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> +#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> +# include <io.h> +# include <direct.h> + +# define _MAIN_CC __cdecl + +# 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) +# endif +# ifndef chdir +# define chdir(path) _chdir(path) +# endif +# ifndef access +# define access(path, mode) _access(path, mode) +# endif +# ifndef strdup +# define strdup(str) _strdup(str) +# endif +# ifndef strcasecmp +# define strcasecmp(a,b) _stricmp(a,b) +# endif + +# ifndef __MINGW32__ +# pragma comment(lib, "shell32") +# ifndef strncpy +# define strncpy(to, from, to_size) strncpy_s(to, to_size, from, _TRUNCATE) +# endif +# ifndef W_OK +# define W_OK 02 +# endif +# ifndef S_ISDIR +# define S_ISDIR(x) ((x & _S_IFDIR) != 0) +# endif +# define p_snprintf(buf,sz,fmt,...) _snprintf_s(buf,sz,_TRUNCATE,fmt,__VA_ARGS__) +# else +# define p_snprintf snprintf +# endif +#else +# include <sys/wait.h> /* waitpid(2) */ +# include <unistd.h> +# define _MAIN_CC +# define p_snprintf snprintf + typedef struct stat STAT_T; +#endif + +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#include "clar.h" + +static void fs_rm(const char *_source); +static void fs_copy(const char *_source, const char *dest); + +#ifdef CLAR_FIXTURE_PATH +static const char * +fixture_path(const char *base, const char *fixture_name); +#endif + +struct clar_error { + const char *file; + const char *function; + uintmax_t line_number; + const char *error_msg; + char *description; + + struct clar_error *next; +}; + +struct clar_explicit { + size_t suite_idx; + const char *filter; + + struct clar_explicit *next; +}; + +struct clar_report { + const char *test; + int test_number; + const char *suite; + + enum cl_test_status status; + time_t start; + double elapsed; + + struct clar_error *errors; + struct clar_error *last_error; + + struct clar_report *next; +}; + +struct clar_summary { + const char *filename; + FILE *fp; +}; + +static struct { + enum cl_test_status test_status; + + const char *active_test; + const char *active_suite; + + int total_skipped; + int total_errors; + + int tests_ran; + int suites_ran; + + enum cl_output_format output_format; + + int report_errors_only; + int exit_on_error; + int verbosity; + + int write_summary; + char *summary_filename; + struct clar_summary *summary; + + struct clar_explicit *explicit; + struct clar_explicit *last_explicit; + + struct clar_report *reports; + struct clar_report *last_report; + + void (*local_cleanup)(void *); + void *local_cleanup_payload; + + jmp_buf trampoline; + int trampoline_enabled; + + cl_trace_cb *pfn_trace_cb; + void *trace_payload; + +} _clar; + +struct clar_func { + const char *name; + void (*ptr)(void); +}; + +struct clar_suite { + const char *name; + struct clar_func initialize; + struct clar_func cleanup; + const struct clar_func *tests; + size_t test_count; + int enabled; +}; + +/* From clar_print_*.c */ +static void clar_print_init(int test_count, int suite_count, const char *suite_names); +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 void clar_sandbox(void); + +/* From summary.h */ +static struct clar_summary *clar_summary_init(const char *filename); +static int clar_summary_shutdown(struct clar_summary *fp); + +/* Load the declarations for the test suite */ +#include "clar.suite" + + +#define CL_TRACE(ev) \ + do { \ + if (_clar.pfn_trace_cb) \ + _clar.pfn_trace_cb(ev, \ + _clar.active_suite, \ + _clar.active_test, \ + _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; + _clar.trace_payload = payload; +} + + +/* Core test functions */ +static void +clar_report_errors(struct clar_report *report) +{ + struct clar_error *error; + int i = 1; + + for (error = report->errors; error; error = error->next) + clar_print_error(i++, _clar.last_report, error); +} + +static void +clar_report_all(void) +{ + struct clar_report *report; + struct clar_error *error; + int i = 1; + + for (report = _clar.reports; report; report = report->next) { + if (report->status != CL_TEST_FAILURE) + continue; + + for (error = report->errors; error; error = error->next) + clar_print_error(i++, report, error); + } +} + +#ifdef WIN32 +# define clar_time DWORD + +static void clar_time_now(clar_time *out) +{ + *out = GetTickCount(); +} + +static double clar_time_diff(clar_time *start, clar_time *end) +{ + return ((double)*end - (double)*start) / 1000; +} +#else +# include <sys/time.h> + +# define clar_time struct timeval + +static void clar_time_now(clar_time *out) +{ + gettimeofday(out, NULL); +} + +static double clar_time_diff(clar_time *start, clar_time *end) +{ + return ((double)end->tv_sec + (double)end->tv_usec / 1.0E6) - + ((double)start->tv_sec + (double)start->tv_usec / 1.0E6); +} +#endif + +static void +clar_run_test( + const struct clar_suite *suite, + const struct clar_func *test, + const struct clar_func *initialize, + const struct clar_func *cleanup) +{ + clar_time start, end; + + _clar.trampoline_enabled = 1; + + CL_TRACE(CL_TRACE__TEST__BEGIN); + + _clar.last_report->start = time(NULL); + clar_time_now(&start); + + if (setjmp(_clar.trampoline) == 0) { + if (initialize->ptr != NULL) + initialize->ptr(); + + CL_TRACE(CL_TRACE__TEST__RUN_BEGIN); + test->ptr(); + CL_TRACE(CL_TRACE__TEST__RUN_END); + } + + clar_time_now(&end); + + _clar.trampoline_enabled = 0; + + if (_clar.last_report->status == CL_TEST_NOTRUN) + _clar.last_report->status = CL_TEST_OK; + + _clar.last_report->elapsed = clar_time_diff(&start, &end); + + if (_clar.local_cleanup != NULL) + _clar.local_cleanup(_clar.local_cleanup_payload); + + if (cleanup->ptr != NULL) + cleanup->ptr(); + + CL_TRACE(CL_TRACE__TEST__END); + + _clar.tests_ran++; + + /* remove any local-set cleanup methods */ + _clar.local_cleanup = NULL; + _clar.local_cleanup_payload = NULL; + + if (_clar.report_errors_only) { + clar_report_errors(_clar.last_report); + } else { + clar_print_ontest(suite->name, test->name, _clar.tests_ran, _clar.last_report->status); + } +} + +static void +clar_run_suite(const struct clar_suite *suite, const char *filter) +{ + const struct clar_func *test = suite->tests; + size_t i, matchlen; + struct clar_report *report; + int exact = 0; + + if (!suite->enabled) + return; + + if (_clar.exit_on_error && _clar.total_errors) + return; + + if (!_clar.report_errors_only) + clar_print_onsuite(suite->name, ++_clar.suites_ran); + + _clar.active_suite = suite->name; + _clar.active_test = NULL; + CL_TRACE(CL_TRACE__SUITE_BEGIN); + + if (filter) { + size_t suitelen = strlen(suite->name); + matchlen = strlen(filter); + if (matchlen <= suitelen) { + filter = NULL; + } else { + filter += suitelen; + while (*filter == ':') + ++filter; + matchlen = strlen(filter); + + if (matchlen && filter[matchlen - 1] == '$') { + exact = 1; + matchlen--; + } + } + } + + for (i = 0; i < suite->test_count; ++i) { + if (filter && strncmp(test[i].name, filter, matchlen)) + continue; + + if (exact && strlen(test[i].name) != matchlen) + continue; + + _clar.active_test = test[i].name; + + 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; + report->status = CL_TEST_NOTRUN; + + if (_clar.reports == NULL) + _clar.reports = report; + + if (_clar.last_report != NULL) + _clar.last_report->next = report; + + _clar.last_report = report; + + clar_run_test(suite, &test[i], &suite->initialize, &suite->cleanup); + + if (_clar.exit_on_error && _clar.total_errors) + return; + } + + _clar.active_test = NULL; + CL_TRACE(CL_TRACE__SUITE_END); +} + +static void +clar_usage(const char *arg) +{ + printf("Usage: %s [options]\n\n", arg); + printf("Options:\n"); + printf(" -sname Run only the suite with `name` (can go to individual test name)\n"); + printf(" -iname Include the suite with `name`\n"); + printf(" -xname Exclude the suite with `name`\n"); + printf(" -v Increase verbosity (show suite names)\n"); + printf(" -q Only report tests that had an error\n"); + printf(" -Q Quit as soon as a test fails\n"); + printf(" -t Display results in tap format\n"); + printf(" -l Print suite names\n"); + printf(" -r[filename] Write summary file (to the optional filename)\n"); + exit(-1); +} + +static void +clar_parse_args(int argc, char **argv) +{ + int i; + + /* Verify options before execute */ + for (i = 1; i < argc; ++i) { + char *argument = argv[i]; + + if (argument[0] != '-' || argument[1] == '\0' + || strchr("sixvqQtlr", argument[1]) == NULL) { + clar_usage(argv[0]); + } + } + + for (i = 1; i < argc; ++i) { + char *argument = argv[i]; + + switch (argument[1]) { + case 's': + case 'i': + case 'x': { /* given suite name */ + int offset = (argument[2] == '=') ? 3 : 2, found = 0; + char action = argument[1]; + size_t j, arglen, suitelen, cmplen; + + argument += offset; + arglen = strlen(argument); + + if (arglen == 0) + clar_usage(argv[0]); + + for (j = 0; j < _clar_suite_count; ++j) { + suitelen = strlen(_clar_suites[j].name); + cmplen = (arglen < suitelen) ? arglen : suitelen; + + if (strncmp(argument, _clar_suites[j].name, cmplen) == 0) { + int exact = (arglen >= suitelen); + + /* Do we have a real suite prefix separated by a + * trailing '::' or just a matching substring? */ + if (arglen > suitelen && (argument[suitelen] != ':' + || argument[suitelen + 1] != ':')) + continue; + + ++found; + + if (!exact) + _clar.verbosity = MAX(_clar.verbosity, 1); + + switch (action) { + case 's': { + 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; + + if (_clar.explicit == NULL) + _clar.explicit = explicit; + + if (_clar.last_explicit != NULL) + _clar.last_explicit->next = explicit; + + _clar_suites[j].enabled = 1; + _clar.last_explicit = explicit; + break; + } + case 'i': _clar_suites[j].enabled = 1; break; + case 'x': _clar_suites[j].enabled = 0; break; + } + + if (exact) + break; + } + } + + if (!found) + clar_abort("No suite matching '%s' found.\n", argument); + break; + } + + case 'q': + _clar.report_errors_only = 1; + break; + + case 'Q': + _clar.exit_on_error = 1; + break; + + case 't': + _clar.output_format = CL_OUTPUT_TAP; + break; + + case 'l': { + size_t j; + printf("Test suites (use -s<name> to run just one):\n"); + for (j = 0; j < _clar_suite_count; ++j) + printf(" %3d: %s\n", (int)j, _clar_suites[j].name); + + exit(0); + } + + case 'v': + _clar.verbosity++; + break; + + case 'r': + _clar.write_summary = 1; + free(_clar.summary_filename); + 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: + clar_abort("Unexpected commandline argument '%s'.\n", + argument[1]); + } + } +} + +void +clar_test_init(int argc, char **argv) +{ + const char *summary_env; + + if (argc > 1) + clar_parse_args(argc, argv); + + clar_print_init( + (int)_clar_callback_count, + (int)_clar_suite_count, + "" + ); + + if (!_clar.summary_filename && + (summary_env = getenv("CLAR_SUMMARY")) != NULL) { + _clar.write_summary = 1; + if ((_clar.summary_filename = strdup(summary_env)) == NULL) + clar_abort("Failed to allocate summary filename.\n"); + } + + if (_clar.write_summary && !_clar.summary_filename) + 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_sandbox(); +} + +int +clar_test_run(void) +{ + size_t i; + struct clar_explicit *explicit; + + if (_clar.explicit) { + for (explicit = _clar.explicit; explicit; explicit = explicit->next) + clar_run_suite(&_clar_suites[explicit->suite_idx], explicit->filter); + } else { + for (i = 0; i < _clar_suite_count; ++i) + clar_run_suite(&_clar_suites[i], NULL); + } + + return _clar.total_errors; +} + +void +clar_test_shutdown(void) +{ + struct clar_explicit *explicit, *explicit_next; + struct clar_report *report, *report_next; + + clar_print_shutdown( + _clar.tests_ran, + (int)_clar_suite_count, + _clar.total_errors + ); + + clar_unsandbox(); + + 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; + free(explicit); + } + + for (report = _clar.reports; report; report = report_next) { + report_next = report->next; + free(report); + } + + free(_clar.summary_filename); +} + +int +clar_test(int argc, char **argv) +{ + int errors; + + clar_test_init(argc, argv); + errors = clar_test_run(); + clar_test_shutdown(); + + return errors; +} + +static void abort_test(void) +{ + if (!_clar.trampoline_enabled) { + clar_print_onabort( + "Fatal error: a cleanup method raised an exception.\n"); + clar_report_errors(_clar.last_report); + exit(-1); + } + + CL_TRACE(CL_TRACE__TEST__LONGJMP); + longjmp(_clar.trampoline, -1); +} + +void clar__skip(void) +{ + _clar.last_report->status = CL_TEST_SKIP; + _clar.total_skipped++; + abort_test(); +} + +void clar__fail( + const char *file, + const char *function, + size_t line, + const char *error_msg, + const char *description, + int should_abort) +{ + 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; + + if (_clar.last_report->last_error != NULL) + _clar.last_report->last_error->next = error; + + _clar.last_report->last_error = error; + + error->file = file; + error->function = function; + error->line_number = line; + error->error_msg = error_msg; + + 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; + + if (should_abort) + abort_test(); +} + +void clar__assert( + int condition, + const char *file, + const char *function, + size_t line, + const char *error_msg, + const char *description, + int should_abort) +{ + if (condition) + return; + + clar__fail(file, function, line, error_msg, description, should_abort); +} + +void clar__assert_equal( + const char *file, + const char *function, + size_t line, + const char *err, + int should_abort, + const char *fmt, + ...) +{ + va_list args; + char buf[4096]; + int is_equal = 1; + + va_start(args, fmt); + + if (!strcmp("%s", fmt)) { + const char *s1 = va_arg(args, const char *); + const char *s2 = va_arg(args, const char *); + is_equal = (!s1 || !s2) ? (s1 == s2) : !strcmp(s1, s2); + + if (!is_equal) { + if (s1 && s2) { + int pos; + for (pos = 0; s1[pos] == s2[pos] && s1[pos] && s2[pos]; ++pos) + /* find differing byte offset */; + p_snprintf(buf, sizeof(buf), "'%s' != '%s' (at byte %d)", + s1, s2, pos); + } else { + p_snprintf(buf, sizeof(buf), "'%s' != '%s'", s1, s2); + } + } + } + else if(!strcmp("%.*s", fmt)) { + const char *s1 = va_arg(args, const char *); + const char *s2 = va_arg(args, const char *); + int len = va_arg(args, int); + is_equal = (!s1 || !s2) ? (s1 == s2) : !strncmp(s1, s2, len); + + if (!is_equal) { + if (s1 && s2) { + int pos; + for (pos = 0; s1[pos] == s2[pos] && pos < len; ++pos) + /* find differing byte offset */; + p_snprintf(buf, sizeof(buf), "'%.*s' != '%.*s' (at byte %d)", + len, s1, len, s2, pos); + } else { + p_snprintf(buf, sizeof(buf), "'%.*s' != '%.*s'", len, s1, len, s2); + } + } + } +#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 *); + is_equal = (!wcs1 || !wcs2) ? (wcs1 == wcs2) : !wcscmp(wcs1, wcs2); + + if (!is_equal) { + if (wcs1 && wcs2) { + int pos; + for (pos = 0; wcs1[pos] == wcs2[pos] && wcs1[pos] && wcs2[pos]; ++pos) + /* find differing byte offset */; + p_snprintf(buf, sizeof(buf), "'%ls' != '%ls' (at byte %d)", + wcs1, wcs2, pos); + } else { + p_snprintf(buf, sizeof(buf), "'%ls' != '%ls'", wcs1, wcs2); + } + } + } + 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 *); + int len = va_arg(args, int); + is_equal = (!wcs1 || !wcs2) ? (wcs1 == wcs2) : !wcsncmp(wcs1, wcs2, len); + + if (!is_equal) { + if (wcs1 && wcs2) { + int pos; + for (pos = 0; wcs1[pos] == wcs2[pos] && pos < len; ++pos) + /* find differing byte offset */; + p_snprintf(buf, sizeof(buf), "'%.*ls' != '%.*ls' (at byte %d)", + len, wcs1, len, wcs2, pos); + } else { + p_snprintf(buf, sizeof(buf), "'%.*ls' != '%.*ls'", len, wcs1, len, wcs2); + } + } + } +#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); + strncat(buf, " != ", sizeof(buf) - offset); + p_snprintf(buf + offset + 4, sizeof(buf) - offset - 4, fmt, sz2); + } + } + else if (!strcmp("%p", fmt)) { + void *p1 = va_arg(args, void *), *p2 = va_arg(args, void *); + is_equal = (p1 == p2); + if (!is_equal) + p_snprintf(buf, sizeof(buf), "%p != %p", p1, p2); + } + else { + int i1 = va_arg(args, int), i2 = va_arg(args, int); + is_equal = (i1 == i2); + if (!is_equal) { + int offset = p_snprintf(buf, sizeof(buf), fmt, i1); + strncat(buf, " != ", sizeof(buf) - offset); + p_snprintf(buf + offset + 4, sizeof(buf) - offset - 4, fmt, i2); + } + } + + va_end(args); + + if (!is_equal) + clar__fail(file, function, line, err, buf, should_abort); +} + +void cl_set_cleanup(void (*cleanup)(void *), void *opaque) +{ + _clar.local_cleanup = cleanup; + _clar.local_cleanup_payload = opaque; +} + +#include "clar/sandbox.h" +#include "clar/fixtures.h" +#include "clar/fs.h" +#include "clar/print.h" +#include "clar/summary.h" diff --git a/t/unit-tests/clar/clar.h b/t/unit-tests/clar/clar.h new file mode 100644 index 0000000000..8c22382bd5 --- /dev/null +++ b/t/unit-tests/clar/clar.h @@ -0,0 +1,173 @@ +/* + * 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. + */ +#ifndef __CLAR_TEST_H__ +#define __CLAR_TEST_H__ + +#include <stdlib.h> + +enum cl_test_status { + CL_TEST_OK, + CL_TEST_FAILURE, + CL_TEST_SKIP, + CL_TEST_NOTRUN, +}; + +enum cl_output_format { + CL_OUTPUT_CLAP, + CL_OUTPUT_TAP, +}; + +/** Setup clar environment */ +void clar_test_init(int argc, char *argv[]); +int clar_test_run(void); +void clar_test_shutdown(void); + +/** One shot setup & run */ +int clar_test(int argc, char *argv[]); + +const char *clar_sandbox_path(void); + +void cl_set_cleanup(void (*cleanup)(void *), void *opaque); +void cl_fs_cleanup(void); + +/** + * cl_trace_* is a hook to provide a simple global tracing + * mechanism. + * + * The goal here is to let main() provide clar-proper + * with a callback to optionally write log info for + * test operations into the same stream used by their + * actual tests. This would let them print test names + * and maybe performance data as they choose. + * + * The goal is NOT to alter the flow of control or to + * override test selection/skipping. (So the callback + * does not return a value.) + * + * The goal is NOT to duplicate the existing + * pass/fail/skip reporting. (So the callback + * does not accept a status/errorcode argument.) + * + */ +typedef enum cl_trace_event { + CL_TRACE__SUITE_BEGIN, + CL_TRACE__SUITE_END, + CL_TRACE__TEST__BEGIN, + CL_TRACE__TEST__END, + CL_TRACE__TEST__RUN_BEGIN, + CL_TRACE__TEST__RUN_END, + CL_TRACE__TEST__LONGJMP, +} cl_trace_event; + +typedef void (cl_trace_cb)( + cl_trace_event ev, + const char *suite_name, + const char *test_name, + void *payload); + +/** + * Register a callback into CLAR to send global trace events. + * Pass NULL to disable. + */ +void cl_trace_register(cl_trace_cb *cb, void *payload); + + +#ifdef CLAR_FIXTURE_PATH +const char *cl_fixture(const char *fixture_name); +void cl_fixture_sandbox(const char *fixture_name); +void cl_fixture_cleanup(const char *fixture_name); +const char *cl_fixture_basename(const char *fixture_name); +#endif + +/** + * Assertion macros with explicit error message + */ +#define cl_must_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 1) +#define cl_must_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 1) +#define cl_assert_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 1) + +/** + * Check macros with explicit error message + */ +#define cl_check_pass_(expr, desc) clar__assert((expr) >= 0, __FILE__, __func__, __LINE__, "Function call failed: " #expr, desc, 0) +#define cl_check_fail_(expr, desc) clar__assert((expr) < 0, __FILE__, __func__, __LINE__, "Expected function call to fail: " #expr, desc, 0) +#define cl_check_(expr, desc) clar__assert((expr) != 0, __FILE__, __func__, __LINE__, "Expression is not true: " #expr, desc, 0) + +/** + * Assertion macros with no error message + */ +#define cl_must_pass(expr) cl_must_pass_(expr, NULL) +#define cl_must_fail(expr) cl_must_fail_(expr, NULL) +#define cl_assert(expr) cl_assert_(expr, NULL) + +/** + * Check macros with no error message + */ +#define cl_check_pass(expr) cl_check_pass_(expr, NULL) +#define cl_check_fail(expr) cl_check_fail_(expr, NULL) +#define cl_check(expr) cl_check_(expr, NULL) + +/** + * Forced failure/warning + */ +#define cl_fail(desc) clar__fail(__FILE__, __func__, __LINE__, "Test failed.", desc, 1) +#define cl_warning(desc) clar__fail(__FILE__, __func__, __LINE__, "Warning during test execution:", desc, 0) + +#define cl_skip() clar__skip() + +/** + * Typed assertion macros + */ +#define cl_assert_equal_s(s1,s2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%s", (s1), (s2)) +#define cl_assert_equal_s_(s1,s2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%s", (s1), (s2)) + +#define cl_assert_equal_wcs(wcs1,wcs2) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%ls", (wcs1), (wcs2)) +#define cl_assert_equal_wcs_(wcs1,wcs2,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%ls", (wcs1), (wcs2)) + +#define cl_assert_equal_strn(s1,s2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2, 1, "%.*s", (s1), (s2), (int)(len)) +#define cl_assert_equal_strn_(s1,s2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #s1 " != " #s2 " (" #note ")", 1, "%.*s", (s1), (s2), (int)(len)) + +#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len)) +#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(__FILE__,__func__,__LINE__,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len)) + +#define cl_assert_equal_i(i1,i2) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2)) +#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2)) +#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(__FILE__,__func__,__LINE__,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2)) + +#define cl_assert_equal_b(b1,b2) clar__assert_equal(__FILE__,__func__,__LINE__,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0)) + +#define cl_assert_equal_p(p1,p2) clar__assert_equal(__FILE__,__func__,__LINE__,"Pointer mismatch: " #p1 " != " #p2, 1, "%p", (p1), (p2)) + +void clar__skip(void); + +void clar__fail( + const char *file, + const char *func, + size_t line, + const char *error, + const char *description, + int should_abort); + +void clar__assert( + int condition, + const char *file, + const char *func, + size_t line, + const char *error, + const char *description, + int should_abort); + +void clar__assert_equal( + const char *file, + const char *func, + size_t line, + const char *err, + int should_abort, + const char *fmt, + ...); + +#endif diff --git a/t/unit-tests/clar/clar/fixtures.h b/t/unit-tests/clar/clar/fixtures.h new file mode 100644 index 0000000000..6ec6423484 --- /dev/null +++ b/t/unit-tests/clar/clar/fixtures.h @@ -0,0 +1,50 @@ +#ifdef CLAR_FIXTURE_PATH +static const char * +fixture_path(const char *base, const char *fixture_name) +{ + static char _path[4096]; + size_t root_len; + + root_len = strlen(base); + strncpy(_path, base, sizeof(_path)); + + if (_path[root_len - 1] != '/') + _path[root_len++] = '/'; + + if (fixture_name[0] == '/') + fixture_name++; + + strncpy(_path + root_len, + fixture_name, + sizeof(_path) - root_len); + + return _path; +} + +const char *cl_fixture(const char *fixture_name) +{ + return fixture_path(CLAR_FIXTURE_PATH, fixture_name); +} + +void cl_fixture_sandbox(const char *fixture_name) +{ + fs_copy(cl_fixture(fixture_name), _clar_path); +} + +const char *cl_fixture_basename(const char *fixture_name) +{ + const char *p; + + for (p = fixture_name; *p; p++) { + if (p[0] == '/' && p[1] && p[1] != '/') + fixture_name = p+1; + } + + return fixture_name; +} + +void cl_fixture_cleanup(const char *fixture_name) +{ + fs_rm(fixture_path(_clar_path, cl_fixture_basename(fixture_name))); +} +#endif diff --git a/t/unit-tests/clar/clar/fs.h b/t/unit-tests/clar/clar/fs.h new file mode 100644 index 0000000000..8b206179fc --- /dev/null +++ b/t/unit-tests/clar/clar/fs.h @@ -0,0 +1,524 @@ +/* + * By default, use a read/write loop to copy files on POSIX systems. + * On Linux, use sendfile by default as it's slightly faster. On + * macOS, we avoid fcopyfile by default because it's slightly slower. + */ +#undef USE_FCOPYFILE +#define USE_SENDFILE 1 + +#ifdef _WIN32 + +#ifdef CLAR_WIN32_LONGPATHS +# define CLAR_MAX_PATH 4096 +#else +# define CLAR_MAX_PATH MAX_PATH +#endif + +#define RM_RETRY_COUNT 5 +#define RM_RETRY_DELAY 10 + +#ifdef __MINGW32__ + +/* These security-enhanced functions are not available + * in MinGW, so just use the vanilla ones */ +#define wcscpy_s(a, b, c) wcscpy((a), (c)) +#define wcscat_s(a, b, c) wcscat((a), (c)) + +#endif /* __MINGW32__ */ + +static int +fs__dotordotdot(WCHAR *_tocheck) +{ + return _tocheck[0] == '.' && + (_tocheck[1] == '\0' || + (_tocheck[1] == '.' && _tocheck[2] == '\0')); +} + +static int +fs_rmdir_rmdir(WCHAR *_wpath) +{ + unsigned retries = 1; + + while (!RemoveDirectoryW(_wpath)) { + /* Only retry when we have retries remaining, and the + * error was ERROR_DIR_NOT_EMPTY. */ + if (retries++ > RM_RETRY_COUNT || + ERROR_DIR_NOT_EMPTY != GetLastError()) + return -1; + + /* Give whatever has a handle to a child item some time + * to release it before trying again */ + Sleep(RM_RETRY_DELAY * retries * retries); + } + + return 0; +} + +static void translate_path(WCHAR *path, size_t path_size) +{ + size_t path_len, i; + + if (wcsncmp(path, L"\\\\?\\", 4) == 0) + return; + + path_len = wcslen(path); + cl_assert(path_size > path_len + 4); + + for (i = path_len; i > 0; i--) { + WCHAR c = path[i - 1]; + + if (c == L'/') + path[i + 3] = L'\\'; + else + path[i + 3] = path[i - 1]; + } + + path[0] = L'\\'; + path[1] = L'\\'; + path[2] = L'?'; + path[3] = L'\\'; + path[path_len + 4] = L'\0'; +} + +static void +fs_rmdir_helper(WCHAR *_wsource) +{ + WCHAR buffer[CLAR_MAX_PATH]; + HANDLE find_handle; + WIN32_FIND_DATAW find_data; + size_t buffer_prefix_len; + + /* Set up the buffer and capture the length */ + wcscpy_s(buffer, CLAR_MAX_PATH, _wsource); + translate_path(buffer, CLAR_MAX_PATH); + wcscat_s(buffer, CLAR_MAX_PATH, L"\\"); + buffer_prefix_len = wcslen(buffer); + + /* FindFirstFile needs a wildcard to match multiple items */ + wcscat_s(buffer, CLAR_MAX_PATH, L"*"); + find_handle = FindFirstFileW(buffer, &find_data); + cl_assert(INVALID_HANDLE_VALUE != find_handle); + + do { + /* FindFirstFile/FindNextFile gives back . and .. + * entries at the beginning */ + if (fs__dotordotdot(find_data.cFileName)) + continue; + + wcscpy_s(buffer + buffer_prefix_len, CLAR_MAX_PATH - buffer_prefix_len, find_data.cFileName); + + if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes) + fs_rmdir_helper(buffer); + else { + /* If set, the +R bit must be cleared before deleting */ + if (FILE_ATTRIBUTE_READONLY & find_data.dwFileAttributes) + cl_assert(SetFileAttributesW(buffer, find_data.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY)); + + cl_assert(DeleteFileW(buffer)); + } + } + while (FindNextFileW(find_handle, &find_data)); + + /* Ensure that we successfully completed the enumeration */ + cl_assert(ERROR_NO_MORE_FILES == GetLastError()); + + /* Close the find handle */ + FindClose(find_handle); + + /* Now that the directory is empty, remove it */ + cl_assert(0 == fs_rmdir_rmdir(_wsource)); +} + +static int +fs_rm_wait(WCHAR *_wpath) +{ + unsigned retries = 1; + DWORD last_error; + + do { + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(_wpath)) + last_error = GetLastError(); + else + last_error = ERROR_SUCCESS; + + /* Is the item gone? */ + if (ERROR_FILE_NOT_FOUND == last_error || + ERROR_PATH_NOT_FOUND == last_error) + return 0; + + Sleep(RM_RETRY_DELAY * retries * retries); + } + while (retries++ <= RM_RETRY_COUNT); + + return -1; +} + +static void +fs_rm(const char *_source) +{ + WCHAR wsource[CLAR_MAX_PATH]; + DWORD attrs; + + /* The input path is UTF-8. Convert it to wide characters + * for use with the Windows API */ + cl_assert(MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, + _source, + -1, /* Indicates NULL termination */ + wsource, + CLAR_MAX_PATH)); + + translate_path(wsource, CLAR_MAX_PATH); + + /* Does the item exist? If not, we have no work to do */ + attrs = GetFileAttributesW(wsource); + + if (INVALID_FILE_ATTRIBUTES == attrs) + return; + + if (FILE_ATTRIBUTE_DIRECTORY & attrs) + fs_rmdir_helper(wsource); + else { + /* The item is a file. Strip the +R bit */ + if (FILE_ATTRIBUTE_READONLY & attrs) + cl_assert(SetFileAttributesW(wsource, attrs & ~FILE_ATTRIBUTE_READONLY)); + + cl_assert(DeleteFileW(wsource)); + } + + /* Wait for the DeleteFile or RemoveDirectory call to complete */ + cl_assert(0 == fs_rm_wait(wsource)); +} + +static void +fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest) +{ + WCHAR buf_source[CLAR_MAX_PATH], buf_dest[CLAR_MAX_PATH]; + HANDLE find_handle; + WIN32_FIND_DATAW find_data; + size_t buf_source_prefix_len, buf_dest_prefix_len; + + wcscpy_s(buf_source, CLAR_MAX_PATH, _wsource); + wcscat_s(buf_source, CLAR_MAX_PATH, L"\\"); + translate_path(buf_source, CLAR_MAX_PATH); + buf_source_prefix_len = wcslen(buf_source); + + wcscpy_s(buf_dest, CLAR_MAX_PATH, _wdest); + wcscat_s(buf_dest, CLAR_MAX_PATH, L"\\"); + translate_path(buf_dest, CLAR_MAX_PATH); + buf_dest_prefix_len = wcslen(buf_dest); + + /* Get an enumerator for the items in the source. */ + wcscat_s(buf_source, CLAR_MAX_PATH, L"*"); + find_handle = FindFirstFileW(buf_source, &find_data); + cl_assert(INVALID_HANDLE_VALUE != find_handle); + + /* Create the target directory. */ + cl_assert(CreateDirectoryW(_wdest, NULL)); + + do { + /* FindFirstFile/FindNextFile gives back . and .. + * entries at the beginning */ + if (fs__dotordotdot(find_data.cFileName)) + continue; + + wcscpy_s(buf_source + buf_source_prefix_len, CLAR_MAX_PATH - buf_source_prefix_len, find_data.cFileName); + wcscpy_s(buf_dest + buf_dest_prefix_len, CLAR_MAX_PATH - buf_dest_prefix_len, find_data.cFileName); + + if (FILE_ATTRIBUTE_DIRECTORY & find_data.dwFileAttributes) + fs_copydir_helper(buf_source, buf_dest); + else + cl_assert(CopyFileW(buf_source, buf_dest, TRUE)); + } + while (FindNextFileW(find_handle, &find_data)); + + /* Ensure that we successfully completed the enumeration */ + cl_assert(ERROR_NO_MORE_FILES == GetLastError()); + + /* Close the find handle */ + FindClose(find_handle); +} + +static void +fs_copy(const char *_source, const char *_dest) +{ + WCHAR wsource[CLAR_MAX_PATH], wdest[CLAR_MAX_PATH]; + DWORD source_attrs, dest_attrs; + HANDLE find_handle; + WIN32_FIND_DATAW find_data; + + /* The input paths are UTF-8. Convert them to wide characters + * for use with the Windows API. */ + cl_assert(MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, + _source, + -1, + wsource, + CLAR_MAX_PATH)); + + cl_assert(MultiByteToWideChar(CP_UTF8, + MB_ERR_INVALID_CHARS, + _dest, + -1, + wdest, + CLAR_MAX_PATH)); + + translate_path(wsource, CLAR_MAX_PATH); + translate_path(wdest, CLAR_MAX_PATH); + + /* Check the source for existence */ + source_attrs = GetFileAttributesW(wsource); + cl_assert(INVALID_FILE_ATTRIBUTES != source_attrs); + + /* Check the target for existence */ + dest_attrs = GetFileAttributesW(wdest); + + if (INVALID_FILE_ATTRIBUTES != dest_attrs) { + /* Target exists; append last path part of source to target. + * Use FindFirstFile to parse the path */ + find_handle = FindFirstFileW(wsource, &find_data); + cl_assert(INVALID_HANDLE_VALUE != find_handle); + wcscat_s(wdest, CLAR_MAX_PATH, L"\\"); + wcscat_s(wdest, CLAR_MAX_PATH, find_data.cFileName); + FindClose(find_handle); + + /* Check the new target for existence */ + cl_assert(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(wdest)); + } + + if (FILE_ATTRIBUTE_DIRECTORY & source_attrs) + fs_copydir_helper(wsource, wdest); + else + cl_assert(CopyFileW(wsource, wdest, TRUE)); +} + +void +cl_fs_cleanup(void) +{ +#ifdef CLAR_FIXTURE_PATH + fs_rm(fixture_path(_clar_path, "*")); +#else + ((void)fs_copy); /* unused */ +#endif +} + +#else + +#include <errno.h> +#include <string.h> +#include <limits.h> +#include <dirent.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#if defined(__linux__) +# include <sys/sendfile.h> +#endif + +#if defined(__APPLE__) +# include <copyfile.h> +#endif + +static void basename_r(const char **out, int *out_len, const char *in) +{ + size_t in_len = strlen(in), start_pos; + + for (in_len = strlen(in); in_len; in_len--) { + if (in[in_len - 1] != '/') + break; + } + + for (start_pos = in_len; start_pos; start_pos--) { + if (in[start_pos - 1] == '/') + break; + } + + cl_assert(in_len - start_pos < INT_MAX); + + if (in_len - start_pos > 0) { + *out = &in[start_pos]; + *out_len = (in_len - start_pos); + } else { + *out = "/"; + *out_len = 1; + } +} + +static char *joinpath(const char *dir, const char *base, int base_len) +{ + char *out; + int len; + + if (base_len == -1) { + size_t bl = strlen(base); + + cl_assert(bl < INT_MAX); + base_len = (int)bl; + } + + len = strlen(dir) + base_len + 2; + cl_assert(len > 0); + + cl_assert(out = malloc(len)); + cl_assert(snprintf(out, len, "%s/%.*s", dir, base_len, base) < len); + + return out; +} + +static void +fs_copydir_helper(const char *source, const char *dest, int dest_mode) +{ + DIR *source_dir; + struct dirent *d; + + mkdir(dest, dest_mode); + + cl_assert_(source_dir = opendir(source), "Could not open source dir"); + while ((d = (errno = 0, readdir(source_dir))) != NULL) { + char *child; + + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + child = joinpath(source, d->d_name, -1); + fs_copy(child, dest); + free(child); + } + + cl_assert_(errno == 0, "Failed to iterate source dir"); + + closedir(source_dir); +} + +static void +fs_copyfile_helper(const char *source, size_t source_len, const char *dest, int dest_mode) +{ + int in, out; + + cl_must_pass((in = open(source, O_RDONLY))); + cl_must_pass((out = open(dest, O_WRONLY|O_CREAT|O_TRUNC, dest_mode))); + +#if USE_FCOPYFILE && defined(__APPLE__) + ((void)(source_len)); /* unused */ + cl_must_pass(fcopyfile(in, out, 0, COPYFILE_DATA)); +#elif USE_SENDFILE && defined(__linux__) + { + ssize_t ret = 0; + + while (source_len && (ret = sendfile(out, in, NULL, source_len)) > 0) { + source_len -= (size_t)ret; + } + cl_assert(ret >= 0); + } +#else + { + char buf[131072]; + ssize_t ret; + + ((void)(source_len)); /* unused */ + + while ((ret = read(in, buf, sizeof(buf))) > 0) { + size_t len = (size_t)ret; + + while (len && (ret = write(out, buf, len)) > 0) { + cl_assert(ret <= (ssize_t)len); + len -= ret; + } + cl_assert(ret >= 0); + } + cl_assert(ret == 0); + } +#endif + + close(in); + close(out); +} + +static void +fs_copy(const char *source, const char *_dest) +{ + char *dbuf = NULL; + const char *dest = NULL; + struct stat source_st, dest_st; + + cl_must_pass_(lstat(source, &source_st), "Failed to stat copy source"); + + if (lstat(_dest, &dest_st) == 0) { + const char *base; + int base_len; + + /* Target exists and is directory; append basename */ + cl_assert(S_ISDIR(dest_st.st_mode)); + + basename_r(&base, &base_len, source); + cl_assert(base_len < INT_MAX); + + dbuf = joinpath(_dest, base, base_len); + dest = dbuf; + } else if (errno != ENOENT) { + cl_fail("Cannot copy; cannot stat destination"); + } else { + dest = _dest; + } + + if (S_ISDIR(source_st.st_mode)) { + fs_copydir_helper(source, dest, source_st.st_mode); + } else { + fs_copyfile_helper(source, source_st.st_size, dest, source_st.st_mode); + } + + free(dbuf); +} + +static void +fs_rmdir_helper(const char *path) +{ + DIR *dir; + struct dirent *d; + + cl_assert_(dir = opendir(path), "Could not open dir"); + while ((d = (errno = 0, readdir(dir))) != NULL) { + char *child; + + if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) + continue; + + child = joinpath(path, d->d_name, -1); + fs_rm(child); + free(child); + } + + cl_assert_(errno == 0, "Failed to iterate source dir"); + closedir(dir); + + cl_must_pass_(rmdir(path), "Could not remove directory"); +} + +static void +fs_rm(const char *path) +{ + struct stat st; + + if (lstat(path, &st)) { + if (errno == ENOENT) + return; + + cl_fail("Cannot copy; cannot stat destination"); + } + + if (S_ISDIR(st.st_mode)) { + fs_rmdir_helper(path); + } else { + cl_must_pass(unlink(path)); + } +} + +void +cl_fs_cleanup(void) +{ + clar_unsandbox(); + clar_sandbox(); +} +#endif diff --git a/t/unit-tests/clar/clar/print.h b/t/unit-tests/clar/clar/print.h new file mode 100644 index 0000000000..69d0ee967e --- /dev/null +++ b/t/unit-tests/clar/clar/print.h @@ -0,0 +1,216 @@ +/* clap: clar protocol, the traditional clar output format */ + +static void clar_print_clap_init(int test_count, int suite_count, const char *suite_names) +{ + (void)test_count; + printf("Loaded %d suites: %s\n", (int)suite_count, suite_names); + printf("Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')\n"); +} + +static void clar_print_clap_shutdown(int test_count, int suite_count, int error_count) +{ + (void)test_count; + (void)suite_count; + (void)error_count; + + printf("\n\n"); + clar_report_all(); +} + +static void clar_print_clap_error(int num, const struct clar_report *report, const struct clar_error *error) +{ + printf(" %d) Failure:\n", num); + + printf("%s::%s [%s:%"PRIuMAX"]\n", + report->suite, + report->test, + error->file, + error->line_number); + + printf(" %s\n", error->error_msg); + + if (error->description != NULL) + printf(" %s\n", error->description); + + printf("\n"); + fflush(stdout); +} + +static void clar_print_clap_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status) +{ + (void)test_name; + (void)test_number; + + if (_clar.verbosity > 1) { + printf("%s::%s: ", suite_name, test_name); + + switch (status) { + case CL_TEST_OK: printf("ok\n"); break; + case CL_TEST_FAILURE: printf("fail\n"); break; + case CL_TEST_SKIP: printf("skipped"); break; + case CL_TEST_NOTRUN: printf("notrun"); break; + } + } else { + switch (status) { + case CL_TEST_OK: printf("."); break; + case CL_TEST_FAILURE: printf("F"); break; + case CL_TEST_SKIP: printf("S"); break; + case CL_TEST_NOTRUN: printf("N"); break; + } + + fflush(stdout); + } +} + +static void clar_print_clap_onsuite(const char *suite_name, int suite_index) +{ + if (_clar.verbosity == 1) + printf("\n%s", suite_name); + + (void)suite_index; +} + +static void clar_print_clap_onabort(const char *fmt, va_list arg) +{ + vfprintf(stderr, fmt, arg); +} + +/* tap: test anywhere protocol format */ + +static void clar_print_tap_init(int test_count, int suite_count, const char *suite_names) +{ + (void)test_count; + (void)suite_count; + (void)suite_names; + printf("TAP version 13\n"); +} + +static void clar_print_tap_shutdown(int test_count, int suite_count, int error_count) +{ + (void)suite_count; + (void)error_count; + + printf("1..%d\n", test_count); +} + +static void clar_print_tap_error(int num, const struct clar_report *report, const struct clar_error *error) +{ + (void)num; + (void)report; + (void)error; +} + +static void print_escaped(const char *str) +{ + char *c; + + while ((c = strchr(str, '\'')) != NULL) { + printf("%.*s", (int)(c - str), str); + printf("''"); + str = c + 1; + } + + printf("%s", str); +} + +static void clar_print_tap_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status) +{ + const struct clar_error *error = _clar.last_report->errors; + + (void)test_name; + (void)test_number; + + switch(status) { + case CL_TEST_OK: + printf("ok %d - %s::%s\n", test_number, suite_name, test_name); + break; + case CL_TEST_FAILURE: + printf("not ok %d - %s::%s\n", test_number, suite_name, test_name); + + printf(" ---\n"); + printf(" reason: |\n"); + printf(" %s\n", error->error_msg); + + if (error->description) + printf(" %s\n", error->description); + + printf(" at:\n"); + printf(" file: '"); print_escaped(error->file); printf("'\n"); + printf(" line: %" PRIuMAX "\n", error->line_number); + printf(" function: '%s'\n", error->function); + printf(" ---\n"); + + break; + case CL_TEST_SKIP: + case CL_TEST_NOTRUN: + printf("ok %d - # SKIP %s::%s\n", test_number, suite_name, test_name); + break; + } + + fflush(stdout); +} + +static void clar_print_tap_onsuite(const char *suite_name, int suite_index) +{ + printf("# start of suite %d: %s\n", suite_index, suite_name); +} + +static void clar_print_tap_onabort(const char *fmt, va_list arg) +{ + printf("Bail out! "); + vprintf(fmt, arg); + fflush(stdout); +} + +/* indirection between protocol output selection */ + +#define PRINT(FN, ...) do { \ + switch (_clar.output_format) { \ + case CL_OUTPUT_CLAP: \ + clar_print_clap_##FN (__VA_ARGS__); \ + break; \ + case CL_OUTPUT_TAP: \ + clar_print_tap_##FN (__VA_ARGS__); \ + break; \ + default: \ + abort(); \ + } \ + } while (0) + +static void clar_print_init(int test_count, int suite_count, const char *suite_names) +{ + PRINT(init, test_count, suite_count, suite_names); +} + +static void clar_print_shutdown(int test_count, int suite_count, int error_count) +{ + PRINT(shutdown, test_count, suite_count, error_count); +} + +static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error) +{ + PRINT(error, num, report, error); +} + +static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status status) +{ + PRINT(ontest, suite_name, test_name, test_number, status); +} + +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); + 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 new file mode 100644 index 0000000000..bc960f50e0 --- /dev/null +++ b/t/unit-tests/clar/clar/sandbox.h @@ -0,0 +1,158 @@ +#ifdef __APPLE__ +#include <sys/syslimits.h> +#endif + +static char _clar_path[4096 + 1]; + +static int +is_valid_tmp_path(const char *path) +{ + STAT_T st; + + if (stat(path, &st) != 0) + return 0; + + if (!S_ISDIR(st.st_mode)) + return 0; + + return (access(path, W_OK) == 0); +} + +static int +find_tmp_path(char *buffer, size_t length) +{ +#ifndef _WIN32 + static const size_t var_count = 5; + static const char *env_vars[] = { + "CLAR_TMP", "TMPDIR", "TMP", "TEMP", "USERPROFILE" + }; + + size_t i; + + for (i = 0; i < var_count; ++i) { + const char *env = getenv(env_vars[i]); + if (!env) + continue; + + if (is_valid_tmp_path(env)) { +#ifdef __APPLE__ + if (length >= PATH_MAX && realpath(env, buffer) != NULL) + return 0; +#endif + strncpy(buffer, env, length - 1); + buffer[length - 1] = '\0'; + return 0; + } + } + + /* If the environment doesn't say anything, try to use /tmp */ + if (is_valid_tmp_path("/tmp")) { +#ifdef __APPLE__ + if (length >= PATH_MAX && realpath("/tmp", buffer) != NULL) + return 0; +#endif + strncpy(buffer, "/tmp", length - 1); + buffer[length - 1] = '\0'; + return 0; + } + +#else + DWORD env_len = GetEnvironmentVariable("CLAR_TMP", buffer, (DWORD)length); + if (env_len > 0 && env_len < (DWORD)length) + return 0; + + if (GetTempPath((DWORD)length, buffer)) + return 0; +#endif + + /* This system doesn't like us, try to use the current directory */ + if (is_valid_tmp_path(".")) { + strncpy(buffer, ".", length - 1); + buffer[length - 1] = '\0'; + return 0; + } + + return -1; +} + +static void clar_unsandbox(void) +{ + if (_clar_path[0] == '\0') + return; + + cl_must_pass(chdir("..")); + + fs_rm(_clar_path); +} + +static int build_sandbox_path(void) +{ +#ifdef CLAR_TMPDIR + const char path_tail[] = CLAR_TMPDIR "_XXXXXX"; +#else + const char path_tail[] = "clar_tmp_XXXXXX"; +#endif + + size_t len; + + if (find_tmp_path(_clar_path, sizeof(_clar_path)) < 0) + return -1; + + len = strlen(_clar_path); + +#ifdef _WIN32 + { /* normalize path to POSIX forward slashes */ + size_t i; + for (i = 0; i < len; ++i) { + if (_clar_path[i] == '\\') + _clar_path[i] = '/'; + } + } +#endif + + if (_clar_path[len - 1] != '/') { + _clar_path[len++] = '/'; + } + + strncpy(_clar_path + len, path_tail, sizeof(_clar_path) - len); + +#if defined(__MINGW32__) + if (_mktemp(_clar_path) == NULL) + return -1; + + if (mkdir(_clar_path, 0700) != 0) + return -1; +#elif defined(_WIN32) + if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0) + return -1; + + if (mkdir(_clar_path, 0700) != 0) + return -1; +#elif defined(__sun) || defined(__TANDEM) + if (mktemp(_clar_path) == NULL) + return -1; + + if (mkdir(_clar_path, 0700) != 0) + return -1; +#else + if (mkdtemp(_clar_path) == NULL) + return -1; +#endif + + return 0; +} + +static void clar_sandbox(void) +{ + if (_clar_path[0] == '\0' && build_sandbox_path() < 0) + clar_abort("Failed to build sandbox path.\n"); + + if (chdir(_clar_path) != 0) + clar_abort("Failed to change into sandbox directory '%s': %s.\n", + _clar_path, strerror(errno)); +} + +const char *clar_sandbox_path(void) +{ + return _clar_path; +} diff --git a/t/unit-tests/clar/clar/summary.h b/t/unit-tests/clar/clar/summary.h new file mode 100644 index 0000000000..0d0b646fe7 --- /dev/null +++ b/t/unit-tests/clar/clar/summary.h @@ -0,0 +1,139 @@ + +#include <stdio.h> +#include <time.h> + +static int clar_summary_close_tag( + struct clar_summary *summary, const char *tag, int indent) +{ + const char *indt; + + if (indent == 0) indt = ""; + else if (indent == 1) indt = "\t"; + else indt = "\t\t"; + + return fprintf(summary->fp, "%s</%s>\n", indt, tag); +} + +static int clar_summary_testsuites(struct clar_summary *summary) +{ + return fprintf(summary->fp, "<testsuites>\n"); +} + +static int clar_summary_testsuite(struct clar_summary *summary, + int idn, const char *name, time_t timestamp, + int test_count, int fail_count, int error_count) +{ + struct tm *tm = localtime(×tamp); + char iso_dt[20]; + + if (strftime(iso_dt, sizeof(iso_dt), "%Y-%m-%dT%H:%M:%S", tm) == 0) + return -1; + + return fprintf(summary->fp, "\t<testsuite" + " id=\"%d\"" + " name=\"%s\"" + " hostname=\"localhost\"" + " timestamp=\"%s\"" + " tests=\"%d\"" + " failures=\"%d\"" + " errors=\"%d\">\n", + idn, name, iso_dt, test_count, fail_count, error_count); +} + +static int clar_summary_testcase(struct clar_summary *summary, + const char *name, const char *classname, double elapsed) +{ + return fprintf(summary->fp, + "\t\t<testcase name=\"%s\" classname=\"%s\" time=\"%.2f\">\n", + name, classname, elapsed); +} + +static int clar_summary_failure(struct clar_summary *summary, + const char *type, const char *message, const char *desc) +{ + return fprintf(summary->fp, + "\t\t\t<failure type=\"%s\"><![CDATA[%s\n%s]]></failure>\n", + type, message, desc); +} + +static int clar_summary_skipped(struct clar_summary *summary) +{ + return fprintf(summary->fp, "\t\t\t<skipped />\n"); +} + +struct clar_summary *clar_summary_init(const char *filename) +{ + struct clar_summary *summary; + FILE *fp; + + 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) + clar_abort("Failed to allocate summary.\n"); + + summary->filename = filename; + summary->fp = fp; + + return summary; +} + +int clar_summary_shutdown(struct clar_summary *summary) +{ + struct clar_report *report; + const char *last_suite = NULL; + + if (clar_summary_testsuites(summary) < 0) + goto on_error; + + report = _clar.reports; + while (report != NULL) { + struct clar_error *error = report->errors; + + if (last_suite == NULL || strcmp(last_suite, report->suite) != 0) { + if (clar_summary_testsuite(summary, 0, report->suite, + report->start, _clar.tests_ran, _clar.total_errors, 0) < 0) + goto on_error; + } + + last_suite = report->suite; + + clar_summary_testcase(summary, report->test, report->suite, report->elapsed); + + while (error != NULL) { + if (clar_summary_failure(summary, "assert", + error->error_msg, error->description) < 0) + goto on_error; + + error = error->next; + } + + if (report->status == CL_TEST_SKIP) + clar_summary_skipped(summary); + + if (clar_summary_close_tag(summary, "testcase", 2) < 0) + goto on_error; + + report = report->next; + + if (!report || strcmp(last_suite, report->suite) != 0) { + if (clar_summary_close_tag(summary, "testsuite", 1) < 0) + goto on_error; + } + } + + if (clar_summary_close_tag(summary, "testsuites", 0) < 0 || + fclose(summary->fp) != 0) + goto on_error; + + printf("written summary file to %s\n", summary->filename); + + free(summary); + return 0; + +on_error: + fclose(summary->fp); + free(summary); + return -1; +} diff --git a/t/unit-tests/clar/generate.py b/t/unit-tests/clar/generate.py new file mode 100755 index 0000000000..80996ac3e7 --- /dev/null +++ b/t/unit-tests/clar/generate.py @@ -0,0 +1,266 @@ +#!/usr/bin/env python +# +# 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. +# + +from __future__ import with_statement +from string import Template +import re, fnmatch, os, sys, codecs, pickle + +class Module(object): + class Template(object): + def __init__(self, module): + self.module = module + + def _render_callback(self, cb): + if not cb: + return ' { NULL, NULL }' + return ' { "%s", &%s }' % (cb['short_name'], cb['symbol']) + + class DeclarationTemplate(Template): + def render(self): + out = "\n".join("extern %s;" % cb['declaration'] for cb in self.module.callbacks) + "\n" + + for initializer in self.module.initializers: + out += "extern %s;\n" % initializer['declaration'] + + if self.module.cleanup: + out += "extern %s;\n" % self.module.cleanup['declaration'] + + return out + + class CallbacksTemplate(Template): + def render(self): + out = "static const struct clar_func _clar_cb_%s[] = {\n" % self.module.name + out += ",\n".join(self._render_callback(cb) for cb in self.module.callbacks) + out += "\n};\n" + return out + + class InfoTemplate(Template): + def render(self): + templates = [] + + initializers = self.module.initializers + if len(initializers) == 0: + initializers = [ None ] + + for initializer in initializers: + name = self.module.clean_name() + if initializer and initializer['short_name'].startswith('initialize_'): + variant = initializer['short_name'][len('initialize_'):] + name += " (%s)" % variant.replace('_', ' ') + + template = Template( + r""" + { + "${clean_name}", + ${initialize}, + ${cleanup}, + ${cb_ptr}, ${cb_count}, ${enabled} + }""" + ).substitute( + clean_name = name, + initialize = self._render_callback(initializer), + cleanup = self._render_callback(self.module.cleanup), + cb_ptr = "_clar_cb_%s" % self.module.name, + cb_count = len(self.module.callbacks), + enabled = int(self.module.enabled) + ) + templates.append(template) + + return ','.join(templates) + + def __init__(self, name): + self.name = name + + self.mtime = None + self.enabled = True + self.modified = False + + def clean_name(self): + return self.name.replace("_", "::") + + def _skip_comments(self, text): + SKIP_COMMENTS_REGEX = re.compile( + r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', + re.DOTALL | re.MULTILINE) + + def _replacer(match): + s = match.group(0) + return "" if s.startswith('/') else s + + return re.sub(SKIP_COMMENTS_REGEX, _replacer, text) + + def parse(self, contents): + TEST_FUNC_REGEX = r"^(void\s+(test_%s__(\w+))\s*\(\s*void\s*\))\s*\{" + + contents = self._skip_comments(contents) + regex = re.compile(TEST_FUNC_REGEX % self.name, re.MULTILINE) + + self.callbacks = [] + self.initializers = [] + self.cleanup = None + + for (declaration, symbol, short_name) in regex.findall(contents): + data = { + "short_name" : short_name, + "declaration" : declaration, + "symbol" : symbol + } + + if short_name.startswith('initialize'): + self.initializers.append(data) + elif short_name == 'cleanup': + self.cleanup = data + else: + self.callbacks.append(data) + + return self.callbacks != [] + + def refresh(self, path): + self.modified = False + + try: + st = os.stat(path) + + # Not modified + if st.st_mtime == self.mtime: + return True + + self.modified = True + self.mtime = st.st_mtime + + with codecs.open(path, encoding='utf-8') as fp: + raw_content = fp.read() + + except IOError: + return False + + return self.parse(raw_content) + +class TestSuite(object): + + def __init__(self, path, output): + self.path = path + self.output = output + + def should_generate(self, path): + if not os.path.isfile(path): + return True + + if any(module.modified for module in self.modules.values()): + return True + + return False + + def find_modules(self): + modules = [] + for root, _, files in os.walk(self.path): + module_root = root[len(self.path):] + module_root = [c for c in module_root.split(os.sep) if c] + + tests_in_module = fnmatch.filter(files, "*.c") + + for test_file in tests_in_module: + full_path = os.path.join(root, test_file) + module_name = "_".join(module_root + [test_file[:-2]]).replace("-", "_") + + modules.append((full_path, module_name)) + + return modules + + def load_cache(self): + path = os.path.join(self.output, '.clarcache') + cache = {} + + try: + fp = open(path, 'rb') + cache = pickle.load(fp) + fp.close() + except (IOError, ValueError): + pass + + return cache + + def save_cache(self): + path = os.path.join(self.output, '.clarcache') + with open(path, 'wb') as cache: + pickle.dump(self.modules, cache) + + def load(self, force = False): + module_data = self.find_modules() + self.modules = {} if force else self.load_cache() + + for path, name in module_data: + if name not in self.modules: + self.modules[name] = Module(name) + + if not self.modules[name].refresh(path): + del self.modules[name] + + def disable(self, excluded): + for exclude in excluded: + for module in self.modules.values(): + name = module.clean_name() + if name.startswith(exclude): + module.enabled = False + module.modified = True + + def suite_count(self): + return sum(max(1, len(m.initializers)) for m in self.modules.values()) + + def callback_count(self): + return sum(len(module.callbacks) for module in self.modules.values()) + + def write(self): + output = os.path.join(self.output, 'clar.suite') + + if not self.should_generate(output): + return False + + with open(output, 'w') as data: + modules = sorted(self.modules.values(), key=lambda module: module.name) + + for module in modules: + t = Module.DeclarationTemplate(module) + data.write(t.render()) + + for module in modules: + t = Module.CallbacksTemplate(module) + data.write(t.render()) + + suites = "static struct clar_suite _clar_suites[] = {" + ','.join( + Module.InfoTemplate(module).render() for module in modules + ) + "\n};\n" + + data.write(suites) + + data.write("static const size_t _clar_suite_count = %d;\n" % self.suite_count()) + data.write("static const size_t _clar_callback_count = %d;\n" % self.callback_count()) + + self.save_cache() + return True + +if __name__ == '__main__': + from optparse import OptionParser + + parser = OptionParser() + parser.add_option('-f', '--force', action="store_true", dest='force', default=False) + parser.add_option('-x', '--exclude', dest='excluded', action='append', default=[]) + parser.add_option('-o', '--output', dest='output') + + options, args = parser.parse_args() + if len(args) > 1: + print("More than one path given") + sys.exit(1) + + path = args.pop() if args else '.' + output = options.output or path + suite = TestSuite(path, output) + suite.load(options.force) + suite.disable(options.excluded) + if suite.write(): + print("Written `clar.suite` (%d tests in %d suites)" % (suite.callback_count(), suite.suite_count())) diff --git a/t/unit-tests/clar/test/CMakeLists.txt b/t/unit-tests/clar/test/CMakeLists.txt new file mode 100644 index 0000000000..7f2c1dc17a --- /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/clar_test.h b/t/unit-tests/clar/test/clar_test.h new file mode 100644 index 0000000000..0fcaa639aa --- /dev/null +++ b/t/unit-tests/clar/test/clar_test.h @@ -0,0 +1,16 @@ +/* + * 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. + */ +#ifndef __CLAR_TEST__ +#define __CLAR_TEST__ + +/* Import the standard clar helper functions */ +#include "clar.h" + +/* Your custom shared includes / defines here */ +extern int global_test_counter; + +#endif diff --git a/t/unit-tests/clar/test/main.c b/t/unit-tests/clar/test/main.c new file mode 100644 index 0000000000..59e56ad255 --- /dev/null +++ b/t/unit-tests/clar/test/main.c @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#include "clar_test.h" + +/* + * Sample main() for clar tests. + * + * You should write your own main routine for clar tests that does specific + * setup and teardown as necessary for your application. The only required + * line is the call to `clar_test(argc, argv)`, which will execute the test + * suite. If you want to check the return value of the test application, + * your main() should return the same value returned by clar_test(). + */ + +int global_test_counter = 0; + +#ifdef _WIN32 +int __cdecl main(int argc, char *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + int ret; + + /* Your custom initialization here */ + global_test_counter = 0; + + /* Run the test suite */ + ret = clar_test(argc, argv); + + /* Your custom cleanup here */ + cl_assert_equal_i(8, global_test_counter); + + return ret; +} diff --git a/t/unit-tests/clar/test/main.c.sample b/t/unit-tests/clar/test/main.c.sample new file mode 100644 index 0000000000..a4d91b72fa --- /dev/null +++ b/t/unit-tests/clar/test/main.c.sample @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#include "clar_test.h" + +/* + * Minimal main() for clar tests. + * + * Modify this with any application specific setup or teardown that you need. + * The only required line is the call to `clar_test(argc, argv)`, which will + * execute the test suite. If you want to check the return value of the test + * application, main() should return the same value returned by clar_test(). + */ + +#ifdef _WIN32 +int __cdecl main(int argc, char *argv[]) +#else +int main(int argc, char *argv[]) +#endif +{ + /* Run the test suite */ + return clar_test(argc, argv); +} diff --git a/t/unit-tests/clar/test/resources/test/file b/t/unit-tests/clar/test/resources/test/file new file mode 100644 index 0000000000..220f4aa98a --- /dev/null +++ b/t/unit-tests/clar/test/resources/test/file @@ -0,0 +1 @@ +File diff --git a/t/unit-tests/clar/test/sample.c b/t/unit-tests/clar/test/sample.c new file mode 100644 index 0000000000..faa1209262 --- /dev/null +++ b/t/unit-tests/clar/test/sample.c @@ -0,0 +1,84 @@ +#include "clar_test.h" +#include <sys/stat.h> + +static int file_size(const char *filename) +{ + struct stat st; + + if (stat(filename, &st) == 0) + return (int)st.st_size; + return -1; +} + +void test_sample__initialize(void) +{ + global_test_counter++; +} + +void test_sample__cleanup(void) +{ + cl_fixture_cleanup("test"); + + cl_assert(file_size("test/file") == -1); +} + +void test_sample__1(void) +{ + cl_assert(1); + cl_must_pass(0); /* 0 == success */ + cl_must_fail(-1); /* <0 == failure */ + cl_must_pass(-1); /* demonstrate a failing call */ +} + +void test_sample__2(void) +{ + cl_fixture_sandbox("test"); + + cl_assert(file_size("test/nonexistent") == -1); + cl_assert(file_size("test/file") > 0); + cl_assert(100 == 101); +} + +void test_sample__strings(void) +{ + const char *actual = "expected"; + cl_assert_equal_s("expected", actual); + cl_assert_equal_s_("expected", actual, "second try with annotation"); + cl_assert_equal_s_("mismatched", actual, "this one fails"); +} + +void test_sample__strings_with_length(void) +{ + const char *actual = "expected"; + cl_assert_equal_strn("expected_", actual, 8); + cl_assert_equal_strn("exactly", actual, 2); + cl_assert_equal_strn_("expected_", actual, 8, "with annotation"); + cl_assert_equal_strn_("exactly", actual, 3, "this one fails"); +} + +void test_sample__int(void) +{ + int value = 100; + cl_assert_equal_i(100, value); + cl_assert_equal_i_(101, value, "extra note on failing test"); +} + +void test_sample__int_fmt(void) +{ + int value = 100; + cl_assert_equal_i_fmt(022, value, "%04o"); +} + +void test_sample__bool(void) +{ + int value = 100; + cl_assert_equal_b(1, value); /* test equality as booleans */ + cl_assert_equal_b(0, value); +} + +void test_sample__ptr(void) +{ + const char *actual = "expected"; + cl_assert_equal_p(actual, actual); /* pointers to same object */ + cl_assert_equal_p(&actual, actual); +} diff --git a/t/unit-tests/t-ctype.c b/t/unit-tests/ctype.c index 6043f0d9bc..32e65867cd 100644 --- a/t/unit-tests/t-ctype.c +++ b/t/unit-tests/ctype.c @@ -1,16 +1,16 @@ -#include "test-lib.h" +#include "unit-test.h" #define TEST_CHAR_CLASS(class, string) do { \ size_t len = ARRAY_SIZE(string) - 1 + \ BUILD_ASSERT_OR_ZERO(ARRAY_SIZE(string) > 0) + \ BUILD_ASSERT_OR_ZERO(sizeof(string[0]) == sizeof(char)); \ - if_test (#class " works") { \ - for (int i = 0; i < 256; i++) { \ - if (!check_int(class(i), ==, !!memchr(string, i, len)))\ - test_msg(" i: 0x%02x", i); \ - } \ - check(!class(EOF)); \ + for (int i = 0; i < 256; i++) { \ + int actual = class(i), expect = !!memchr(string, i, len); \ + if (actual != expect) \ + cl_failf("0x%02x is classified incorrectly: expected %d, got %d", \ + i, expect, actual); \ } \ + cl_assert(!class(EOF)); \ } while (0) #define DIGIT "0123456789" @@ -31,21 +31,72 @@ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ "\x7f" -int cmd_main(int argc UNUSED, const char **argv UNUSED) { +void test_ctype__isspace(void) +{ TEST_CHAR_CLASS(isspace, " \n\r\t"); +} + +void test_ctype__isdigit(void) +{ TEST_CHAR_CLASS(isdigit, DIGIT); +} + +void test_ctype__isalpha(void) +{ TEST_CHAR_CLASS(isalpha, LOWER UPPER); +} + +void test_ctype__isalnum(void) +{ TEST_CHAR_CLASS(isalnum, LOWER UPPER DIGIT); +} + +void test_ctype__is_glob_special(void) +{ TEST_CHAR_CLASS(is_glob_special, "*?[\\"); +} + +void test_ctype__is_regex_special(void) +{ TEST_CHAR_CLASS(is_regex_special, "$()*+.?[\\^{|"); +} + +void test_ctype__is_pathspec_magic(void) +{ TEST_CHAR_CLASS(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~"); +} + +void test_ctype__isascii(void) +{ TEST_CHAR_CLASS(isascii, ASCII); +} + +void test_ctype__islower(void) +{ TEST_CHAR_CLASS(islower, LOWER); +} + +void test_ctype__isupper(void) +{ TEST_CHAR_CLASS(isupper, UPPER); +} + +void test_ctype__iscntrl(void) +{ TEST_CHAR_CLASS(iscntrl, CNTRL); +} + +void test_ctype__ispunct(void) +{ TEST_CHAR_CLASS(ispunct, PUNCT); +} + +void test_ctype__isxdigit(void) +{ TEST_CHAR_CLASS(isxdigit, DIGIT "abcdefABCDEF"); - TEST_CHAR_CLASS(isprint, LOWER UPPER DIGIT PUNCT " "); +} - return test_done(); +void test_ctype__isprint(void) +{ + TEST_CHAR_CLASS(isprint, LOWER UPPER DIGIT PUNCT " "); } diff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh new file mode 100755 index 0000000000..688e0885f4 --- /dev/null +++ b/t/unit-tests/generate-clar-decls.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +if test $# -lt 2 +then + echo "USAGE: $0 <OUTPUT> <SUITE>..." 2>&1 + exit 1 +fi + +OUTPUT="$1" +shift + +for suite in "$@" +do + sed -ne "s/^\(void test_$(basename "${suite%.c}")__[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 0000000000..d5c712221e --- /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-reftable.c b/t/unit-tests/lib-reftable.c index 54c26c43e7..d795dfb7c9 100644 --- a/t/unit-tests/lib-reftable.c +++ b/t/unit-tests/lib-reftable.c @@ -2,8 +2,9 @@ #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,7 +20,7 @@ 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) { struct reftable_writer *writer; @@ -29,7 +30,7 @@ struct reftable_writer *t_reftable_strbuf_writer(struct strbuf *buf, 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, @@ -82,7 +83,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 d115419084..e4c360fa7e 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/strvec.c b/t/unit-tests/strvec.c new file mode 100644 index 0000000000..e66b7bbfae --- /dev/null +++ b/t/unit-tests/strvec.c @@ -0,0 +1,316 @@ +#include "unit-test.h" +#include "strbuf.h" +#include "strvec.h" + +#define check_strvec(vec, ...) \ + do { \ + const char *expect[] = { __VA_ARGS__ }; \ + size_t expect_len = ARRAY_SIZE(expect); \ + cl_assert(expect_len > 0); \ + cl_assert_equal_p(expect[expect_len - 1], NULL); \ + cl_assert_equal_i((vec)->nr, expect_len - 1); \ + cl_assert((vec)->nr <= (vec)->alloc); \ + for (size_t i = 0; i < expect_len; i++) \ + cl_assert_equal_s((vec)->v[i], expect[i]); \ + } while (0) + +void test_strvec__init(void) +{ + struct strvec vec = STRVEC_INIT; + + cl_assert_equal_p(vec.v, empty_strvec); + cl_assert_equal_i(vec.nr, 0); + cl_assert_equal_i(vec.alloc, 0); +} + +void test_strvec__dynamic_init(void) +{ + struct strvec vec; + + strvec_init(&vec); + cl_assert_equal_p(vec.v, empty_strvec); + cl_assert_equal_i(vec.nr, 0); + cl_assert_equal_i(vec.alloc, 0); +} + +void test_strvec__clear(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_push(&vec, "foo"); + strvec_clear(&vec); + cl_assert_equal_p(vec.v, empty_strvec); + cl_assert_equal_i(vec.nr, 0); + cl_assert_equal_i(vec.alloc, 0); +} + +void test_strvec__push(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_push(&vec, "foo"); + check_strvec(&vec, "foo", NULL); + + strvec_push(&vec, "bar"); + check_strvec(&vec, "foo", "bar", NULL); + + strvec_clear(&vec); +} + +void test_strvec__pushf(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushf(&vec, "foo: %d", 1); + check_strvec(&vec, "foo: 1", NULL); + strvec_clear(&vec); +} + +void test_strvec__pushl(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + check_strvec(&vec, "foo", "bar", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__pushv(void) +{ + const char *strings[] = { + "foo", "bar", "baz", NULL, + }; + struct strvec vec = STRVEC_INIT; + + strvec_pushv(&vec, strings); + check_strvec(&vec, "foo", "bar", "baz", NULL); + + 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; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_replace(&vec, 0, "replaced"); + check_strvec(&vec, "replaced", "bar", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__replace_at_tail(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_replace(&vec, 2, "replaced"); + check_strvec(&vec, "foo", "bar", "replaced", NULL); + strvec_clear(&vec); +} + +void test_strvec__replace_in_between(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_replace(&vec, 1, "replaced"); + check_strvec(&vec, "foo", "replaced", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__replace_with_substring(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", NULL); + strvec_replace(&vec, 0, vec.v[0] + 1); + check_strvec(&vec, "oo", NULL); + strvec_clear(&vec); +} + +void test_strvec__remove_at_head(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_remove(&vec, 0); + check_strvec(&vec, "bar", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__remove_at_tail(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_remove(&vec, 2); + check_strvec(&vec, "foo", "bar", NULL); + strvec_clear(&vec); +} + +void test_strvec__remove_in_between(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_remove(&vec, 1); + check_strvec(&vec, "foo", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__pop_empty_array(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pop(&vec); + check_strvec(&vec, NULL); + strvec_clear(&vec); +} + +void test_strvec__pop_non_empty_array(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_pop(&vec); + check_strvec(&vec, "foo", "bar", NULL); + strvec_clear(&vec); +} + +void test_strvec__split_empty_string(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_split(&vec, ""); + check_strvec(&vec, NULL); + strvec_clear(&vec); +} + +void test_strvec__split_single_item(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_split(&vec, "foo"); + check_strvec(&vec, "foo", NULL); + strvec_clear(&vec); +} + +void test_strvec__split_multiple_items(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_split(&vec, "foo bar baz"); + check_strvec(&vec, "foo", "bar", "baz", NULL); + strvec_clear(&vec); +} + +void test_strvec__split_whitespace_only(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_split(&vec, " \t\n"); + check_strvec(&vec, NULL); + strvec_clear(&vec); +} + +void test_strvec__split_multiple_consecutive_whitespaces(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_split(&vec, "foo\n\t bar"); + check_strvec(&vec, "foo", "bar", NULL); + strvec_clear(&vec); +} + +void test_strvec__detach(void) +{ + struct strvec vec = STRVEC_INIT; + const char **detached; + + strvec_push(&vec, "foo"); + + detached = strvec_detach(&vec); + cl_assert_equal_s(detached[0], "foo"); + cl_assert_equal_p(detached[1], NULL); + + cl_assert_equal_p(vec.v, empty_strvec); + cl_assert_equal_i(vec.nr, 0); + cl_assert_equal_i(vec.alloc, 0); + + free((char *) detached[0]); + free(detached); +} diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c index 1fa77b6faf..65d50df091 100644 --- a/t/unit-tests/t-reftable-basics.c +++ b/t/unit-tests/t-reftable-basics.c @@ -54,7 +54,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); } @@ -99,8 +99,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; @@ -113,14 +113,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(!reftable_buf_addstr(&a, cases[i].a)); + check(!reftable_buf_addstr(&b, cases[i].b)); check_int(common_prefix_size(&a, &b), ==, cases[i].want); - strbuf_reset(&a); - strbuf_reset(&b); + 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") { diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index d470060e8b..22040aeefa 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -11,6 +11,7 @@ https://developers.google.com/open-source/licenses/bsd #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,14 +30,14 @@ 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_source_from_buf(&block.source ,&buf); ret = block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); rec.u.ref.refname = (char *) ""; @@ -47,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); @@ -61,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); @@ -72,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++) { @@ -85,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); @@ -93,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]); } @@ -114,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, @@ -123,14 +124,14 @@ 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_source_from_buf(&block.source ,&buf); ret = block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); for (i = 0; i < N; i++) { @@ -150,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); @@ -161,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); @@ -175,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); @@ -183,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]); } @@ -204,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, @@ -213,14 +214,14 @@ 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_source_from_buf(&block.source, &buf); ret = block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); for (i = 0; i < N; i++) { @@ -242,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); @@ -253,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++) { @@ -266,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]); } @@ -287,31 +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_source_from_buf(&block.source, &buf); ret = block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + 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]); @@ -323,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); @@ -334,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++) { @@ -347,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); @@ -355,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 3c84363e98..a12bd0e1a3 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 = { @@ -35,14 +35,14 @@ merged_table_from_records(struct reftable_ref_record **refs, 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; } @@ -75,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 = @@ -91,13 +91,13 @@ static void t_merged_single_record(void) 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); } @@ -152,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 = @@ -168,7 +168,7 @@ static void t_merged_refs(void) 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); @@ -186,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); @@ -234,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; @@ -252,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); @@ -265,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); @@ -277,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 = { @@ -293,14 +365,14 @@ merged_table_from_log_records(struct reftable_log_record **logs, 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; } @@ -361,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( @@ -377,7 +449,7 @@ static void t_merged_logs(void) 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); @@ -395,7 +467,7 @@ 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)); err = merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); check(!err); @@ -404,7 +476,7 @@ static void t_merged_logs(void) 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++) @@ -412,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); @@ -421,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", @@ -442,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); } @@ -467,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 ada4c19f18..f3f8a0cdf3 100644 --- a/t/unit-tests/t-reftable-pq.c +++ b/t/unit-tests/t-reftable-pq.c @@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd #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 eea86966c0..546df6005e 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 27ce84445e..91c881aedf 100644 --- a/t/unit-tests/t-reftable-readwrite.c +++ b/t/unit-tests/t-reftable-readwrite.c @@ -13,18 +13,19 @@ https://developers.google.com/open-source/licenses/bsd #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 +38,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, @@ -62,7 +63,7 @@ static void write_table(char ***names, struct strbuf *buf, int N, 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++) { @@ -70,7 +71,7 @@ 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"; } @@ -82,7 +83,7 @@ static void write_table(char ***names, struct strbuf *buf, int N, 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, }; @@ -104,7 +105,7 @@ 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++) { + for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) { log.value.update.old_hash[i] = (uint8_t)(git_rand() % 256); log.value.update.new_hash[i] = (uint8_t)(git_rand() % 256); } @@ -114,12 +115,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), @@ -148,7 +149,7 @@ 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) @@ -161,7 +162,7 @@ static void t_log_write_read(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; int N = 2, err, i, n; @@ -191,9 +192,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); @@ -207,7 +208,7 @@ 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); @@ -247,7 +248,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); } @@ -260,7 +261,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 }; @@ -298,7 +299,7 @@ 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); @@ -312,13 +313,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 }; @@ -326,9 +327,9 @@ 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); @@ -352,25 +353,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 }; @@ -378,9 +379,9 @@ 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); @@ -393,17 +394,17 @@ static void t_table_read_api(void) 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 }; @@ -411,12 +412,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); @@ -443,8 +444,8 @@ 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, "/")); err = reftable_reader_init_ref_iterator(reader, &it); check(!err); @@ -457,34 +458,34 @@ 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) { 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, @@ -492,7 +493,7 @@ static void t_table_refs_for(int indexed) struct reftable_ref_record ref = { 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); struct reftable_iterator it = { 0 }; int N = 50, n, j, err, i; @@ -500,10 +501,10 @@ static void t_table_refs_for(int indexed) 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 }; @@ -517,9 +518,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 */ @@ -527,8 +528,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); } @@ -538,7 +539,7 @@ 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); @@ -565,7 +566,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); @@ -584,7 +585,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; @@ -600,7 +601,7 @@ static void t_write_empty_table(void) check_int(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); @@ -615,7 +616,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) @@ -623,7 +624,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, @@ -649,7 +650,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) @@ -657,7 +658,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, @@ -684,13 +685,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 *) "", @@ -706,13 +707,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] = { { @@ -745,7 +746,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) @@ -753,12 +754,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); @@ -770,9 +772,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); @@ -788,9 +789,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); @@ -807,7 +807,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); @@ -823,8 +823,7 @@ static void t_write_multiple_indices(void) 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) @@ -832,7 +831,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; @@ -848,10 +847,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); @@ -865,7 +864,7 @@ 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); @@ -880,18 +879,18 @@ static void t_write_multi_level_index(void) 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); } @@ -899,17 +898,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) diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c index a7f67d4d9f..42bc64cec8 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(©); } @@ -59,7 +60,7 @@ static void t_varint_roundtrip(void) static void set_hash(uint8_t *h, int j) { - for (int i = 0; i < hash_size(GIT_SHA1_FORMAT_ID); i++) + for (int i = 0; i < hash_size(REFTABLE_HASH_SHA1); i++) h[i] = (j >> i) & 0xff; } @@ -84,14 +85,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 +117,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 +125,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 +156,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 +194,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 +263,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 +275,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 +304,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 +328,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 +381,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 +414,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 +428,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 +436,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 +457,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 +494,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 +502,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) diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c index cc2db2cdef..b2f6c1c37e 100644 --- a/t/unit-tests/t-reftable-stack.c +++ b/t/unit-tests/t-reftable-stack.c @@ -8,15 +8,18 @@ https://developers.google.com/open-source/licenses/bsd #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); @@ -105,7 +108,6 @@ static int write_test_ref(struct reftable_writer *wr, void *arg) 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 +119,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 { @@ -147,7 +148,7 @@ static int write_test_log(struct reftable_writer *wr, void *arg) 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 +171,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 +195,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); } @@ -267,7 +268,7 @@ static void t_reftable_stack_transaction_api(void) reftable_addition_destroy(add); - err = reftable_stack_new_addition(&add, st); + err = reftable_stack_new_addition(&add, st, 0); check(!err); err = reftable_addition_add(add, write_test_ref, &ref); @@ -281,13 +282,75 @@ 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); clear_dir(dir); } +static void t_reftable_stack_transaction_with_reload(void) +{ + char *dir = get_tmp_dir(__LINE__); + struct reftable_stack *st1 = NULL, *st2 = NULL; + int err; + struct reftable_addition *add = NULL; + struct reftable_ref_record refs[2] = { + { + .refname = (char *) "refs/heads/a", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { '1' }, + }, + { + .refname = (char *) "refs/heads/b", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { '1' }, + }, + }; + struct reftable_ref_record ref = { 0 }; + + err = reftable_new_stack(&st1, dir, NULL); + check(!err); + err = reftable_new_stack(&st2, dir, NULL); + check(!err); + + err = reftable_stack_new_addition(&add, st1, 0); + check(!err); + err = reftable_addition_add(add, write_test_ref, &refs[0]); + check(!err); + err = reftable_addition_commit(add); + check(!err); + reftable_addition_destroy(add); + + /* + * The second stack is now outdated, which we should notice. We do not + * create the addition and lock the stack by default, but allow the + * reload to happen when REFTABLE_STACK_NEW_ADDITION_RELOAD is set. + */ + err = reftable_stack_new_addition(&add, st2, 0); + check_int(err, ==, REFTABLE_OUTDATED_ERROR); + err = reftable_stack_new_addition(&add, st2, REFTABLE_STACK_NEW_ADDITION_RELOAD); + check(!err); + err = reftable_addition_add(add, write_test_ref, &refs[1]); + check(!err); + err = reftable_addition_commit(add); + check(!err); + reftable_addition_destroy(add); + + 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, REFTABLE_HASH_SIZE_SHA1)); + } + + reftable_ref_record_release(&ref); + reftable_stack_destroy(st1); + reftable_stack_destroy(st2); + clear_dir(dir); +} + static void t_reftable_stack_transaction_api_performs_auto_compaction(void) { char *dir = get_tmp_dir(__LINE__); @@ -318,7 +381,7 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void) */ st->opts.disable_auto_compact = i != n; - err = reftable_stack_new_addition(&add, st); + err = reftable_stack_new_addition(&add, st, 0); check(!err); err = reftable_addition_add(add, write_test_ref, &ref); @@ -354,7 +417,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; @@ -372,7 +435,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; @@ -383,7 +449,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); } @@ -453,7 +519,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); @@ -466,13 +532,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++) { @@ -498,7 +564,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); } @@ -507,22 +573,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); @@ -536,7 +602,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); } @@ -558,14 +624,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++) { @@ -592,7 +658,7 @@ 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); @@ -610,7 +676,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); @@ -703,7 +769,7 @@ 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); @@ -712,7 +778,7 @@ static void t_reftable_stack_tombstone(void) 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"); } @@ -772,7 +838,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; @@ -795,7 +861,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); @@ -845,7 +911,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++) { @@ -1000,7 +1066,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; @@ -1015,8 +1081,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); /* @@ -1031,7 +1099,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); } @@ -1039,7 +1107,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; @@ -1053,6 +1120,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 @@ -1061,9 +1129,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); @@ -1080,7 +1147,6 @@ static void t_reftable_stack_add_performs_auto_compaction(void) } reftable_stack_destroy(st); - strbuf_release(&refname); clear_dir(dir); } @@ -1090,7 +1156,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; @@ -1101,8 +1167,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); /* @@ -1115,7 +1183,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); } @@ -1241,7 +1309,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; @@ -1259,10 +1327,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); @@ -1287,8 +1358,8 @@ 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); } @@ -1315,6 +1386,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_reftable_stack_reload_with_missing_table(), "stack iteration with garbage tables"); TEST(t_reftable_stack_tombstone(), "'tombstone' refs in stack"); TEST(t_reftable_stack_transaction_api(), "update transaction to stack"); + TEST(t_reftable_stack_transaction_with_reload(), "transaction with reload"); TEST(t_reftable_stack_transaction_api_performs_auto_compaction(), "update transaction triggers auto-compaction"); TEST(t_reftable_stack_update_index_check(), "update transactions with equal update indices"); TEST(t_reftable_stack_uptodate(), "stack must be reloaded before ref update"); diff --git a/t/unit-tests/t-strvec.c b/t/unit-tests/t-strvec.c deleted file mode 100644 index 5c844cf0c9..0000000000 --- a/t/unit-tests/t-strvec.c +++ /dev/null @@ -1,211 +0,0 @@ -#include "test-lib.h" -#include "strbuf.h" -#include "strvec.h" - -#define check_strvec(vec, ...) \ - do { \ - const char *expect[] = { __VA_ARGS__ }; \ - if (check_uint(ARRAY_SIZE(expect), >, 0) && \ - check_pointer_eq(expect[ARRAY_SIZE(expect) - 1], NULL) && \ - check_uint((vec)->nr, ==, ARRAY_SIZE(expect) - 1) && \ - check_uint((vec)->nr, <=, (vec)->alloc)) { \ - for (size_t i = 0; i < ARRAY_SIZE(expect); i++) { \ - if (!check_str((vec)->v[i], expect[i])) { \ - test_msg(" i: %"PRIuMAX, \ - (uintmax_t)i); \ - break; \ - } \ - } \ - } \ - } while (0) - -int cmd_main(int argc UNUSED, const char **argv UNUSED) -{ - if_test ("static initialization") { - struct strvec vec = STRVEC_INIT; - check_pointer_eq(vec.v, empty_strvec); - check_uint(vec.nr, ==, 0); - check_uint(vec.alloc, ==, 0); - } - - if_test ("dynamic initialization") { - struct strvec vec; - strvec_init(&vec); - check_pointer_eq(vec.v, empty_strvec); - check_uint(vec.nr, ==, 0); - check_uint(vec.alloc, ==, 0); - } - - if_test ("clear") { - struct strvec vec = STRVEC_INIT; - strvec_push(&vec, "foo"); - strvec_clear(&vec); - check_pointer_eq(vec.v, empty_strvec); - check_uint(vec.nr, ==, 0); - check_uint(vec.alloc, ==, 0); - } - - if_test ("push") { - struct strvec vec = STRVEC_INIT; - - strvec_push(&vec, "foo"); - check_strvec(&vec, "foo", NULL); - - strvec_push(&vec, "bar"); - check_strvec(&vec, "foo", "bar", NULL); - - strvec_clear(&vec); - } - - if_test ("pushf") { - struct strvec vec = STRVEC_INIT; - strvec_pushf(&vec, "foo: %d", 1); - check_strvec(&vec, "foo: 1", NULL); - strvec_clear(&vec); - } - - if_test ("pushl") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - check_strvec(&vec, "foo", "bar", "baz", NULL); - strvec_clear(&vec); - } - - if_test ("pushv") { - const char *strings[] = { - "foo", "bar", "baz", NULL, - }; - struct strvec vec = STRVEC_INIT; - - strvec_pushv(&vec, strings); - check_strvec(&vec, "foo", "bar", "baz", NULL); - - strvec_clear(&vec); - } - - if_test ("replace at head") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_replace(&vec, 0, "replaced"); - check_strvec(&vec, "replaced", "bar", "baz", NULL); - strvec_clear(&vec); - } - - if_test ("replace at tail") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_replace(&vec, 2, "replaced"); - check_strvec(&vec, "foo", "bar", "replaced", NULL); - strvec_clear(&vec); - } - - if_test ("replace in between") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_replace(&vec, 1, "replaced"); - check_strvec(&vec, "foo", "replaced", "baz", NULL); - strvec_clear(&vec); - } - - if_test ("replace with substring") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", NULL); - strvec_replace(&vec, 0, vec.v[0] + 1); - check_strvec(&vec, "oo", NULL); - strvec_clear(&vec); - } - - if_test ("remove at head") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_remove(&vec, 0); - check_strvec(&vec, "bar", "baz", NULL); - strvec_clear(&vec); - } - - if_test ("remove at tail") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_remove(&vec, 2); - check_strvec(&vec, "foo", "bar", NULL); - strvec_clear(&vec); - } - - if_test ("remove in between") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_remove(&vec, 1); - check_strvec(&vec, "foo", "baz", NULL); - strvec_clear(&vec); - } - - if_test ("pop with empty array") { - struct strvec vec = STRVEC_INIT; - strvec_pop(&vec); - check_strvec(&vec, NULL); - strvec_clear(&vec); - } - - if_test ("pop with non-empty array") { - struct strvec vec = STRVEC_INIT; - strvec_pushl(&vec, "foo", "bar", "baz", NULL); - strvec_pop(&vec); - check_strvec(&vec, "foo", "bar", NULL); - strvec_clear(&vec); - } - - if_test ("split empty string") { - struct strvec vec = STRVEC_INIT; - strvec_split(&vec, ""); - check_strvec(&vec, NULL); - strvec_clear(&vec); - } - - if_test ("split single item") { - struct strvec vec = STRVEC_INIT; - strvec_split(&vec, "foo"); - check_strvec(&vec, "foo", NULL); - strvec_clear(&vec); - } - - if_test ("split multiple items") { - struct strvec vec = STRVEC_INIT; - strvec_split(&vec, "foo bar baz"); - check_strvec(&vec, "foo", "bar", "baz", NULL); - strvec_clear(&vec); - } - - if_test ("split whitespace only") { - struct strvec vec = STRVEC_INIT; - strvec_split(&vec, " \t\n"); - check_strvec(&vec, NULL); - strvec_clear(&vec); - } - - if_test ("split multiple consecutive whitespaces") { - struct strvec vec = STRVEC_INIT; - strvec_split(&vec, "foo\n\t bar"); - check_strvec(&vec, "foo", "bar", NULL); - strvec_clear(&vec); - } - - if_test ("detach") { - struct strvec vec = STRVEC_INIT; - const char **detached; - - strvec_push(&vec, "foo"); - - detached = strvec_detach(&vec); - check_str(detached[0], "foo"); - check_pointer_eq(detached[1], NULL); - - check_pointer_eq(vec.v, empty_strvec); - check_uint(vec.nr, ==, 0); - check_uint(vec.alloc, ==, 0); - - free((char *) detached[0]); - free(detached); - } - - return test_done(); -} diff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c new file mode 100644 index 0000000000..a474cdcfd3 --- /dev/null +++ b/t/unit-tests/unit-test.c @@ -0,0 +1,47 @@ +#include "unit-test.h" +#include "parse-options.h" +#include "string-list.h" +#include "strvec.h" + +static const char * const unit_test_usage[] = { + N_("unit-test [<options>]"), + NULL, +}; + +int cmd_main(int argc, const char **argv) +{ + struct string_list run_args = STRING_LIST_INIT_NODUP; + struct string_list exclude_args = STRING_LIST_INIT_NODUP; + int immediate = 0; + struct option options[] = { + OPT_BOOL('i', "immediate", &immediate, + 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"), + N_("exclude test suite <suite>")), + OPT_END(), + }; + struct strvec args = STRVEC_INIT; + int ret; + + argc = parse_options(argc, argv, NULL, options, + unit_test_usage, PARSE_OPT_KEEP_ARGV0); + if (argc > 1) + usagef(_("extra command line parameter '%s'"), argv[0]); + + strvec_push(&args, argv[0]); + strvec_push(&args, "-t"); + if (immediate) + strvec_push(&args, "-Q"); + for (size_t i = 0; i < run_args.nr; i++) + strvec_pushf(&args, "-s%s", run_args.items[i].string); + for (size_t i = 0; i < exclude_args.nr; i++) + strvec_pushf(&args, "-x%s", exclude_args.items[i].string); + + ret = clar_test(args.nr, (char **) args.v); + + string_list_clear(&run_args, 0); + strvec_clear(&args); + return ret; +} diff --git a/t/unit-tests/unit-test.h b/t/unit-tests/unit-test.h new file mode 100644 index 0000000000..85e5d6a948 --- /dev/null +++ b/t/unit-tests/unit-test.h @@ -0,0 +1,10 @@ +#include "git-compat-util.h" +#include "clar/clar.h" +#include "clar-decls.h" +#include "strbuf.h" + +#define cl_failf(fmt, ...) do { \ + char desc[4096]; \ + snprintf(desc, sizeof(desc), fmt, __VA_ARGS__); \ + clar__fail(__FILE__, __func__, __LINE__, "Test failed.", desc, 1); \ +} while (0) @@ -84,7 +84,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/templates/Makefile b/templates/Makefile index 367ad00c24..bd1e9e30c1 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -29,24 +29,35 @@ all: boilerplates.made custom # 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 fae88709a6..0000000000 --- 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 index 498b267a8c..498b267a8c 100644 --- a/templates/this--description +++ b/templates/description diff --git a/templates/hooks--applypatch-msg.sample b/templates/hooks/applypatch-msg.sample index a5d7b84a67..a5d7b84a67 100755 --- a/templates/hooks--applypatch-msg.sample +++ b/templates/hooks/applypatch-msg.sample diff --git a/templates/hooks--commit-msg.sample b/templates/hooks/commit-msg.sample index b58d1184a9..b58d1184a9 100755 --- a/templates/hooks--commit-msg.sample +++ b/templates/hooks/commit-msg.sample diff --git a/templates/hooks--fsmonitor-watchman.sample b/templates/hooks/fsmonitor-watchman.sample index 23e856f5de..23e856f5de 100755 --- a/templates/hooks--fsmonitor-watchman.sample +++ b/templates/hooks/fsmonitor-watchman.sample diff --git a/templates/hooks/meson.build b/templates/hooks/meson.build new file mode 100644 index 0000000000..ef85e10a16 --- /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 index ec17ec1939..ec17ec1939 100755 --- a/templates/hooks--post-update.sample +++ b/templates/hooks/post-update.sample diff --git a/templates/hooks--pre-applypatch.sample b/templates/hooks/pre-applypatch.sample index 4142082bcb..4142082bcb 100755 --- a/templates/hooks--pre-applypatch.sample +++ b/templates/hooks/pre-applypatch.sample diff --git a/templates/hooks--pre-commit.sample b/templates/hooks/pre-commit.sample index 29ed5ee486..29ed5ee486 100755 --- a/templates/hooks--pre-commit.sample +++ b/templates/hooks/pre-commit.sample diff --git a/templates/hooks--pre-merge-commit.sample b/templates/hooks/pre-merge-commit.sample index 399eab1924..399eab1924 100755 --- a/templates/hooks--pre-merge-commit.sample +++ b/templates/hooks/pre-merge-commit.sample diff --git a/templates/hooks--pre-push.sample b/templates/hooks/pre-push.sample index 4ce688d32b..4ce688d32b 100755 --- a/templates/hooks--pre-push.sample +++ b/templates/hooks/pre-push.sample diff --git a/templates/hooks--pre-rebase.sample b/templates/hooks/pre-rebase.sample index db5feab8a1..db5feab8a1 100755 --- a/templates/hooks--pre-rebase.sample +++ b/templates/hooks/pre-rebase.sample diff --git a/templates/hooks--pre-receive.sample b/templates/hooks/pre-receive.sample index a1fd29ec14..a1fd29ec14 100755 --- a/templates/hooks--pre-receive.sample +++ b/templates/hooks/pre-receive.sample diff --git a/templates/hooks--prepare-commit-msg.sample b/templates/hooks/prepare-commit-msg.sample index 318afe3fd8..318afe3fd8 100755 --- a/templates/hooks--prepare-commit-msg.sample +++ b/templates/hooks/prepare-commit-msg.sample diff --git a/templates/hooks--push-to-checkout.sample b/templates/hooks/push-to-checkout.sample index af5a0c0018..af5a0c0018 100755 --- a/templates/hooks--push-to-checkout.sample +++ b/templates/hooks/push-to-checkout.sample diff --git a/templates/hooks--sendemail-validate.sample b/templates/hooks/sendemail-validate.sample index 640bcf874d..640bcf874d 100755 --- a/templates/hooks--sendemail-validate.sample +++ b/templates/hooks/sendemail-validate.sample diff --git a/templates/hooks--update.sample b/templates/hooks/update.sample index c4d426bc6e..c4d426bc6e 100755 --- a/templates/hooks--update.sample +++ b/templates/hooks/update.sample diff --git a/templates/info--exclude b/templates/info/exclude index a5196d1be8..a5196d1be8 100644 --- a/templates/info--exclude +++ b/templates/info/exclude diff --git a/templates/info/meson.build b/templates/info/meson.build new file mode 100644 index 0000000000..026f231385 --- /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 0000000000..1faf9a44ce --- /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 a8e4553f27..9da0071cba 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -13,6 +13,7 @@ #include "strvec.h" #include "quote.h" #include "object-store-ll.h" +#include "repository.h" struct tmp_objdir { struct strbuf path; @@ -132,7 +133,8 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) * can recognize any stale objdirs left behind by a crash and delete * them. */ - strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", get_object_directory(), prefix); + strbuf_addf(&t->path, "%s/tmp_objdir-%s-XXXXXX", + repo_get_object_directory(the_repository), prefix); if (!mkdtemp(t->path.buf)) { /* free, not destroy, as we never touched the filesystem */ @@ -152,7 +154,7 @@ struct tmp_objdir *tmp_objdir_create(const char *prefix) } env_append(&t->env, ALTERNATE_DB_ENVIRONMENT, - absolute_path(get_object_directory())); + absolute_path(repo_get_object_directory(the_repository))); env_replace(&t->env, DB_ENVIRONMENT, absolute_path(t->path.buf)); env_replace(&t->env, GIT_QUARANTINE_ENVIRONMENT, absolute_path(t->path.buf)); @@ -204,9 +206,11 @@ 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 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 strbuf *src, struct strbuf *dst, + enum finalize_object_file_flags flags) { struct stat st; @@ -218,12 +222,18 @@ static int migrate_one(struct strbuf *src, struct strbuf *dst) return -1; } else if (errno != EEXIST) return -1; - return migrate_paths(src, dst); + return migrate_paths(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 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; @@ -237,11 +247,15 @@ static int migrate_paths(struct strbuf *src, struct strbuf *dst) for (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(src, dst, flags_copy); strbuf_setlen(src, src_len); strbuf_setlen(dst, dst_len); @@ -267,9 +281,9 @@ int tmp_objdir_migrate(struct tmp_objdir *t) } strbuf_addbuf(&src, &t->path); - strbuf_addstr(&dst, get_object_directory()); + strbuf_addstr(&dst, repo_get_object_directory(the_repository)); - ret = migrate_paths(&src, &dst); + ret = migrate_paths(&src, &dst, 0); strbuf_release(&src); strbuf_release(&dst); @@ -21,9 +21,11 @@ * along with this program; if not, see <https://www.gnu.org/licenses/>. */ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "abspath.h" -#include "environment.h" +#include "repository.h" #include "quote.h" #include "setup.h" #include "trace.h" @@ -305,14 +307,14 @@ void trace_repo_setup(void) cwd = xgetcwd(); - if (!(git_work_tree = get_git_work_tree())) + if (!(git_work_tree = repo_get_work_tree(the_repository))) git_work_tree = "(null)"; if (!startup_info->prefix) prefix = "(null)"; - trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(get_git_dir())); - trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir())); + 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: 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/trace2/tr2_cfg.c b/trace2/tr2_cfg.c index d96d908bb9..22a99a0682 100644 --- a/trace2/tr2_cfg.c +++ b/trace2/tr2_cfg.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "config.h" #include "strbuf.h" @@ -124,7 +126,7 @@ void tr2_cfg_list_config_fl(const char *file, int line) struct tr2_cfg_data data = { file, line }; if (tr2_cfg_load_patterns() > 0) - read_early_config(tr2_cfg_cb, &data); + read_early_config(the_repository, tr2_cfg_cb, &data); } void tr2_list_env_vars_fl(const char *file, int line) diff --git a/trace2/tr2_ctr.c b/trace2/tr2_ctr.c index 036b643578..ee17bfa86b 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_tls.c b/trace2/tr2_tls.c index 4f75392952..7b023c1bfc 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 3dfe6557fc..3bdbf4d275 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) @@ -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); } } @@ -975,16 +982,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 +1024,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 +1072,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 +1084,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 +1121,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 +1154,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 +1165,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 +1175,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 +1196,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 +1220,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); } @@ -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 09b3560ffd..bc27653cde 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -89,11 +89,18 @@ static int recvline(struct helper_data *helper, struct strbuf *buffer) return recvline_fh(helper->out, buffer); } -static void write_constant(int fd, const char *str) +static int write_constant_gently(int fd, const char *str) { if (debug) fprintf(stderr, "Debug: Remote helper: -> %s", str); if (write_in_full(fd, str, strlen(str)) < 0) + return -1; + return 0; +} + +static void write_constant(int fd, const char *str) +{ + if (write_constant_gently(fd, str) < 0) die_errno(_("full write to remote helper failed")); } @@ -143,7 +150,7 @@ static struct child_process *get_helper(struct transport *transport) if (have_git_dir()) strvec_pushf(&helper->env, "%s=%s", - GIT_DIR_ENVIRONMENT, get_git_dir()); + GIT_DIR_ENVIRONMENT, repo_get_git_dir(the_repository)); helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */ @@ -168,13 +175,16 @@ static struct child_process *get_helper(struct transport *transport) die_errno(_("can't dup helper output fd")); data->out = xfdopen(duped, "r"); - write_constant(helper->in, "capabilities\n"); + sigchain_push(SIGPIPE, SIG_IGN); + if (write_constant_gently(helper->in, "capabilities\n") < 0) + die("remote helper '%s' aborted session", data->name); + sigchain_pop(SIGPIPE); while (1) { const char *capname, *arg; int mandatory = 0; if (recvline(data, &buf)) - exit(128); + die("remote helper '%s' aborted session", data->name); if (!*buf.buf) break; @@ -389,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; @@ -707,8 +719,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++) @@ -1013,6 +1031,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 3c4714581f..6966df51a8 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" @@ -172,12 +173,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 +203,16 @@ 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); transport->hash_algo = data->header.hash_algo; strvec_clear(&extra_index_pack_args); + strbuf_release(&msg_types); return ret; } @@ -334,6 +356,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 +439,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 +502,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 +533,7 @@ cleanup: ret = -1; data->conn = NULL; + free(to_fetch_dup); free_refs(refs_tmp); free_refs(refs); list_objects_filter_release(&args.filter_options); @@ -1099,6 +1133,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)) diff --git a/transport.h b/transport.h index 6393cd9823..44100fa9b7 100644 --- a/transport.h +++ b/transport.h @@ -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 9252481df3..5eab8af631 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -1,6 +1,9 @@ /* * Helper functions for tree diff generation */ + +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "diff.h" #include "diffcore.h" diff --git a/unicode-width.h b/unicode-width.h index be5bf8c4f2..3ffee123a0 100644 --- a/unicode-width.h +++ b/unicode-width.h @@ -27,7 +27,7 @@ static const struct interval zero_width[] = { { 0x0829, 0x082D }, { 0x0859, 0x085B }, { 0x0890, 0x0891 }, -{ 0x0898, 0x089F }, +{ 0x0897, 0x089F }, { 0x08CA, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C }, @@ -227,8 +227,9 @@ static const struct interval zero_width[] = { { 0x10A3F, 0x10A3F }, { 0x10AE5, 0x10AE6 }, { 0x10D24, 0x10D27 }, +{ 0x10D69, 0x10D6D }, { 0x10EAB, 0x10EAC }, -{ 0x10EFD, 0x10EFF }, +{ 0x10EFC, 0x10EFF }, { 0x10F46, 0x10F50 }, { 0x10F82, 0x10F85 }, { 0x11001, 0x11001 }, @@ -261,6 +262,11 @@ static const struct interval zero_width[] = { { 0x11340, 0x11340 }, { 0x11366, 0x1136C }, { 0x11370, 0x11374 }, +{ 0x113BB, 0x113C0 }, +{ 0x113CE, 0x113CE }, +{ 0x113D0, 0x113D0 }, +{ 0x113D2, 0x113D2 }, +{ 0x113E1, 0x113E2 }, { 0x11438, 0x1143F }, { 0x11442, 0x11444 }, { 0x11446, 0x11446 }, @@ -280,7 +286,8 @@ static const struct interval zero_width[] = { { 0x116AD, 0x116AD }, { 0x116B0, 0x116B5 }, { 0x116B7, 0x116B7 }, -{ 0x1171D, 0x1171F }, +{ 0x1171D, 0x1171D }, +{ 0x1171F, 0x1171F }, { 0x11722, 0x11725 }, { 0x11727, 0x1172B }, { 0x1182F, 0x11837 }, @@ -319,8 +326,11 @@ static const struct interval zero_width[] = { { 0x11F36, 0x11F3A }, { 0x11F40, 0x11F40 }, { 0x11F42, 0x11F42 }, +{ 0x11F5A, 0x11F5A }, { 0x13430, 0x13440 }, { 0x13447, 0x13455 }, +{ 0x1611E, 0x16129 }, +{ 0x1612D, 0x1612F }, { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, { 0x16F4F, 0x16F4F }, @@ -351,6 +361,7 @@ static const struct interval zero_width[] = { { 0x1E2AE, 0x1E2AE }, { 0x1E2EC, 0x1E2EF }, { 0x1E4EC, 0x1E4EF }, +{ 0x1E5EE, 0x1E5EF }, { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, { 0xE0001, 0xE0001 }, @@ -366,8 +377,10 @@ static const struct interval double_width[] = { { 0x23F3, 0x23F3 }, { 0x25FD, 0x25FE }, { 0x2614, 0x2615 }, +{ 0x2630, 0x2637 }, { 0x2648, 0x2653 }, { 0x267F, 0x267F }, +{ 0x268A, 0x268F }, { 0x2693, 0x2693 }, { 0x26A1, 0x26A1 }, { 0x26AA, 0x26AB }, @@ -401,11 +414,10 @@ static const struct interval double_width[] = { { 0x3099, 0x30FF }, { 0x3105, 0x312F }, { 0x3131, 0x318E }, -{ 0x3190, 0x31E3 }, +{ 0x3190, 0x31E5 }, { 0x31EF, 0x321E }, { 0x3220, 0x3247 }, -{ 0x3250, 0x4DBF }, -{ 0x4E00, 0xA48C }, +{ 0x3250, 0xA48C }, { 0xA490, 0xA4C6 }, { 0xA960, 0xA97C }, { 0xAC00, 0xD7A3 }, @@ -420,7 +432,7 @@ static const struct interval double_width[] = { { 0x16FF0, 0x16FF1 }, { 0x17000, 0x187F7 }, { 0x18800, 0x18CD5 }, -{ 0x18D00, 0x18D08 }, +{ 0x18CFF, 0x18D08 }, { 0x1AFF0, 0x1AFF3 }, { 0x1AFF5, 0x1AFFB }, { 0x1AFFD, 0x1AFFE }, @@ -430,6 +442,8 @@ static const struct interval double_width[] = { { 0x1B155, 0x1B155 }, { 0x1B164, 0x1B167 }, { 0x1B170, 0x1B2FB }, +{ 0x1D300, 0x1D356 }, +{ 0x1D360, 0x1D376 }, { 0x1F004, 0x1F004 }, { 0x1F0CF, 0x1F0CF }, { 0x1F18E, 0x1F18E }, @@ -470,11 +484,10 @@ static const struct interval double_width[] = { { 0x1F93C, 0x1F945 }, { 0x1F947, 0x1F9FF }, { 0x1FA70, 0x1FA7C }, -{ 0x1FA80, 0x1FA88 }, -{ 0x1FA90, 0x1FABD }, -{ 0x1FABF, 0x1FAC5 }, -{ 0x1FACE, 0x1FADB }, -{ 0x1FAE0, 0x1FAE8 }, +{ 0x1FA80, 0x1FA89 }, +{ 0x1FA8F, 0x1FAC6 }, +{ 0x1FACE, 0x1FADC }, +{ 0x1FADF, 0x1FAE9 }, { 0x1FAF0, 0x1FAF8 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } diff --git a/unimplemented.sh b/unimplemented.sh index fee21d24e8..41776b279d 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/unpack-trees.c b/unpack-trees.c index 9a55cb6204..e10a9d1209 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -808,6 +808,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 @@ -2070,9 +2072,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, diff --git a/upload-pack.c b/upload-pack.c index f03ba3e98b..43006c0614 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -166,6 +166,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); } @@ -709,10 +710,13 @@ static int get_reachable_list(struct upload_pack_data *data, struct object *o; char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */ const unsigned hexsz = the_hash_algo->hexsz; + int ret; if (do_reachable_revlist(&cmd, &data->shallows, reachable, - data->allow_uor) < 0) - return -1; + data->allow_uor) < 0) { + ret = -1; + goto out; + } while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) { struct object_id oid; @@ -736,10 +740,16 @@ static int get_reachable_list(struct upload_pack_data *data, } close(cmd.out); - if (finish_command(&cmd)) - return -1; + if (finish_command(&cmd)) { + ret = -1; + goto out; + } - return 0; + ret = 0; + +out: + child_process_clear(&cmd); + return ret; } static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) @@ -749,7 +759,7 @@ static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) int i; if (do_reachable_revlist(&cmd, src, NULL, allow_uor) < 0) - return 1; + goto error; /* * The commits out of the rev-list are not ancestors of @@ -775,6 +785,7 @@ static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) error: if (cmd.out >= 0) close(cmd.out); + child_process_clear(&cmd); return 1; } @@ -1015,10 +1026,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; @@ -1802,7 +1817,7 @@ int upload_pack_v2(struct repository *r, struct packet_reader *request) } else { /* * Request had 'want's but no 'have's so we can - * immedietly go to construct and send a pack. + * immediately go to construct and send a pack. */ state = FETCH_SEND_PACK; } @@ -350,18 +350,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 989629149f..d43d8360d1 100644 --- a/userdiff.c +++ b/userdiff.c @@ -1,3 +1,5 @@ +#define USE_THE_REPOSITORY_VARIABLE + #include "git-compat-util.h" #include "config.h" #include "userdiff.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 0000000000..347995df06 --- /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 */ @@ -1,5 +1,6 @@ #include "git-compat-util.h" #include "version.h" +#include "version-def.h" #include "strbuf.h" const char git_version_string[] = GIT_VERSION; @@ -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); @@ -186,7 +186,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 +290,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; @@ -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 30a947426e..af68b24f9d 100644 --- a/worktree.c +++ b/worktree.c @@ -57,7 +57,7 @@ static void add_head_info(struct worktree *wt) static int is_current_worktree(struct worktree *wt) { - char *git_dir = absolute_pathdup(get_git_dir()); + char *git_dir = absolute_pathdup(repo_get_git_dir(the_repository)); const char *wt_git_dir = get_worktree_git_dir(wt); int is_current = !fspathcmp(git_dir, absolute_path(wt_git_dir)); free(git_dir); @@ -72,7 +72,7 @@ static struct worktree *get_main_worktree(int skip_reading_head) struct worktree *worktree = NULL; struct strbuf worktree_path = STRBUF_INIT; - strbuf_add_real_path(&worktree_path, get_git_common_dir()); + strbuf_add_real_path(&worktree_path, repo_get_common_dir(the_repository)); strbuf_strip_suffix(&worktree_path, "/.git"); CALLOC_ARRAY(worktree, 1); @@ -110,6 +110,12 @@ struct worktree *get_linked_worktree(const char *id, 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); @@ -143,7 +149,7 @@ static struct worktree **get_worktrees_internal(int skip_reading_head) list[counter++] = get_main_worktree(skip_reading_head); - strbuf_addf(&path, "%s/worktrees", get_git_common_dir()); + strbuf_addf(&path, "%s/worktrees", repo_get_common_dir(the_repository)); dir = opendir(path.buf); strbuf_release(&path); if (dir) { @@ -171,9 +177,9 @@ struct worktree **get_worktrees(void) const char *get_worktree_git_dir(const struct worktree *wt) { if (!wt) - return get_git_dir(); + return repo_get_git_dir(the_repository); else if (!wt->id) - return get_git_common_dir(); + return repo_get_common_dir(the_repository); else return git_common_path("worktrees/%s", wt->id); } @@ -370,21 +376,28 @@ done: 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; if (is_main_worktree(wt)) BUG("can't relocate main worktree"); + strbuf_realpath(&gitdir, git_common_path("worktrees/%s/gitdir", wt->id), 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); } int is_worktree_being_rebased(const struct worktree *wt, @@ -560,42 +573,60 @@ 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; 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); 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); strbuf_release(&repo); strbuf_release(&dotgit); + strbuf_release(&gitdir); + strbuf_release(&backlink); } static void repair_noop(int iserr UNUSED, @@ -606,7 +637,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 +645,47 @@ 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; + + if (is_main_worktree(wt)) + goto done; + + strbuf_realpath(&gitdir, git_common_path("worktrees/%s/gitdir", wt->id), 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); +} + +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); } @@ -626,7 +697,7 @@ static int is_main_worktree_path(const char *path) strbuf_add_real_path(&target, path); strbuf_strip_suffix(&target, "/.git"); - strbuf_add_real_path(&maindir, get_git_common_dir()); + strbuf_add_real_path(&maindir, repo_get_common_dir(the_repository)); strbuf_strip_suffix(&maindir, "/.git"); cmp = fspathcmp(maindir.buf, target.buf); @@ -641,11 +712,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 +730,17 @@ 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)) + strbuf_reset(inferred); + strbuf_git_common_path(inferred, the_repository, "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 +748,15 @@ error: * 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 +767,179 @@ 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))) { + strbuf_realpath(&repo, git_common_path("worktrees/%s", id), 1); + 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 +1013,38 @@ cleanup: 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 11279d0c8f..38145df80f 100644 --- a/worktree.h +++ b/worktree.h @@ -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 95851b85b6..0000000000 --- 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/wt-status.c b/wt-status.c index b477239039..6a8c05d1cf 100644 --- a/wt-status.c +++ b/wt-status.c @@ -16,6 +16,7 @@ #include "revision.h" #include "diffcore.h" #include "quote.h" +#include "repository.h" #include "run-command.h" #include "strvec.h" #include "remote.h" @@ -152,7 +153,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s) "HEAD", 0, NULL, NULL); s->reference = "HEAD"; s->fp = stdout; - s->index_file = get_index_file(); + s->index_file = repo_get_index_file(the_repository); s->change.strdup_strings = 1; s->untracked.strdup_strings = 1; s->ignored.strdup_strings = 1; @@ -716,6 +717,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++) { @@ -734,7 +736,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); @@ -742,9 +743,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; } @@ -771,6 +774,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) @@ -2595,7 +2600,7 @@ int has_unstaged_changes(struct repository *r, int ignore_submodules) rev_info.diffopt.flags.quick = 1; diff_setup_done(&rev_info.diffopt); run_diff_files(&rev_info, 0); - result = diff_result_code(&rev_info.diffopt); + result = diff_result_code(&rev_info); release_revisions(&rev_info); return result; } @@ -2629,7 +2634,7 @@ int has_uncommitted_changes(struct repository *r, diff_setup_done(&rev_info.diffopt); run_diff_index(&rev_info, DIFF_INDEX_CACHED); - result = diff_result_code(&rev_info.diffopt); + result = diff_result_code(&rev_info); release_revisions(&rev_info); return result; } |
